import { zodResolver } from "@hookform/resolvers/zod"
import { useState } from "react"
import { Controller, useForm } from "react-hook-form"
import { toast } from "sonner"
import z from "zod"
import { updateCoupon } from "@/actions/coupon"
import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { FieldError, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import type { Coupon } from "@/models/coupon"

const schema = z
  .object({
    name: z.string().min(1, "请输入优惠券名称"),
    amount: z
      .string()
      .min(1, "请输入优惠券金额")
      .regex(/^\d+(\.\d+)?$/, "请输入有效的金额数字")
      .refine(val => Number(val) > 0, "优惠券金额必须大于0"),
    count: z
      .string()
      .min(1, "请输入优惠券数量")
      .regex(/^\d+$/, "请输入正整数")
      .refine(val => Number(val) >= 1, "优惠券数量至少为1"),
    min_amount: z
      .string()
      .min(1, "请输入最低消费金额")
      .regex(/^\d+(\.\d+)?$/, "请输入有效的金额数字")
      .refine(val => Number(val) >= 0, "最低消费金额不能为负数"),
    expire_at: z.string().optional(),
    expire_type: z.string().min(1, "请选择过期类型"),
    expire_in: z.string().optional(),
    status: z.string().optional(),
  })
  .superRefine((data, ctx) => {
    const expireType = Number(data.expire_type)
    if (!data.expire_type) return
    if (expireType === 1 && !data.expire_at) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: "请选择过期时间",
        path: ["expire_at"],
      })
    }
    if (expireType === 2 && !data.expire_in) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: "请输入过期时长天数",
        path: ["expire_in"],
      })
    }
  })

