"use client"

import { useCallback, useEffect, useMemo, useRef, useState, useTransition } from "react"
import { useTranslations } from "next-intl"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { toast } from "sonner"
import { Loader2, Save, Sparkles, Trash2 } from "lucide-react"

import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { Button } from "@/shared/components/ui/button"
import { Checkbox } from "@/shared/components/ui/checkbox"
import { Label } from "@/shared/components/ui/label"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/shared/components/ui/alert-dialog"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
} from "@/shared/components/ui/form"
import { TextField } from "@/shared/components/form-fields/text-field"
import { SelectField } from "@/shared/components/form-fields/select-field"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/components/ui/select"
import { deleteAiProviderAction, getAiProviderSummaries, testAiProviderAction, upsertAiProviderAction, type AiProviderSummary } from "@/modules/settings/actions"

const ProviderSchema = z.enum(["zhipu", "openai", "gemini", "custom"])

const AiProviderFormSchema = z.object({
  id: z.string().optional(),
  provider: ProviderSchema,
  baseUrl: z.string().optional(),
  model: z.string().min(1, "Model is required"),
  apiKey: z.string().optional(),
  isDefault: z.boolean().optional(),
})

type AiProviderFormValues = z.infer<typeof AiProviderFormSchema>

const NEW_PROVIDER_VALUE = "__new__"

