"use client";

import { useEffect, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useTranslations } from "next-intl";
import { Server, Wifi, WifiOff, Trash2, Plus, Loader2 } from "lucide-react";
import { apiGet, apiPatch } from "@/lib/api/client";
import {
  listPrintAgents,
  createPairingCode,
  revokePrintAgent,
  testPrintDevice,
  deviceOptions,
  type PairingCode,
} from "@/lib/api/print-agents";
import { printErrorMessage } from "@/lib/api/print";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { LabeledField } from "@/components/ui/labeled-field";
import { useConfirm } from "@/components/providers/confirm-provider";
import { notify } from "@/lib/notify";

type BranchPrintSettings = {
  branchId: string;
  receiptPrinterIp?: string | null;
  receiptPrinterPort?: number | null;
  kitchenPrinterIp?: string | null;
  kitchenPrinterPort?: number | null;
  paperWidthMm: number;
  autoCutEnabled: boolean;
  receiptHeader?: string | null;
  receiptFooter?: string | null;
  wifiPassword?: string | null;
  posDeviceIp?: string | null;
  posDevicePort?: number | null;
  receiptPrintDeviceId?: string | null;
  kitchenPrintDeviceId?: string | null;
};

type SettingsPrinterPanelProps = {
  cafeId: string;
  onOpenPrintTest?: () => void;
};

