import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@workspace/ui/components/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@workspace/ui/components/dialog";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@workspace/ui/components/form";
import { EnhancedInput } from "@workspace/ui/composed/enhanced-input";
import { grantLotteryChances } from "@workspace/ui/services/admin/lottery";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { z } from "zod";

const grantSchema = z.object({
  user_id: z.number().int().min(1),
  amount: z.number().int().min(1),
  source_ref: z.string().trim().min(1),
});

// 数字输入统一用 type="text" + 该 formatOutput，避开 number 类型 input 的实时钳制问题。
const numberOutput = (v: string | number): number | undefined => {
  const s = String(v ?? "").trim();
  if (s === "") {
    return;
  }
  const n = Number(s);
  return Number.isNaN(n) ? undefined : n;
};

type GrantFormValues = z.infer<typeof grantSchema>;

const SOURCE_REF_RANDOM_LENGTH = 6;

function generateSourceRef(): string {
  const now = new Date();
  const ymd = [
    now.getFullYear(),
    String(now.getMonth() + 1).padStart(2, "0"),
    String(now.getDate()).padStart(2, "0"),
  ].join("");
  const random = Math.random()
    .toString(36)
    .slice(2, 2 + SOURCE_REF_RANDOM_LENGTH)
    .padEnd(SOURCE_REF_RANDOM_LENGTH, "0");
  return `grant-${ymd}-${random}`;
}

interface GrantDialogProps {
  activity: API.LotteryActivity | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

export default function GrantDialog({
  activity,
  open,
  onOpenChange,
}: GrantDialogProps) {
  const { t } = useTranslation("lottery");
  const [loading, setLoading] = useState(false);
  const form = useForm<GrantFormValues>({
    resolver: zodResolver(grantSchema),
    defaultValues: { amount: 1, source_ref: "" },
  });

  useEffect(() => {
    if (open) {
      form.reset({
        user_id: undefined,
        amount: 1,
        source_ref: generateSourceRef(),
      });
    }
  }, [open, form]);

  async function handleSubmit(values: GrantFormValues) {
    if (!activity) return;
    setLoading(true);
    try {
      await grantLotteryChances({
        activity_id: activity.id,
        user_id: values.user_id,
        amount: values.amount,
        source_ref: values.source_ref.trim(),
      });
      toast.success(t("grant.success", "Chances granted"));
      onOpenChange(false);
      form.reset({ user_id: undefined, amount: 1, source_ref: "" });
    } catch {
      // Request layer already surfaces the error toast
    } finally {
      setLoading(false);
    }
  }

  return (
    <Dialog onOpenChange={onOpenChange} open={open}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>{t("grant.title", "Grant Chances")}</DialogTitle>
          <DialogDescription>
            {t(
              "grant.description",
              "Manually grant draw chances to a user for activity: {{title}}"
            ).replace("{{title}}", activity?.title ?? "")}
          </DialogDescription>
        </DialogHeader>
        <Form {...form}>
          <form
            className="space-y-4"
            id="lottery-grant-form"
            onSubmit={form.handleSubmit(handleSubmit)}
          >
            <FormField
              control={form.control}
              name="user_id"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>{t("grant.userId", "User ID")}</FormLabel>
                  <FormControl>
                    <EnhancedInput
                      formatOutput={numberOutput}
                      inputMode="numeric"
                      onValueChange={(value) => field.onChange(value)}
                      placeholder={t("grant.userIdPlaceholder", "e.g. 87433")}
                      type="text"
                      value={field.value}
                    />
                  </FormControl>
                  <FormDescription>
                    {t(
                      "grant.userIdHint",
                      "Enter the numeric user ID. You can find it in the user management list."
                    )}
                  </FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="amount"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>{t("grant.amount", "Amount")}</FormLabel>
                  <FormControl>
                    <EnhancedInput
                      formatOutput={numberOutput}
                      inputMode="numeric"
                      onValueChange={(value) => field.onChange(value)}
                      placeholder="1"
                      type="text"
                      value={field.value}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="source_ref"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>
                    {t("grant.sourceRef", "Source Reference")}
                  </FormLabel>
                  <FormControl>
                    <EnhancedInput
                      onValueChange={(value) => field.onChange(value)}
                      placeholder={t(
                        "grant.sourceRefPlaceholder",
                        "grant-20260709-abc123"
                      )}
                      value={field.value}
                    />
                  </FormControl>
                  <FormDescription>
                    {t(
                      "grant.sourceRefHint",
                      "Idempotency key: the same reference only grants once. Repeated submissions will not grant again."
                    )}
                  </FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
          </form>
        </Form>
        <DialogFooter>
          <Button
            onClick={() => onOpenChange(false)}
            type="button"
            variant="outline"
          >
            {t("cancel", "Cancel")}
          </Button>
          <Button disabled={loading} form="lottery-grant-form" type="submit">
            {t("confirm", "Confirm")}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