export function AiProviderSettingsCard({
  onProvidersChanged,
  initialMode = "first",
}: {
  onProvidersChanged?: (rows: AiProviderSummary[]) => void
  initialMode?: "new" | "first"
}) {
  const t = useTranslations("settings.ai.providers")
  const [isPending, startTransition] = useTransition()
  const [providers, setProviders] = useState<AiProviderSummary[]>([])
  const [selectedId, setSelectedId] = useState<string>("")
  const [testStatus, setTestStatus] = useState<"idle" | "testing" | "passed" | "failed">("idle")
  const [lastTestedSignature, setLastTestedSignature] = useState<string>("")
  const loadedRef = useRef(false)

  const form = useForm<AiProviderFormValues>({
    resolver: zodResolver(AiProviderFormSchema),
    defaultValues: {
      id: "",
      provider: "openai",
      baseUrl: "",
      model: "",
      apiKey: "",
      isDefault: false,
    },
  })

  const selectedProvider = useMemo(
    () => providers.find((item) => item.id === selectedId) ?? null,
    [providers, selectedId]
  )

  const buildSignature = useCallback((values: AiProviderFormValues) => {
    return JSON.stringify({
      provider: values.provider,
      baseUrl: values.baseUrl?.trim() || "",
      model: values.model.trim(),
      apiKey: values.apiKey?.trim() || "",
    })
  }, [])

  const resetToNew = useCallback(() => {
    setSelectedId("")
    setTestStatus("idle")
    setLastTestedSignature("")
    form.reset({
      id: "",
      provider: "openai",
      baseUrl: "",
      model: "",
      apiKey: "",
      isDefault: false,
    })
  }, [form])

  useEffect(() => {
    if (loadedRef.current) return
    loadedRef.current = true
    startTransition(async () => {
      try {
        const result = await getAiProviderSummaries()
        if (!result.success || !result.data) {
          toast.error(result.message ?? t("loadFailure"))
          return
        }
        const rows = result.data
        setProviders(rows)
        onProvidersChanged?.(rows)
        if (initialMode === "new") {
          resetToNew()
          return
        }
        if (rows.length > 0 && !selectedId) {
          const next = rows[0]
          setSelectedId(next.id)
          form.reset({
            id: next.id,
            provider: next.provider,
            baseUrl: next.baseUrl ?? "",
            model: next.model,
            apiKey: "",
            isDefault: next.isDefault,
          })
        }
      } catch {
        toast.error(t("loadFailure"))
      }
    })
  }, [form, selectedId, onProvidersChanged, initialMode, resetToNew, t])

  const handleSelectChange = (value: string) => {
    if (value === NEW_PROVIDER_VALUE) {
      resetToNew()
      return
    }
    setSelectedId(value)
    setTestStatus("idle")
    setLastTestedSignature("")
    const next = providers.find((item) => item.id === value)
    if (!next) return
    form.reset({
      id: next.id,
      provider: next.provider,
      baseUrl: next.baseUrl ?? "",
      model: next.model,
      apiKey: "",
      isDefault: next.isDefault,
    })
  }

  useEffect(() => {
    const subscription = form.watch(() => {
      if (!lastTestedSignature) return
      const currentSignature = buildSignature(form.getValues())
      if (currentSignature !== lastTestedSignature) {
        setTestStatus("idle")
      }
    })
    return () => subscription.unsubscribe()
  }, [form, buildSignature, lastTestedSignature])

  const handleTest = () => {
    const values = form.getValues()
    const apiKey = values.apiKey?.trim()
    if (!apiKey && !values.id?.trim()) {
      toast.error(t("needKey"))
      return
    }
    setTestStatus("testing")
    startTransition(async () => {
      const payload = {
        id: values.id?.trim() || undefined,
        provider: values.provider,
        baseUrl: values.baseUrl?.trim() || undefined,
        model: values.model.trim(),
        apiKey: apiKey || undefined,
        isDefault: values.isDefault ?? false,
      }
      const result = await testAiProviderAction(payload)
      if (result.success) {
        setTestStatus("passed")
        setLastTestedSignature(buildSignature(values))
        toast.success(result.message ?? t("testSuccess"))
      } else {
        setTestStatus("failed")
        toast.error(result.message ?? t("testFailure"))
      }
    })
  }

  const onSubmit = (values: AiProviderFormValues) => {
    const signature = buildSignature(values)
    if (testStatus !== "passed" || signature !== lastTestedSignature) {
      toast.error(t("needTest"))
      return
    }
    startTransition(async () => {
      const payload = {
        id: values.id?.trim() || undefined,
        provider: values.provider,
        baseUrl: values.baseUrl?.trim() || undefined,
        model: values.model.trim(),
        apiKey: values.apiKey?.trim() || undefined,
        isDefault: values.isDefault ?? false,
      }
      const result = await upsertAiProviderAction(payload)
      if (result.success) {
        toast.success(result.message ?? t("saveSuccess"))
        setTestStatus("idle")
        setLastTestedSignature("")
        const summariesResult = await getAiProviderSummaries()
        if (!summariesResult.success || !summariesResult.data) {
          toast.error(summariesResult.message ?? t("loadFailure"))
          return
        }
        const rows = summariesResult.data
        setProviders(rows)
        onProvidersChanged?.(rows)
        const nextId = result.data ?? payload.id ?? ""
        setSelectedId(nextId)
        const next = rows.find((item) => item.id === nextId)
        if (next) {
          form.reset({
            id: next.id,
            provider: next.provider,
            baseUrl: next.baseUrl ?? "",
            model: next.model,
            apiKey: "",
            isDefault: next.isDefault,
          })
        }
      } else {
        toast.error(result.message ?? t("saveFailure"))
      }
    })
  }

  const handleDelete = () => {
    const id = form.getValues("id")
    if (!id?.trim()) {
      toast.error(t("deleteNeedSelect"))
      return
    }
    startTransition(async () => {
      const result = await deleteAiProviderAction({ id: id.trim() })
      if (result.success) {
        toast.success(result.message ?? t("deleteSuccess"))
        const summariesResult = await getAiProviderSummaries()
        if (summariesResult.success && summariesResult.data) {
          const rows = summariesResult.data
          setProviders(rows)
          onProvidersChanged?.(rows)
          if (rows.length > 0) {
            const next = rows[0]
            setSelectedId(next.id)
            form.reset({
              id: next.id,
              provider: next.provider,
              baseUrl: next.baseUrl ?? "",
              model: next.model,
              apiKey: "",
              isDefault: next.isDefault,
            })
          } else {
            resetToNew()
          }
        } else {
          resetToNew()
        }
      } else {
        toast.error(result.message ?? t("deleteFailure"))
      }
    })
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <Sparkles className="h-4 w-4 text-purple-500" />
          {t("title")}
        </CardTitle>
        <CardDescription>{t("description")}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        <div className="grid gap-4 sm:grid-cols-2">
          <div className="space-y-2">
            <Label>{t("existing")}</Label>
            <Select value={selectedId || NEW_PROVIDER_VALUE} onValueChange={handleSelectChange}>
              <SelectTrigger>
                <SelectValue placeholder={t("selectPlaceholder")} />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={NEW_PROVIDER_VALUE}>{t("createNew")}</SelectItem>
                {providers.map((item) => (
                  <SelectItem key={item.id} value={item.id}>
                    {item.provider} · {item.model}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label>{t("keyStatus")}</Label>
            <div className="rounded-md border px-3 py-2 text-sm text-muted-foreground">
              {selectedProvider?.apiKeyLast4
                ? `${t("stored")} • ****${selectedProvider.apiKeyLast4}`
                : t("noKey")}
            </div>
          </div>
        </div>

        <Form {...form}>
          <div className="grid gap-6">
            <div className="grid gap-4 sm:grid-cols-2">
              <TextField
                control={form.control}
                name="id"
                label={t("id")}
                disabled
                description={t("idDesc")}
              />
              <SelectField
                control={form.control}
                name="provider"
                label={t("provider")}
                placeholder={t("providerPlaceholder")}
                options={[
                  { value: "zhipu", label: "Zhipu" },
                  { value: "openai", label: "OpenAI" },
                  { value: "gemini", label: "Gemini" },
                  { value: "custom", label: "Custom" },
                ]}
              />
              <TextField
                control={form.control}
                name="baseUrl"
                label={t("baseUrl")}
                placeholder={t("baseUrlPlaceholder")}
                description={t("baseUrlDesc")}
              />
              <TextField
                control={form.control}
                name="model"
                label={t("model")}
                placeholder={t("modelPlaceholder")}
              />
              <TextField
                control={form.control}
                name="apiKey"
                label={t("apiKey")}
                type="password"
                placeholder={t("apiKeyPlaceholder")}
                description={t("apiKeyDesc")}
                itemClassName="sm:col-span-2"
              />
            </div>

            <FormField
              control={form.control}
              name="isDefault"
              render={({ field }) => (
                <FormItem className="flex items-center gap-2">
                  <FormControl>
                    <Checkbox checked={!!field.value} onCheckedChange={(value) => field.onChange(value === true)} />
                  </FormControl>
                  <FormLabel>{t("setDefault")}</FormLabel>
                </FormItem>
              )}
            />

            <CardFooter className="flex justify-between border-t px-0 pt-4">
              <AlertDialog>
                <AlertDialogTrigger asChild>
                  <Button
                    type="button"
                    variant="destructive"
                    disabled={isPending || !form.getValues("id")?.trim()}
                  >
                    <Trash2 className="mr-2 h-4 w-4" />
                    {t("delete")}
                  </Button>
                </AlertDialogTrigger>
                <AlertDialogContent>
                  <AlertDialogHeader>
                    <AlertDialogTitle>{t("deleteConfirmTitle")}</AlertDialogTitle>
                    <AlertDialogDescription>{t("deleteConfirmDescription")}</AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>{t("deleteCancel")}</AlertDialogCancel>
                    <AlertDialogAction onClick={handleDelete}>{t("deleteConfirm")}</AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
              <div className="flex gap-2">
                <Button type="button" variant="outline" onClick={handleTest} disabled={isPending || testStatus === "testing"}>
                  {testStatus === "testing" ? (
                    <>
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      {t("testing")}
                    </>
                  ) : (
                    <>
                      <Sparkles className="mr-2 h-4 w-4" />
                      {t("test")}
                    </>
                  )}
                </Button>
                <Button type="button" onClick={form.handleSubmit(onSubmit)} disabled={isPending}>
                  {isPending ? (
                    <>
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      {t("saving")}
                    </>
                  ) : (
                    <>
                      <Save className="mr-2 h-4 w-4" />
                      {t("save")}
                    </>
                  )}
                </Button>
              </div>
            </CardFooter>
          </div>
        </Form>
      </CardContent>
    </Card>
  )
}
