<template>
  <Dialog v-model:open="open">
    <DialogContent
      class="gap-0 rounded-[40px]! border-none bg-[#111111] px-12 py-10 text-white shadow-2xl! ring-0! outline-hidden! sm:max-w-[500px]"
    >
      <DialogHeader>
        <DialogTitle class="text-left text-2xl font-bold tracking-tight text-white"
          >佣金提现</DialogTitle
        >
      </DialogHeader>

      <div class="my-4 text-left text-sm font-medium text-white/30">
        {{
          values.type === 'USDT(TRC20)'
            ? '提现至您的数字钱包，手续费1USDT，该费率由支付平台收取'
            : '该提现方式需5%手续费，该费率由支付平台收取'
        }}
      </div>

      <form @submit="onSubmit" class="space-y-[20px]">
        <FormField v-slot="{ componentField }" name="type">
          <FormItem>
            <FormLabel class="block text-sm font-bold text-white">提现方式</FormLabel>
            <Select v-bind="componentField">
              <FormControl>
                <SelectTrigger
                  class="!h-[46px] w-full rounded-[32px] border-[4px] border-[#ADFF5B] bg-transparent px-6 text-sm font-medium text-[#ADFF5B] outline-hidden! focus:ring-0! [&_svg]:size-6 [&_svg]:text-[#ADFF5B] [&_svg]:opacity-100"
                >
                  <SelectValue />
                </SelectTrigger>
              </FormControl>
              <SelectContent class="rounded-2xl border-white/10 bg-[#222222] text-white">
                <SelectItem
                  v-for="t in ACCOUNT_TYPE"
                  :key="t"
                  :value="t"
                  class="py-3 text-sm focus:bg-[#ADFF5B] focus:text-black"
                >
                  {{ t }}
                </SelectItem>
              </SelectContent>
            </Select>
          </FormItem>
        </FormField>

        <FormField v-if="values.type === 'USDT(TRC20)'" v-slot="{ componentField }" name="account">
          <FormItem>
            <FormLabel class="block text-sm font-bold text-white">提现地址</FormLabel>
            <FormControl>
              <Input
                v-bind="componentField"
                class="h-[46px] rounded-[32px] border-none bg-[#222222] px-6 text-sm text-white transition-colors placeholder:text-white/20 focus:bg-[#2a2a2a]"
                placeholder="输入地址"
              />
            </FormControl>
            <FormMessage class="ml-4 text-red-400" />
          </FormItem>
        </FormField>

        <FormField v-slot="{ componentField }" name="money">
          <FormItem>
            <FormLabel class="block text-sm font-bold text-white">提现金额</FormLabel>
            <div
              class="group relative flex h-[46px] items-center overflow-hidden rounded-[32px] bg-[#ADFF5B] p-[3px]"
            >
              <div class="flex h-full items-center px-6 text-xl font-bold text-black">
                {{ values.type === 'USDT(TRC20)' ? '₮' : '$' }}
              </div>

              <FormControl>
                <Input
                  v-bind="componentField"
                  inputmode="decimal"
                  @keypress="
                    (e: KeyboardEvent) => {
                      if (!/[\d.]/.test(e.key)) {
                        e.preventDefault()
                      }
                      if (e.key === '.' && (e.target as HTMLInputElement).value.includes('.')) {
                        e.preventDefault()
                      }
                    }
                  "
                  @input="
                    (e: any) => {
                      let val = e.target.value
                      // 1. 只允许数字和小数点
                      val = val.replace(/[^\d.]/g, '')
                      // 2. 只允许一个小数点
                      const parts = val.split('.')
                      if (parts.length > 2) {
                        val = parts[0] + '.' + parts.slice(1).join('')
                      }
                      // 3. 强制限制两位小数
                      if (parts[1] && parts[1].length > 2) {
                        val = parts[0] + '.' + parts[1].slice(0, 2)
                      }
                      // 4. 关键：直接同步回 DOM，防止拼音输入暂留在框内
                      e.target.value = val
                      setFieldValue('money', val)
                    }
                  "
                  class="h-full flex-1 rounded-[28px]! border-none bg-[#222222] px-4 text-center text-sm font-bold text-white placeholder:text-white/20 focus:ring-0! focus-visible:ring-0!"
                  :placeholder="values.type === 'USDT(TRC20)' ? '不小于30USDT' : '不小于30$'"
                />
              </FormControl>

              <div class="flex h-full items-center px-6 text-sm font-bold text-black">
                {{ values.type === 'USDT(TRC20)' ? 'USDT' : '$' }}
              </div>
            </div>
            <FormMessage class="ml-4 text-red-400" />
          </FormItem>
        </FormField>

        <FormField v-if="values.type !== 'USDT(TRC20)'" name="avatar">
          <FormItem>
            <FormLabel class="mb-4 block text-sm font-bold text-white">收款码</FormLabel>
            <input
              ref="fileInputRef"
              type="file"
              accept="image/*"
              class="hidden"
              @change="onFileChange"
            />
            <div
              class="group relative flex cursor-pointer flex-col items-center justify-center overflow-hidden rounded-[32px] border-2 border-dashed border-white/10 bg-[#222222] transition-all hover:border-[#ADFF5B]/50 hover:bg-[#2a2a2a]"
              :class="[values.avatar ? 'h-auto min-h-[160px] p-2' : 'p-10']"
              @click="fileInputRef?.click()"
            >
              <template v-if="values.avatar">
                <img
                  :src="receiptPreviewUrl || values.avatar"
                  class="max-h-[300px] w-full rounded-2xl object-contain"
                />
                <div
                  class="absolute inset-0 flex items-center justify-center bg-black/60 opacity-0 transition-opacity group-hover:opacity-100"
                >
                  <span class="text-sm font-bold text-white">点击更换图片</span>
                </div>
              </template>
              <template v-else>
                <Upload class="mb-3 h-12 w-12 text-white/20" />
                <span class="text-base font-medium text-white/30">点击上传高清收款二维码</span>
              </template>
              <div
                v-if="isUploadingReceipt"
                class="absolute inset-0 flex items-center justify-center bg-black/70"
              >
                <Loader2 class="mr-2 h-6 w-6 animate-spin text-[#ADFF5B]" />
                <span class="text-sm font-bold text-white">上传中</span>
              </div>
            </div>
            <FormMessage class="ml-4 text-red-400" />
          </FormItem>
        </FormField>

        <div class="flex justify-center pt-2">
          <Button
            type="submit"
            :disabled="isPending || isUploadingReceipt"
            class="h-[30px] w-[100px] rounded-full bg-[#ADFF5B] text-sm font-black text-black shadow-[0_10px_30px_rgba(173,255,91,0.3)] transition-all hover:scale-105 hover:bg-[#9ded4e] active:scale-95 disabled:opacity-50"
          >
            <Loader2 v-if="isPending" class="mr-2 h-7 w-7 animate-spin" />
            确定
          </Button>
        </div>
      </form>
    </DialogContent>
  </Dialog>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useForm } from 'vee-validate'
