<template>
  <ElDialog v-model="dialogVisible" title="创建退款申请" width="40%" @closed="handleDialogClosed">
    <ElForm ref="formRef" :model="formData" :rules="formRules" label-width="120px">
      <ElFormItem label="订单号" prop="order_id">
        <ElSelect
          v-if="!hasInitialOrder"
          v-model="formData.order_id"
          filterable
          remote
          clearable
          :remote-method="searchOrders"
          :loading="orderSearchLoading"
          placeholder="请输入订单号搜索"
          style="width: 100%"
          @change="handleOrderSelectChange"
        >
          <ElOption
            v-for="order in orderSearchOptions"
            :key="order.id"
            :label="order.order_no"
            :value="order.id"
          />
        </ElSelect>
        <ElInput v-else :model-value="props.initialOrderNo" disabled style="width: 100%" />
      </ElFormItem>
      <ElFormItem label="申请退款金额" prop="requested_refund_amount">
        <ElInputNumber
          v-model="formData.requested_refund_amount"
          :min="0"
          :precision="2"
          :step="1"
          style="width: 100%"
          placeholder="请输入申请退款金额（元）"
        />
      </ElFormItem>
      <ElFormItem label="实收金额">
        <ElInput :model-value="selectedOrderActualPaid" disabled style="width: 100%" />
      </ElFormItem>
      <ElFormItem label="退款原因" prop="refund_reason">
        <ElInput
          v-model="formData.refund_reason"
          type="textarea"
          :rows="3"
          maxlength="1000"
          show-word-limit
          placeholder="请输入退款原因"
        />
      </ElFormItem>
      <ElFormItem label="备注">
        <ElInput
          v-model="formData.remark"
          type="textarea"
          :rows="2"
          maxlength="500"
          show-word-limit
          placeholder="请输入备注"
        />
      </ElFormItem>
      <ElFormItem label="退款凭证" prop="refund_voucher_key">
        <VoucherUpload
          ref="uploadRef"
          v-model="formData.refund_voucher_key"
          voucher-name="退款凭证"
          @uploading-change="voucherUploading = $event"
          @change="formRef?.validateField('refund_voucher_key')"
          @files-change="formData.attachments = $event"
        />
      </ElFormItem>
    </ElForm>
    <template #footer>
      <div class="dialog-footer">
        <ElButton @click="dialogVisible = false">取消</ElButton>
        <ElButton
          type="primary"
          @click="handleSubmit"
          :loading="submitLoading || voucherUploading"
          :disabled="voucherUploading"
        >
          {{ voucherUploading ? '凭证上传中...' : '确认创建' }}
        </ElButton>
      </div>
    </template>
  </ElDialog>
</template>

