"use client"

import { useCallback, useEffect, useRef, useState, useTransition, type ReactElement } 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 } 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 {
  Form,
  FormControl,
  FormDescription,
  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"
import { AiProviderSelector } from "@/modules/settings/components/ai-provider-selector"
import { AiProviderDeleteDialog } from "@/modules/settings/components/ai-provider-delete-dialog"

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

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(),
  visibility: VisibilitySchema.optional(),
})

type AiProviderFormValues = z.infer<typeof AiProviderFormSchema>

type AiProviderSettingsCardProps = {
  onProvidersChanged?: (rows: AiProviderSummary[]) => void
  initialMode?: "new" | "first"
  isAdmin?: boolean
  currentUserId?: string
}

export function AiProviderSettingsCard({
  onProvidersChanged,
  initialMode = "first",
  isAdmin = false,
  currentUserId,
}: AiProviderSettingsCardProps): ReactElement {
  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,
      visibility: "private",
    },
  })

  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,
      visibility: "private",
    })
  }, [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,
            visibility: next.visibility,
          })
        }
      } catch {
        toast.error(t("loadFailure"))
      }
    })
  }, [form, selectedId, onProvidersChanged, initialMode, resetToNew, t])

  const handleSelectChange = (value: string) => {
    if (value === "__new__") {
      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,
      visibility: next.visibility,
    })
  }

  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()
    const isLocalProvider = values.provider === "ollama"
    if (!apiKey && !values.id?.trim() && !isLocalProvider) {
      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,
        visibility: values.visibility,
      }
      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,
        visibility: values.visibility,
      }
      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,
            visibility: next.visibility,
          })
        }
      } 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,
              visibility: next.visibility,
            })
          } 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">
        <AiProviderSelector
          providers={providers}
          selectedId={selectedId}
          currentUserId={currentUserId}
          onSelectChange={handleSelectChange}
        />

        <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: "ollama", label: "Ollama (Local)" },
                  { value: "custom", label: "Custom" },
                ]}
              />
              <TextField
                control={form.control}
                name="baseUrl"
                label={t("baseUrl")}
                placeholder={form.watch("provider") === "ollama" ? "http://localhost:11434/v1" : t("baseUrlPlaceholder")}
                description={form.watch("provider") === "ollama" ? t("baseUrlDescOllama") : t("baseUrlDesc")}
              />
              <TextField
                control={form.control}
                name="model"
                label={t("model")}
                placeholder={form.watch("provider") === "ollama" ? "llama3.2" : t("modelPlaceholder")}
              />
              <TextField
                control={form.control}
                name="apiKey"
                label={t("apiKey")}
                type="password"
                placeholder={form.watch("provider") === "ollama" ? t("apiKeyPlaceholderOllama") : t("apiKeyPlaceholder")}
                description={form.watch("provider") === "ollama" ? t("apiKeyDescOllama") : t("apiKeyDesc")}
                itemClassName="sm:col-span-2"
              />
            </div>

            <FormField
              control={form.control}
              name="visibility"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>{t("visibility")}</FormLabel>
                  <FormControl>
                    <Select
                      value={field.value ?? "private"}
                      onValueChange={field.onChange}
                      disabled={!isAdmin}
                    >
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="private">{t("visibilityPrivateLabel")}</SelectItem>
                        {isAdmin ? (
                          <SelectItem value="public">{t("visibilityPublicLabel")}</SelectItem>
                        ) : null}
                      </SelectContent>
                    </Select>
                  </FormControl>
                  <FormDescription>
                    {isAdmin ? t("visibilityDesc") : t("visibilityReadOnly")}
                  </FormDescription>
                </FormItem>
              )}
            />

            <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">
              <AiProviderDeleteDialog
                disabled={isPending || !form.getValues("id")?.trim()}
                isPending={isPending}
                onConfirm={handleDelete}
              />
              <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>
  )
}