export function UpdateCoupon(props: {
  coupon: Coupon
  onSuccess?: () => void
}) {
  const [open, setOpen] = useState(false)

  const form = useForm({
    resolver: zodResolver(schema),
    defaultValues: {
      name: props.coupon.name,
      amount: String(props.coupon.amount),
      min_amount: String(props.coupon.min_amount),
      expire_at: props?.coupon.expire_at
        ? new Date(props?.coupon.expire_at).toISOString().split("T")[0]
        : "",
      status: String(props.coupon.status),
      count: String(props.coupon.count),
      expire_in: String(props?.coupon.expire_in),
    },
    mode: "onChange",
  })

  const { control, handleSubmit, reset, watch } = form
  const watchExpireType = watch("expire_type")
  const onSubmit = async (data: z.infer<typeof schema>) => {
    try {
      const expireType = Number(data.expire_type)
      const payload = {
        id: props.coupon.id,
        name: data.name,
        amount: Number(data.amount),
        min_amount: Number(data.min_amount),
        count: Number(data.count),
        status: Number(data.status),
        expire_type: expireType,
        expire_at: data.expire_at ? new Date(data.expire_at) : undefined,
        expire_in: expireType === 2 ? Number(data.expire_in) : undefined,
      }
      const resp = await updateCoupon(payload)
      if (resp.success) {
        toast.success("优惠券修改成功")
        props.onSuccess?.()
        setOpen(false)
      } else {
        toast.error(resp.message)
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : error
      toast.error(`接口请求错误: ${message}`)
    }
  }

  const handleOpenChange = (value: boolean) => {
    if (value) {
      reset({
        name: props.coupon.name,
        count: String(props.coupon.count),
        amount: String(props.coupon.amount),
        min_amount: String(props.coupon.min_amount),
        expire_at: props.coupon.expire_at
          ? new Date(props.coupon.expire_at).toISOString().split("T")[0]
          : "",
        status: String(props.coupon.status),
        expire_type: String(props.coupon.expire_type),
        expire_in: String(props.coupon.expire_in),
      })
    }
    setOpen(value)
  }

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogTrigger asChild>
        <Button size="sm" variant="secondary">
          修改
        </Button>
      </DialogTrigger>

      <DialogContent className="max-w-3xl">
        <DialogHeader>
          <DialogTitle>修改优惠券</DialogTitle>
        </DialogHeader>

        <form id="coupon-update" onSubmit={handleSubmit(onSubmit)}>
          <FieldGroup>
            <Controller
              control={control}
              name="name"
              render={({ field, fieldState }) => (
                <div className="flex items-start gap-4">
                  <FieldLabel className="w-28 pt-2">优惠券名称:</FieldLabel>
                  <div className="flex-1">
                    <Input {...field} />
                    <FieldError>{fieldState.error?.message}</FieldError>
                  </div>
                </div>
              )}
            />

            <Controller
              control={control}
              name="count"
              render={({ field, fieldState }) => (
                <div className="flex items-start gap-4">
                  <FieldLabel className="w-28 pt-2">优惠券数量:</FieldLabel>
                  <div className="flex-1">
                    <Input {...field} />
                    <FieldError>{fieldState.error?.message}</FieldError>
                  </div>
                </div>
              )}
            />

            <Controller
              control={control}
              name="amount"
              render={({ field, fieldState }) => (
                <div className="flex items-start gap-4">
                  <FieldLabel className="w-28 pt-2">优惠券金额:</FieldLabel>
                  <div className="flex-1">
                    <Input {...field} />
                    <FieldError>{fieldState.error?.message}</FieldError>
                  </div>
                </div>
              )}
            />

            <Controller
              control={control}
              name="min_amount"
              render={({ field, fieldState }) => (
                <div className="flex items-start gap-4">
                  <FieldLabel className="w-28 pt-2">最低消费金额:</FieldLabel>
                  <div className="flex-1">
                    <Input {...field} />
                    <FieldError>{fieldState.error?.message}</FieldError>
                  </div>
                </div>
              )}
            />
            <Controller
              control={control}
              name="status"
              render={({ field, fieldState }) => (
                <div className="flex items-start gap-4">
                  <FieldLabel className="w-28 pt-2">优惠券状态:</FieldLabel>
                  <div className="flex-1">
                    <Select value={field.value} onValueChange={field.onChange}>
                      <SelectTrigger>
                        <SelectValue placeholder="请选择状态" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="0">禁用</SelectItem>
                        <SelectItem value="1">正常</SelectItem>
                      </SelectContent>
                    </Select>
                    <FieldError>{fieldState.error?.message}</FieldError>
                  </div>
                </div>
              )}
            />
            <Controller
              control={control}
              name="expire_type"
              render={({ field, fieldState }) => (
                <div className="flex items-start gap-4">
                  <FieldLabel className="w-28 pt-2">过期类型:</FieldLabel>
                  <div className="flex-1">
                    <Select value={field.value} onValueChange={field.onChange}>
                      <SelectTrigger>
                        <SelectValue placeholder="请选择过期类型" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="0">不过期</SelectItem>
                        <SelectItem value="1">固定日期</SelectItem>
                        <SelectItem value="2">相对日期</SelectItem>
                      </SelectContent>
                    </Select>
                    <FieldError>{fieldState.error?.message}</FieldError>
                  </div>
                </div>
              )}
            />
            {watchExpireType === "1" && (
              <Controller
                control={control}
                name="expire_at"
                render={({ field, fieldState }) => (
                  <div className="flex items-start gap-4">
                    <FieldLabel className="w-28 pt-2">过期时间:</FieldLabel>
                    <div className="flex-1">
                      <Input
                        type="date"
                        min={new Date().toISOString().split("T")[0]}
                        {...field}
                      />
                      <FieldError>{fieldState.error?.message}</FieldError>
                    </div>
                  </div>
                )}
              />
            )}

            {watchExpireType === "2" && (
              <Controller
                control={control}
                name="expire_in"
                render={({ field, fieldState }) => (
                  <div className="flex items-start gap-4">
                    <FieldLabel className="w-28 pt-2">
                      过期时长（天）:
                    </FieldLabel>
                    <div className="flex-1">
                      <Input
                        type="number"
                        min="0"
                        placeholder="请输入过期天数"
                        {...field}
                      />
                      <FieldError>{fieldState.error?.message}</FieldError>
                    </div>
                  </div>
                )}
              />
            )}
          </FieldGroup>
        </form>

        <DialogFooter>
          <DialogClose asChild>
            <Button variant="ghost">取消</Button>
          </DialogClose>
          <Button type="submit" form="coupon-update">
            保存
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