import { z } from 'zod'
import { toTypedSchema } from '@vee-validate/zod'
import { toast } from 'vue-sonner'
import { Upload, Loader2 } from 'lucide-vue-next'

// Shadcn UI 组件
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'

// 业务 API
import request from '@/utils/request'

const props = defineProps<{ commission: number }>()
const emit = defineEmits(['confirm'])

const open = ref(false)
const isPending = ref(false) // 手动管理加载状态
const isUploadingReceipt = ref(false)
const receiptPreviewUrl = ref('')
const fileInputRef = ref<HTMLInputElement | null>(null)
const ACCOUNT_TYPE = ['USDT(TRC20)', '微信', '支付宝'] as const
const RECEIPT_UPLOAD_BIZ_TYPE = 'app-package'
const WITHDRAW_METHOD = {
  支付宝: 1,
  微信: 2,
  'USDT(TRC20)': 3,
} as const

type FileUploadResponse =
  | string
  | {
      url?: string
      file_url?: string
      full_url?: string
      path?: string
      uri?: string
      file?: string
      src?: string
    }

const revokeReceiptPreview = () => {
  if (receiptPreviewUrl.value) {
    URL.revokeObjectURL(receiptPreviewUrl.value)
    receiptPreviewUrl.value = ''
  }
}

