"use client"

import { useEffect, useMemo, useState } from "react"
import { toast } from "sonner"
import { FormField } from "@/components/form-kit"
import { Alert, AlertDescription, AlertTitle } from "@/components/reui/alert"
import { Frame, FramePanel } from "@/components/reui/frame"
import { CodeBlock, downloadText } from "@/components/reui-kit/code-export-sheet"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { ScrollArea } from "@/components/ui/scroll-area"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
import {
  Sheet, SheetContent, SheetHeader, SheetTitle,
  SheetDescription, SheetFooter, SheetClose,
} from "@/components/ui/sheet"
import { applyTrafficFlowOverlay } from "@/shared/api/traffic-flow"
import type { ServerRead } from "@mmapp/contracts/servers"
import type { TrafficFlowOverlayResult } from "@mmapp/contracts/traffic-flow"
import {
  CheckIcon,
  CopyIcon,
  DownloadIcon,
  InfoIcon,
} from "lucide-react"

function FlowOverlaySheet({
  open,
  onOpenChange,
  servers,
  backendUrl,
  onDone,
}: {
  open: boolean
  onOpenChange: (v: boolean) => void
  servers: ServerRead[]
  backendUrl: string
  onDone?: (result: TrafficFlowOverlayResult) => void
}) {
  const jumpHosts = useMemo(
    () => servers.filter((s) => s.enabled && s.type === "jump-host"),
    [servers],
  )
  const [serverId, setServerId] = useState("")
  const [endpoint, setEndpoint] = useState("")
  const [busy, setBusy] = useState(false)
  const [result, setResult] = useState<TrafficFlowOverlayResult | null>(null)
  const [copied, setCopied] = useState(false)
  const [tab, setTab] = useState("linux")

  useEffect(() => {
    if (!open) return
    setResult(null)
    setCopied(false)
    setTab("linux")
    const first = jumpHosts[0]
    const nextId = first ? String(first.id) : ""
    setServerId(nextId)
    setEndpoint(first?.host ?? "")
  }, [open, jumpHosts])

  function handleServerChange(id: string) {
    setServerId(id)
    const selected = jumpHosts.find((s) => String(s.id) === id)
    if (selected) setEndpoint(selected.host)
  }

  const formats = result?.hostFiles ?? []
  const active = formats.find((f) => f.id === tab) ?? formats[0]
  const selectedHost = jumpHosts.find((s) => String(s.id) === serverId)
  const selectedLabel = selectedHost
    ? `${selectedHost.name || selectedHost.host} (${selectedHost.host})`
    : "Выберите сервер…"
  const canSubmit = Boolean(serverId && endpoint.trim()) && !busy

  async function handleSubmit() {
    if (!serverId || !endpoint.trim()) return
    setBusy(true)
    try {
      const res = await applyTrafficFlowOverlay(backendUrl, serverId, endpoint.trim())
      setResult(res)
      setTab(res.hostFiles[0]?.id ?? "linux")
      toast.success(`wg-flow на ${res.address}`)
      onDone?.(res)
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Не удалось подключить JH")
    } finally {
      setBusy(false)
    }
  }

  function handleCopy() {
    const code = active?.code ?? ""
    if (!code) return
    void navigator.clipboard.writeText(code).then(() => {
      setCopied(true)
      toast.success("Скопировано")
      setTimeout(() => setCopied(false), 1800)
    })
  }

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent
        side="right"
        className="flex w-full flex-col gap-0 overflow-hidden p-0 sm:max-w-2xl"
      >
        <SheetHeader className="shrink-0 gap-1 border-b px-5 pt-5 pb-4 pr-12">
          <SheetTitle className="text-base font-semibold tracking-tight">
            Подключить jump-host
          </SheetTitle>
          <SheetDescription>
            Создаст wg-flow на MikroTik (сервер, listen 13232) и выдаст готовый bash для Linux-хоста Docker MM (клиент).
          </SheetDescription>
        </SheetHeader>
        <div className="flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-5 py-4">
          <FormField label="Jump-host" required>
            <Select
              value={serverId || undefined}
              onValueChange={(v) => handleServerChange(String(v ?? ""))}
            >
              <SelectTrigger className="h-9 w-full min-w-0">
                <SelectValue>{selectedLabel}</SelectValue>
              </SelectTrigger>
              <SelectContent align="start" className="min-w-(--anchor-width)">
                {jumpHosts.map((s) => (
                  <SelectItem key={s.id} value={String(s.id)}>
                    {s.name || s.host} ({s.host})
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </FormField>
          <FormField
            label="Публичный IP или DNS jump-host"
            required
            hint="Куда хост MM (wg-quick) стучится по UDP 13232. Не контейнер backend."
          >
            <Input
              className="font-mono"
              value={endpoint}
              onChange={(e) => setEndpoint(e.target.value)}
              placeholder="jh.example.com"
              autoComplete="off"
            />
          </FormField>
          {result ? (
            <div className="flex min-h-0 flex-col gap-4">
              <Alert variant="success">
                <InfoIcon />
                <AlertTitle>Linux-хост /opt/cdn-mm</AlertTitle>
                <AlertDescription>
                  Скопируйте вкладку Linux и выполните от root. WG — клиент к JH:13232; контейнер слушает только WG-IP:4739, не 0.0.0.0. Ключ не кладите в git.
                </AlertDescription>
              </Alert>
              <ul className="flex flex-col gap-1.5">
                {result.steps.map((s) => (
                  <li key={s} className="flex items-start gap-2 text-sm">
                    <CheckIcon className="mt-0.5 size-3.5 shrink-0 text-success" />
                    <span>{s}</span>
                  </li>
                ))}
              </ul>
              {formats.length > 0 && active ? (
                <div className="flex min-h-0 flex-col gap-3">
                  <Tabs
                    value={tab}
                    onValueChange={(v) => {
                      setTab(String(v))
                      setCopied(false)
                    }}
                    className="shrink-0 gap-0"
                  >
                    <TabsList className="h-9 w-full">
                      {formats.map((f) => (
                        <TabsTrigger key={f.id} value={f.id} className="flex-1 px-2 text-xs sm:text-sm">
                          {f.label}
                        </TabsTrigger>
                      ))}
                    </TabsList>
                  </Tabs>
                  <Frame dense className="flex min-h-0 flex-col overflow-hidden">
                    <FramePanel className="relative flex min-h-0 flex-col overflow-hidden p-0">
                      <ScrollArea className="h-full min-h-0 max-h-[min(52vh,22rem)]">
                        <CodeBlock code={active.code} className="whitespace-pre break-normal" />
                      </ScrollArea>
                    </FramePanel>
                  </Frame>
                  <div className="flex items-center justify-end gap-2">
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      onClick={() => downloadText(active.filename, active.code)}
                    >
                      <DownloadIcon className="size-3.5" />
                      Файл
                    </Button>
                    <Button type="button" size="sm" onClick={handleCopy}>
                      {copied ? <CheckIcon className="size-3.5" /> : <CopyIcon className="size-3.5" />}
                      {copied ? "Скопировано" : "Копировать"}
                    </Button>
                  </div>
                </div>
              ) : null}
            </div>
          ) : null}
        </div>
        <SheetFooter className="shrink-0 flex-row items-center justify-between gap-3 border-t px-5 py-3.5 sm:flex-row">
          <SheetClose render={<Button type="button" variant="outline" className="shrink-0" />}>
            Закрыть
          </SheetClose>
          <Button disabled={!canSubmit} onClick={() => { void handleSubmit() }}>
            {busy ? "Подключение…" : "Подключить"}
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  )
}

export { FlowOverlaySheet }