<script setup lang="ts">
  import { ref, reactive, computed, watch } from 'vue'
  import { ElMessage } from 'element-plus'
  import type { FormInstance, FormRules } from 'element-plus'
  import { RefundService, OrderService } from '@/api/modules'
  import type { CreateRefundRequest, Order, RefundAttachment } from '@/types/api'
  import { formatMoney, yuanToFen } from '@/utils/business/format'
  import { getErrorMessage } from '@/utils/business'
  import VoucherUpload from '@/components/business/VoucherUpload.vue'

  interface Props {
    modelValue: boolean
    initialOrderId?: number
    initialOrderNo?: string
  }

  const props = defineProps<Props>()
  const emit = defineEmits<{
    'update:modelValue': [value: boolean]
    success: []
  }>()

  const dialogVisible = computed({
    get: () => props.modelValue,
    set: (val) => emit('update:modelValue', val)
  })

  const formRef = ref<FormInstance>()
  const uploadRef = ref<InstanceType<typeof VoucherUpload>>()
  const submitLoading = ref(false)
  const voucherUploading = ref(false)
  const orderSearchLoading = ref(false)
  const orderSearchOptions = ref<Order[]>([])

  const formData = reactive<{
    order_id: number | null
    requested_refund_amount?: number
    actual_received_amount: number
    refund_reason: string
    remark: string
    refund_voucher_key: string[]
    attachments: RefundAttachment[]
  }>({
    order_id: null,
    requested_refund_amount: undefined,
    actual_received_amount: 0,
    refund_reason: '',
    remark: '',
    refund_voucher_key: [],
    attachments: []
  })

  const validateRefundAmount = (rule: any, value: number, callback: any) => {
    const requestedRefundAmount = yuanToFen(value) ?? 0
    if (value === undefined || value === null || value < 0) {
      callback(new Error('申请退款金额不能小于0'))
    } else if (requestedRefundAmount > formData.actual_received_amount) {
      callback(new Error('申请退款金额不能大于实收金额'))
    } else {
      callback()
    }
  }

  const formRules = reactive<FormRules>({
    order_id: [{ required: true, message: '请选择订单', trigger: 'change' }],
    requested_refund_amount: [
      { required: true, message: '请输入申请退款金额', trigger: 'blur' },
      { validator: validateRefundAmount, trigger: 'blur' }
    ],
    refund_reason: [{ required: true, message: '请输入退款原因', trigger: 'blur' }],
    refund_voucher_key: [{ required: true, message: '请上传退款凭证', trigger: 'change' }]
  })

  const hasInitialOrder = computed(() => !!props.initialOrderId || !!props.initialOrderNo)

  const selectedOrderActualPaid = computed(() => {
    if (!formData.order_id) return '0.00'
    const selectedOrder = orderSearchOptions.value.find((o) => o.id === formData.order_id)
    return formatMoney(selectedOrder?.actual_paid_amount ?? 0, false)
  })

  const searchOrders = async (query: string) => {
    orderSearchLoading.value = true
    try {
      const params: any = {
        page: 1,
        page_size: 20,
        payment_status: 2
      }
      if (query) {
        params.order_no = query
      }
      const res = await OrderService.getOrders(params)
      if (res.code === 0) {
        orderSearchOptions.value = res.data.items || []
        if (hasInitialOrder.value && props.initialOrderId) {
          formData.order_id = props.initialOrderId
        }
        if (hasInitialOrder.value && props.initialOrderNo) {
          const matchedOrder = orderSearchOptions.value.find(
            (o) => o.order_no === props.initialOrderNo
          )
          if (matchedOrder) {
            formData.order_id = matchedOrder.id
            formData.actual_received_amount = matchedOrder.actual_paid_amount ?? 0
          }
        }
      }
    } catch (error) {
      console.error('Search orders failed:', error)
    } finally {
      orderSearchLoading.value = false
    }
  }

  const handleOrderSelectChange = (orderId: number | null) => {
    if (!orderId) {
      formData.actual_received_amount = 0
      return
    }
    const selectedOrder = orderSearchOptions.value.find((o) => o.id === orderId)
    if (selectedOrder) {
      formData.actual_received_amount = selectedOrder.actual_paid_amount ?? 0
    }
  }

  const handleDialogClosed = () => {
    formRef.value?.resetFields()
    voucherUploading.value = false
    formData.order_id = null
    formData.requested_refund_amount = undefined
    formData.actual_received_amount = 0
    formData.refund_reason = ''
    formData.remark = ''
    formData.refund_voucher_key = []
    formData.attachments = []
    orderSearchOptions.value = []
    uploadRef.value?.clearFiles(false)
  }

  const handleSubmit = async () => {
    if (!formRef.value) return
    if (voucherUploading.value) {
      ElMessage.warning('退款凭证上传中，请稍候')
      return
    }

    await formRef.value.validate(async (valid) => {
      if (valid) {
        submitLoading.value = true
        try {
          const data: CreateRefundRequest = {
            order_id: formData.order_id!,
            requested_refund_amount: yuanToFen(formData.requested_refund_amount) ?? 0,
            actual_received_amount: formData.actual_received_amount,
            attachments: formData.attachments,
            refund_reason: formData.refund_reason || undefined,
            remark: formData.remark || undefined
          }
          await RefundService.createRefund(data)
          ElMessage.success('退款申请创建成功')
          dialogVisible.value = false
          emit('success')
        } catch (error) {
          console.error(error)
          ElMessage.error(getErrorMessage(error, '退款申请创建失败'))
        } finally {
          submitLoading.value = false
        }
      }
    })
  }

  watch(dialogVisible, (val) => {
    if (val) {
      if (hasInitialOrder.value && props.initialOrderId) {
        formData.order_id = props.initialOrderId
      }
      if (hasInitialOrder.value && props.initialOrderNo) {
        searchOrders(props.initialOrderNo)
      } else {
        searchOrders('')
      }
    }
  })
</script>