const getUploadedFileUrl = (data: FileUploadResponse) => {
  if (typeof data === 'string') return data

  return (
    data.url ||
    data.file_url ||
    data.full_url ||
    data.path ||
    data.uri ||
    data.file ||
    data.src ||
    ''
  )
}

const uploadReceiptCode = async (file: File) => {
  const formData = new FormData()
  formData.append('biz_type', RECEIPT_UPLOAD_BIZ_TYPE)
  formData.append('file', file, file.name)

  const data = await request.post<FormData, FileUploadResponse>(
    '/api/v1/public/file/upload',
    formData,
  )
  return getUploadedFileUrl(data)
}

const onFileChange = async (e: Event) => {
  const file = (e.target as HTMLInputElement).files?.[0]
  if (!file) return

  if (!file.type.startsWith('image/')) {
    toast.error('请上传图片文件')
    return
  }

  try {
    isUploadingReceipt.value = true
    const uploadedUrl = await uploadReceiptCode(file)
    if (!uploadedUrl) {
      toast.error('上传失败，请重试')
      return
    }

    revokeReceiptPreview()
    receiptPreviewUrl.value = URL.createObjectURL(file)
    setFieldValue('avatar', uploadedUrl)
  } catch (err) {
    console.error('收款码上传失败:', err)
    toast.error('上传失败，请重试')
  } finally {
    isUploadingReceipt.value = false
    // 重置 input，允许重新选择同一张图
    if (e.target) {
      ;(e.target as HTMLInputElement).value = ''
    }
  }
}

// --- 表单验证 Schema ---
const formSchema = toTypedSchema(
  z
    .object({
      type: z.enum(ACCOUNT_TYPE),
      account: z.string().optional(),
      money: z.coerce
        .string()
        .min(1, '金额不能为空')
        .regex(/^\d+(\.\d{1,2})?$/, '格式错误，最多支持两位小数'),
      avatar: z.string().optional(),
    })
    .superRefine((data, ctx) => {
      if (data.type === 'USDT(TRC20)' && !data.account) {
        ctx.addIssue({ code: z.ZodIssueCode.custom, message: '地址不能为空', path: ['account'] })
      } else if (data.type !== 'USDT(TRC20)' && !data.avatar) {
        ctx.addIssue({ code: z.ZodIssueCode.custom, message: '请上传收款码', path: ['avatar'] })
      }
    }),
)

const { handleSubmit, resetForm, values, setFieldValue } = useForm({
  validationSchema: formSchema,
  initialValues: { type: 'USDT(TRC20)', account: '', money: '', avatar: '' },
})

// --- 暴露给父组件的方法 ---
const show = () => {
  revokeReceiptPreview()
  resetForm()
  open.value = true
}
defineExpose({ show })

// --- 提交逻辑 ---
const onSubmit = handleSubmit(async (val) => {
  const amount = parseFloat(val.money)

  // 1. 基础校验
  const minAmount = 30
  if (amount < minAmount)
    return toast.error(`金额不能小于${minAmount}${val.type === 'USDT(TRC20)' ? 'USDT' : '$'}`)

  try {
    isPending.value = true

    // 2. 获取最新佣金进行校验
    const userInfo = await request.get<any>('/api/v1/public/user/info')
    const latestCommission = userInfo?.commission || 0
    if (Math.round(amount * 100) > latestCommission) {
      toast.error('佣金不足')
      return
    }

    // 3. 执行提现请求
    await request.post('/api/v1/public/user/commission_withdraw', {
      amount: Math.round(amount * 100),
      method: WITHDRAW_METHOD[val.type],
      account: val.type === 'USDT(TRC20)' ? val.account : '',
      qr_code_url: val.type === 'USDT(TRC20)' ? '' : val.avatar,
    })

    // 4. 成功后处理
    toast.success('提现申请已提交，请等待审核')
    open.value = false
    emit('confirm') // 触发父组件刷新 info 接口
  } catch (error) {
    console.error('提现失败1:', error)
    toast.error('操作失败，请重试')
  } finally {
    isPending.value = false
  }
})
</script>
