import { useId, useState } from "react"
import { useParams } from "react-router-dom"
import { AlertTriangle, Loader2, Play, RefreshCw, TriangleAlert } from "lucide-react"
import { DiffView } from "@/components/DiffView"
import { DomainHistory } from "@/components/DomainHistory"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { Label } from "@/components/ui/label"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import {
  useApplyDomain,
  useCheckDomain,
  useCreateTemplateFromZone,
  useDomains,
  useZoneRecords,
} from "@/hooks/useApi"
import { cn } from "@/lib/utils"

export function DomainDiffPage() {
  const { id = "" } = useParams()
  const domains = useDomains()
  const domain = domains.data?.find((d) => d.id === id)
  const hasTemplate = !!domain?.templateId

  const check = useCheckDomain(id, hasTemplate)
  const apply = useApplyDomain(id)
  // Пока список доменов не загружен, hasTemplate недостоверно (false по
  // умолчанию из-за domain === undefined) — не дёргаем provider-запрос
  // записей зоны, пока не будет точно известно, что шаблона нет.
  const zoneRecords = useZoneRecords(id, !domains.isPending && !hasTemplate)
  const createTemplateFromZone = useCreateTemplateFromZone()
  const [applyPrunes, setApplyPrunes] = useState(false)
  const pruneCheckboxId = useId()

  const changeset = check.data
  const hasPrunes = (changeset?.prunes.length ?? 0) > 0
  const hasUpdates = (changeset?.updates.length ?? 0) > 0
  const pruneWarning = applyPrunes && hasPrunes
  const recordList = zoneRecords.data ?? []

  function onApply() {
    apply.mutate({ applyUpdates: true, applyPrunes })
  }

  function onCreateTemplateFromZone() {
    createTemplateFromZone.mutate(id)
  }

  if (domains.isPending) {
    return (
      <div className="mx-auto flex max-w-3xl flex-col gap-6 px-6 py-8">
        <div className="flex items-center gap-2 rounded-lg border border-border bg-card px-4 py-8 text-sm text-muted-foreground">
          <Loader2 className="size-4 animate-spin" strokeWidth={1.75} />
          Загрузка…
        </div>
      </div>
    )
  }

  return (
    <div className="mx-auto flex max-w-3xl flex-col gap-6 px-6 py-8">
      <header className="flex flex-wrap items-end justify-between gap-4">
        <div className="flex flex-col gap-1">
          <span className="font-dns text-[11px] tracking-wider text-muted-foreground uppercase">
            domain / check
          </span>
          <h1 className="font-dns text-xl font-semibold tracking-tight text-foreground">
            {id}
          </h1>
        </div>
        {hasTemplate && (
          <Button
            variant="ghost"
            size="sm"
            onClick={() => check.refetch()}
            disabled={check.isFetching}
          >
            <RefreshCw className={cn("size-3.5", check.isFetching && "animate-spin")} strokeWidth={1.75} />
            Recheck
          </Button>
        )}
      </header>

      {!hasTemplate && (
        <>
          <div className="flex items-start gap-2.5 rounded-lg border border-border bg-card/60 px-4 py-3 text-sm text-muted-foreground">
            <AlertTriangle className="mt-0.5 size-4 shrink-0" strokeWidth={1.75} />
            <span>Шаблон не привязан — дифф недоступен. Ниже текущие записи зоны.</span>
          </div>

          <div className="flex items-center justify-between gap-3 rounded-xl border border-border bg-card/60 p-4">
            <span className="text-xs text-muted-foreground">
              Создать шаблон-эталон из текущего состояния зоны (без NS/SOA).
            </span>
            <Button onClick={onCreateTemplateFromZone} disabled={createTemplateFromZone.isPending}>
              {createTemplateFromZone.isPending ? (
                <Loader2 className="size-4 animate-spin" strokeWidth={1.75} />
              ) : (
                <Play className="size-4" strokeWidth={1.75} />
              )}
              Создать шаблон из этой зоны
            </Button>
          </div>
          {createTemplateFromZone.isError && (
            <span role="alert" className="font-dns text-xs text-destructive">
              {createTemplateFromZone.error.message}
            </span>
          )}

          {zoneRecords.isPending && (
            <div className="flex items-center gap-2 rounded-lg border border-border bg-card px-4 py-8 text-sm text-muted-foreground">
              <Loader2 className="size-4 animate-spin" strokeWidth={1.75} />
              Загружаю записи зоны…
            </div>
          )}

          {zoneRecords.isError && (
            <div className="flex items-start gap-2.5 rounded-lg border border-destructive/30 bg-destructive/5 px-4 py-3 text-sm text-destructive">
              <AlertTriangle className="mt-0.5 size-4 shrink-0" strokeWidth={1.75} />
              <div className="flex flex-col gap-1">
                <span className="font-medium">Не удалось получить записи зоны</span>
                <span className="font-dns text-xs opacity-90">{zoneRecords.error.message}</span>
              </div>
            </div>
          )}

          {recordList.length > 0 && (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Тип</TableHead>
                  <TableHead>Имя</TableHead>
                  <TableHead>TTL</TableHead>
                  <TableHead>Значение</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {recordList.map((r, i) => (
                  <TableRow key={`${r.type}-${r.name}-${i}`}>
                    <TableCell className="font-dns">{r.type}</TableCell>
                    <TableCell className="font-dns">{r.name}</TableCell>
                    <TableCell className="font-dns">{r.ttl}</TableCell>
                    <TableCell className="font-dns whitespace-pre-line">{r.values.join("\n")}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </>
      )}

      {hasTemplate && check.isPending && (
        <div className="flex items-center gap-2 rounded-lg border border-border bg-card px-4 py-8 text-sm text-muted-foreground">
          <Loader2 className="size-4 animate-spin" strokeWidth={1.75} />
          Вычисляю дифф…
        </div>
      )}

      {hasTemplate && check.isError && (
        <div className="flex items-start gap-2.5 rounded-lg border border-destructive/30 bg-destructive/5 px-4 py-3 text-sm text-destructive">
          <AlertTriangle className="mt-0.5 size-4 shrink-0" strokeWidth={1.75} />
          <div className="flex flex-col gap-1">
            <span className="font-medium">Не удалось получить дифф</span>
            <span className="font-dns text-xs opacity-90">{check.error.message}</span>
          </div>
        </div>
      )}

      {hasTemplate && changeset && (
        <>
          <DiffView changeset={changeset} />

          <div className="flex flex-col gap-3 rounded-xl border border-border bg-card/60 p-4">
            <Label
              htmlFor={pruneCheckboxId}
              className="flex items-start gap-2.5 text-sm font-normal"
            >
              <Checkbox
                id={pruneCheckboxId}
                aria-label="prune — удалить лишние записи"
                checked={applyPrunes}
                onCheckedChange={(v) => setApplyPrunes(v === true)}
                className="mt-0.5"
                style={
                  applyPrunes
                    ? ({ borderColor: "var(--diff-delete)", background: "var(--diff-delete)" } as React.CSSProperties)
                    : undefined
                }
              />
              <span className="flex flex-col gap-0.5">
                <span className="font-medium text-foreground">
                  Prune — удалить записи, которых нет в шаблоне
                </span>
                <span className="text-xs text-muted-foreground">
                  По умолчанию выключено. Apply меняет только записи из шаблона.
                </span>
              </span>
            </Label>

            {pruneWarning && (
              <div
                className="flex items-start gap-2 rounded-lg px-3 py-2 text-xs"
                style={{
                  color: "var(--diff-delete)",
                  background: "color-mix(in oklch, var(--diff-delete), transparent 90%)",
                }}
                role="alert"
              >
                <TriangleAlert className="mt-px size-3.5 shrink-0" strokeWidth={2} />
                <span>
                  Будет безвозвратно удалено записей:{" "}
                  <span className="font-dns font-semibold">{changeset.prunes.length}</span>. Действие необратимо.
                </span>
              </div>
            )}

            <div className="flex items-center justify-between gap-3 border-t border-border pt-3">
              {apply.isError ? (
                <span className="font-dns text-xs text-destructive">{apply.error.message}</span>
              ) : apply.isSuccess ? (
                <span className="font-dns text-xs" style={{ color: "var(--diff-add)" }}>
                  Применено ✓
                </span>
              ) : (
                <span className="text-xs text-muted-foreground">
                  {hasUpdates || (applyPrunes && hasPrunes)
                    ? "Готово к применению"
                    : "Изменений для применения нет"}
                </span>
              )}
              <Button onClick={onApply} disabled={apply.isPending}>
                {apply.isPending ? (
                  <Loader2 className="size-4 animate-spin" strokeWidth={1.75} />
                ) : (
                  <Play className="size-4" strokeWidth={1.75} />
                )}
                Apply
              </Button>
            </div>
          </div>
        </>
      )}

      <DomainHistory domainId={id} />
    </div>
  )
}
