'use client'
import {useEffect, useRef, useState} from 'react'
import {Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger} from '@/components/ui/dialog'
import {Button} from '@/components/ui/button'
import {Form, FormField} from '@/components/ui/form'
import {Input} from '@/components/ui/input'
import {useForm} from 'react-hook-form'
import {zodResolver} from '@hookform/resolvers/zod'
import * as z from 'zod'
import {toast} from 'sonner'
import {useRouter} from 'next/navigation'
import {sendSMS} from '@/actions/verify'
import {updatePassword} from '@/actions/user'

interface ChangePasswordDialogProps {
  triggerClassName?: string
  open?: boolean
  onOpenChange?: (open: boolean) => void
  onSuccess?: () => void
}

export function ChangePasswordDialog({
  triggerClassName,
  open,
  onOpenChange,
  onSuccess,
}: ChangePasswordDialogProps) {
  const [internalOpen, setInternalOpen] = useState(false)
  const router = useRouter()

  const actualOpen = open !== undefined ? open : internalOpen
  const actualOnOpenChange = onOpenChange || setInternalOpen

  // 表单验证规则
  const schema = z.object({
    phone: z.string().regex(/^1\d{10}$/, `请输入正确的手机号`),
    captcha: z.string().nonempty('请输入验证码'),
    code: z.string().regex(/^\d{6}$/, `请输入正确的验证码`),
    password: z.string().min(6, `密码至少6位`),
    confirm_password: z.string(),
  }).refine(data => data.password === data.confirm_password, {
    message: '两次输入的密码不一致',
    path: ['confirm_password'],
  })

  type Schema = z.infer<typeof schema>

  // 表单初始化
  const form = useForm<Schema>({
    resolver: zodResolver(
      schema.refine(
        data => /^(?=.*[a-zA-Z])(?=.*\d).{6,}$/.test(data.password),
        {
          message: '密码需包含字母和数字，且不少于6位',
          path: ['password'],
        },
      ),
    ),
    defaultValues: {
      phone: '',
      captcha: '',
      code: '',
      password: '',
      confirm_password: '',
    },
  })

  // 提交处理
  const handler = form.handleSubmit(async (value) => {
    try {
      const resp = await updatePassword({
        phone: value.phone,
        code: value.code,
        password: value.password,
      })
      if (!resp.success) {
        throw new Error(resp.message)
      }

      toast.success(`保存成功，请重新登录`)
      onSuccess?.()
      actualOnOpenChange(false)
      router.replace('/login')
    }
    catch (e) {
      console.error(e)
      toast.error(`保存失败`, {
        description: e instanceof Error ? e.message : String(e),
      })
    }
  })

  // 验证码相关状态
  const [captchaUrl, setCaptchaUrl] = useState(`/captcha?t=${new Date().getTime()}`)
  const [captchaWait, setCaptchaWait] = useState(0)
  const interval = useRef<NodeJS.Timeout>(null)

  // 刷新验证码
  const refreshCaptcha = () => {
    setCaptchaUrl(`/captcha?t=${new Date().getTime()}`)
  }

  // 发送短信验证码
  const sendVerifier = async () => {
    const result = await form.trigger(['phone', 'captcha'])
    if (!result) return

    const {phone, captcha} = form.getValues()
    const resp = await sendSMS({phone, captcha})
    if (!resp.success) {
      toast.error(resp.message)
      refreshCaptcha()
      return
    }

    setCaptchaWait(60)
    interval.current = setInterval(() => {
      setCaptchaWait((wait) => {
        if (wait <= 1) {
          clearInterval(interval.current!)
          return 0
        }
        return wait - 1
      })
    }, 1000)

    toast.success(`验证码已发送，请注意查收`)
  }

  // 清理定时器
  useEffect(() => {
    return () => {
      if (interval.current) {
        clearInterval(interval.current)
      }
    }
  }, [])

  return (
    <Dialog open={actualOpen} onOpenChange={actualOnOpenChange}>
      <DialogTrigger asChild>
        <Button theme="outline" className={triggerClassName || 'w-24 h-9'}>修改密码</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>修改密码</DialogTitle>
        </DialogHeader>
        <Form form={form} handler={handler} className="flex flex-col gap-4 mt-4">
          {/* 手机号输入 */}
          <FormField<Schema> name="phone" label="手机号" className="flex-auto">
            {({field}) => (
              <Input {...field} placeholder="请输入手机号" autoComplete="tel-national"/>
            )}
          </FormField>

          {/* 图形验证码 */}
          <FormField<Schema> name="captcha" label="验证码">
            {({field}) => (
              <div className="flex gap-4">
                <Input {...field} placeholder="请输入验证码" autoComplete="one-time-code"/>
                <Button className="p-0 bg-transparent" onClick={refreshCaptcha} type="button">
                  <img src={captchaUrl} alt="验证码" className="h-10"/>
                </Button>
              </div>
            )}
          </FormField>

          {/* 短信验证码 */}
          <FormField<Schema> name="code" label="短信令牌" className="flex-auto">
            {({field}) => (
              <div className="flex gap-4">
                <Input {...field} placeholder="请输入验证码" autoComplete="one-time-code"/>
                <Button theme="outline" type="button" className="w-36" onClick={() => sendVerifier()}>
                  {captchaWait > 0 ? `重新发送(${captchaWait})` : `获取短信令牌`}
                </Button>
              </div>
            )}
          </FormField>

          {/* 新密码 */}
          <FormField<Schema> name="password" label="新密码" className="flex-auto">
            {({field}) => (
              <Input {...field} placeholder="请输入新密码" type="password" autoComplete="new-password"/>
            )}
          </FormField>

          {/* 确认密码 */}
          <FormField<Schema> name="confirm_password" label="确认密码" className="flex-auto">
            {({field}) => (
              <Input {...field} placeholder="请再次输入新密码" type="password" autoComplete="new-password"/>
            )}
          </FormField>
        </Form>

        <DialogFooter>
          <Button
            theme="outline"
            type="button"
            onClick={() => {
              actualOnOpenChange(false)
              form.reset()
            }}>
            关闭
          </Button>
          <Button onClick={handler}>
            保存
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