export function SettingsPrinterPanel({ cafeId, onOpenPrintTest }: SettingsPrinterPanelProps) {
  const t = useTranslations("print");
  const tSettings = useTranslations("settings");
  const tCommon = useTranslations("common");
  const [message, setMessage] = useState<string | null>(null);

  const [receiptIp, setReceiptIp] = useState("");
  const [receiptPort, setReceiptPort] = useState("9100");
  const [kitchenIp, setKitchenIp] = useState("");
  const [kitchenPort, setKitchenPort] = useState("9100");
  const [paperWidth, setPaperWidth] = useState("80");
  const [autoCut, setAutoCut] = useState(true);
  const [receiptHeader, setReceiptHeader] = useState("");
  const [receiptFooter, setReceiptFooter] = useState("");
  const [wifiPassword, setWifiPassword] = useState("");
  const [posDeviceIp, setPosDeviceIp] = useState("");
  const [posDevicePort, setPosDevicePort] = useState("8088");
  const [receiptDeviceId, setReceiptDeviceId] = useState("");
  const [kitchenDeviceId, setKitchenDeviceId] = useState("");

  const { data: agents = [] } = useQuery({
    queryKey: ["print-agents", cafeId],
    queryFn: () => listPrintAgents(cafeId),
    enabled: !!cafeId,
  });
  const devices = deviceOptions(agents);

  const { data: branches = [], isLoading: branchesLoading } = useQuery({
    queryKey: ["branches", cafeId],
    queryFn: () => apiGet<{ id: string }[]>(`/api/cafes/${cafeId}/branches`),
    enabled: !!cafeId,
  });

  const branchId = branches[0]?.id;

  const { data: settings, refetch } = useQuery({
    queryKey: ["branch-print-settings", cafeId, branchId],
    queryFn: () =>
      apiGet<BranchPrintSettings>(
        `/api/cafes/${cafeId}/branches/${branchId}/print-settings`
      ),
    enabled: !!cafeId && !!branchId,
  });

  useEffect(() => {
    if (!settings) return;
    setReceiptIp(settings.receiptPrinterIp ?? "");
    setReceiptPort(String(settings.receiptPrinterPort ?? 9100));
    setKitchenIp(settings.kitchenPrinterIp ?? "");
    setKitchenPort(String(settings.kitchenPrinterPort ?? 9100));
    setPaperWidth(String(settings.paperWidthMm === 58 ? 58 : 80));
    setAutoCut(settings.autoCutEnabled);
    setReceiptHeader(settings.receiptHeader ?? "");
    setReceiptFooter(settings.receiptFooter ?? "");
    setWifiPassword(settings.wifiPassword ?? "");
    setPosDeviceIp(settings.posDeviceIp ?? "");
    setPosDevicePort(String(settings.posDevicePort ?? 8088));
    setReceiptDeviceId(settings.receiptPrintDeviceId ?? "");
    setKitchenDeviceId(settings.kitchenPrintDeviceId ?? "");
  }, [settings]);

  const save = useMutation({
    mutationFn: () =>
      apiPatch<BranchPrintSettings>(
        `/api/cafes/${cafeId}/branches/${branchId}/print-settings`,
        {
          receiptPrinterIp: receiptIp.trim() || null,
          receiptPrinterPort: parseInt(receiptPort, 10) || 9100,
          kitchenPrinterIp: kitchenIp.trim() || null,
          kitchenPrinterPort: parseInt(kitchenPort, 10) || 9100,
          paperWidthMm: paperWidth === "58" ? 58 : 80,
          autoCutEnabled: autoCut,
          receiptHeader: receiptHeader.trim() || null,
          receiptFooter: receiptFooter.trim() || null,
          wifiPassword: wifiPassword.trim() || null,
          posDeviceIp: posDeviceIp.trim() || null,
          posDevicePort: parseInt(posDevicePort, 10) || 8088,
          receiptPrintDeviceId: receiptDeviceId || null,
          kitchenPrintDeviceId: kitchenDeviceId || null,
        }
      ),
    onSuccess: () => {
      setMessage(t("settingsSaved"));
      void refetch();
    },
  });

  const qc = useQueryClient();
  const confirm = useConfirm();
  const [pairing, setPairing] = useState<PairingCode | null>(null);

  const createCode = useMutation({
    mutationFn: () => createPairingCode(cafeId),
    onSuccess: (c) => {
      setPairing(c);
      void qc.invalidateQueries({ queryKey: ["print-agents", cafeId] });
    },
    onError: () => notify.error(t("agents.codeError")),
  });
  const revoke = useMutation({
    mutationFn: (id: string) => revokePrintAgent(cafeId, id),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["print-agents", cafeId] }),
  });
  const testDevice = useMutation({
    mutationFn: (deviceId: string) => testPrintDevice(cafeId, deviceId),
    onSuccess: () => notify.success(t("testSent")),
    onError: (err) => notify.error(printErrorMessage(err, t)),
  });

  const handleRevoke = async (id: string, name: string) => {
    const ok = await confirm({
      description: t("agents.revokeConfirm", { name }),
      variant: "destructive",
      confirmLabel: tCommon("confirm"),
    });
    if (ok) revoke.mutate(id);
  };

  if (branchesLoading) {
    return <p className="text-sm text-muted-foreground">{tCommon("loading")}</p>;
  }

  if (!branchId) {
    return (
      <Card className="rounded-xl border border-border/80 shadow-sm">
        <CardContent className="pt-6">
          <p className="text-sm text-muted-foreground">{t("noBranchForPrinter")}</p>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className="rounded-xl border border-border/80 shadow-sm">
      <CardHeader className="flex flex-row flex-wrap items-center justify-between gap-3 space-y-0 px-6 pb-4 pt-6">
        <CardTitle className="text-base font-medium">{t("printerSettings")}</CardTitle>
        {onOpenPrintTest ? (
          <Button variant="outline" size="sm" onClick={onOpenPrintTest}>
            {tSettings("nav.printTest")}
          </Button>
        ) : null}
      </CardHeader>
      <CardContent className="space-y-6 px-6 pb-6 pt-0">
        {message ? (
          <p className="rounded-lg border border-border/80 bg-muted/40 px-4 py-2.5 text-xs">
            {message}
          </p>
        ) : null}

        {/* Print servers — auto-discovered printers via the local agent */}
        <section className="space-y-3 rounded-lg border border-border/80 bg-muted/20 p-4 sm:p-5">
          <div className="flex flex-wrap items-center justify-between gap-2">
            <div className="space-y-1">
              <p className="flex items-center gap-1.5 text-sm font-medium">
                <Server className="size-4 text-[#0F6E56]" />
                {t("agents.title")}
              </p>
              <p className="text-xs leading-relaxed text-muted-foreground">{t("agents.hint")}</p>
            </div>
            <Button
              size="sm"
              variant="outline"
              className="shrink-0 gap-1.5"
              disabled={createCode.isPending}
              onClick={() => createCode.mutate()}
            >
              {createCode.isPending ? <Loader2 className="size-4 animate-spin" /> : <Plus className="size-4" />}
              {t("agents.add")}
            </Button>
          </div>

          {pairing ? (
            <div className="rounded-lg border border-[#0F6E56]/30 bg-[#E1F5EE]/50 p-3 text-sm dark:bg-[#0F6E56]/10">
              <p className="font-medium">{t("agents.pairingTitle")}</p>
              <p className="my-2 text-center font-mono text-2xl font-bold tracking-[0.3em] text-[#0F6E56]">
                {pairing.code}
              </p>
              <p className="text-xs leading-relaxed text-muted-foreground">{t("agents.pairingSteps")}</p>
            </div>
          ) : null}

          {agents.length === 0 ? (
            <p className="py-2 text-center text-xs text-muted-foreground">{t("agents.empty")}</p>
          ) : (
            <ul className="space-y-2">
              {agents.map((a) => (
                <li key={a.id} className="rounded-lg border border-border/70 bg-background p-3">
                  <div className="flex flex-wrap items-center gap-2">
                    {a.online ? (
                      <Wifi className="size-4 shrink-0 text-emerald-600" />
                    ) : (
                      <WifiOff className="size-4 shrink-0 text-muted-foreground" />
                    )}
                    <span className="min-w-0 flex-1 truncate text-sm font-medium">{a.name}</span>
                    <span className={a.online ? "text-[11px] text-emerald-600" : "text-[11px] text-muted-foreground"}>
                      {a.online ? t("agents.online") : t("agents.offline")}
                    </span>
                    <Button
                      size="icon"
                      variant="ghost"
                      className="h-7 w-7 text-destructive hover:text-destructive"
                      disabled={revoke.isPending}
                      onClick={() => handleRevoke(a.id, a.name)}
                    >
                      <Trash2 className="size-3.5" />
                    </Button>
                  </div>
                  {a.devices.length > 0 ? (
                    <ul className="mt-2 space-y-1 ps-6">
                      {a.devices.map((d) => (
                        <li key={d.id} className="flex items-center gap-2 text-xs">
                          <span className="min-w-0 flex-1 truncate text-muted-foreground">
                            {d.displayName} <span className="opacity-60">({d.kind})</span>
                          </span>
                          <Button
                            size="sm"
                            variant="ghost"
                            className="h-6 px-2 text-[11px]"
                            disabled={!a.online || testDevice.isPending}
                            onClick={() => testDevice.mutate(d.id)}
                          >
                            {t("agents.test")}
                          </Button>
                        </li>
                      ))}
                    </ul>
                  ) : a.online ? (
                    <p className="mt-1 ps-6 text-[11px] text-muted-foreground">{t("agents.noDevices")}</p>
                  ) : null}
                </li>
              ))}
            </ul>
          )}

          {devices.length > 0 ? (
            <div className="grid gap-4 border-t border-border/60 pt-3 sm:grid-cols-2">
              <LabeledField label={t("agents.receiptVia")} htmlFor="receipt-device">
                <select
                  id="receipt-device"
                  className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm"
                  value={receiptDeviceId}
                  onChange={(e) => setReceiptDeviceId(e.target.value)}
                >
                  <option value="">{t("agents.useIpInstead")}</option>
                  {devices.map((d) => (
                    <option key={d.id} value={d.id}>
                      {d.label}{d.online ? "" : ` (${t("agents.offline")})`}
                    </option>
                  ))}
                </select>
              </LabeledField>
              <LabeledField label={t("agents.kitchenVia")} htmlFor="kitchen-device">
                <select
                  id="kitchen-device"
                  className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm"
                  value={kitchenDeviceId}
                  onChange={(e) => setKitchenDeviceId(e.target.value)}
                >
                  <option value="">{t("agents.useIpInstead")}</option>
                  {devices.map((d) => (
                    <option key={d.id} value={d.id}>
                      {d.label}{d.online ? "" : ` (${t("agents.offline")})`}
                    </option>
                  ))}
                </select>
              </LabeledField>
            </div>
          ) : null}
        </section>

        <section className="space-y-4">
        <div className="grid gap-4 sm:grid-cols-2">
          <LabeledField label={t("receiptPrinter")} htmlFor="receipt-ip">
            <Input
              id="receipt-ip"
              value={receiptIp}
              onChange={(e) => setReceiptIp(e.target.value)}
              placeholder="192.168.1.100"
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("port")} htmlFor="receipt-port">
            <Input
              id="receipt-port"
              value={receiptPort}
              onChange={(e) => setReceiptPort(e.target.value)}
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("kitchenPrinter")} htmlFor="kitchen-ip">
            <Input
              id="kitchen-ip"
              value={kitchenIp}
              onChange={(e) => setKitchenIp(e.target.value)}
              placeholder="192.168.1.101"
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("port")} htmlFor="kitchen-port">
            <Input
              id="kitchen-port"
              value={kitchenPort}
              onChange={(e) => setKitchenPort(e.target.value)}
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("paperWidth")} htmlFor="paper-width">
            <select
              id="paper-width"
              className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm"
              value={paperWidth}
              onChange={(e) => setPaperWidth(e.target.value)}
            >
              <option value="80">80mm</option>
              <option value="58">58mm</option>
            </select>
          </LabeledField>
          <LabeledField label={t("autoCut")} htmlFor="auto-cut">
            <label className="flex h-10 items-center gap-2 text-sm">
              <input
                id="auto-cut"
                type="checkbox"
                checked={autoCut}
                onChange={(e) => setAutoCut(e.target.checked)}
              />
              {t("autoCut")}
            </label>
          </LabeledField>
        </div>
        </section>

        <section className="space-y-4 border-t border-border/80 pt-6">
        <LabeledField label={t("receiptHeader")} htmlFor="receipt-header">
          <Input
            id="receipt-header"
            value={receiptHeader}
            onChange={(e) => setReceiptHeader(e.target.value)}
          />
        </LabeledField>
        <LabeledField label={t("receiptFooter")} htmlFor="receipt-footer">
          <Input
            id="receipt-footer"
            value={receiptFooter}
            onChange={(e) => setReceiptFooter(e.target.value)}
          />
        </LabeledField>
        <LabeledField label={t("wifiOnReceipt")} htmlFor="wifi-pass">
          <Input
            id="wifi-pass"
            value={wifiPassword}
            onChange={(e) => setWifiPassword(e.target.value)}
            dir="ltr"
            className="text-end"
          />
        </LabeledField>
        </section>

        <section className="space-y-4 rounded-lg border border-border/80 bg-muted/20 p-4 sm:p-5">
          <div className="space-y-1">
            <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
              {t("posDeviceSection")}
            </p>
            <p className="text-xs leading-relaxed text-muted-foreground">{t("posDeviceHint")}</p>
          </div>
        <div className="grid gap-4 sm:grid-cols-2">
          <LabeledField label={t("posDeviceIp")} htmlFor="pos-device-ip">
            <Input
              id="pos-device-ip"
              value={posDeviceIp}
              onChange={(e) => setPosDeviceIp(e.target.value)}
              placeholder="192.168.1.50"
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("port")} htmlFor="pos-device-port">
            <Input
              id="pos-device-port"
              value={posDevicePort}
              onChange={(e) => setPosDevicePort(e.target.value)}
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
        </div>
        </section>

        <div className="border-t border-border/80 pt-4">
          <Button
            className="bg-[#0F6E56] hover:bg-[#0c5e46]"
            disabled={save.isPending}
            onClick={() => save.mutate()}
          >
            {t("saveSettings")}
          </Button>
        </div>
      </CardContent>
    </Card>
  );
}
