"use client";

import * as React from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Download, Eraser, FileSignature, Printer, RefreshCw } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Card, CardHeader, CardContent } from "@/components/ui/card";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter } from "@/components/ui/dialog";
import { StatusBadge } from "@/components/ui/badge";
import { fmtDateTime } from "@/lib/dates";
import { markContractSigned, generateContract } from "@/lib/actions/contracts";

export function ContractViewer({ contract, versions, canSign }: { contract: { id: string; code: string; version: number; status: string; html: string; signatureData: string | null; reservationId: string; reservationStatus: string }; versions: { id: string; version: number; status: string; createdAt: string }[]; canSign: boolean }) {
  const router = useRouter();
  const frame = React.useRef<HTMLIFrameElement>(null);
  const [signOpen, setSignOpen] = React.useState(false);
  const [busy, setBusy] = React.useState(false);

  const htmlWithSignature = React.useMemo(() => {
    if (!contract.signatureData) return contract.html;
    return contract.html.replace('<div class="sig">Tenant signature<br>', `<div class="sig"><img src="${contract.signatureData}" alt="signature" style="height:56px;display:block;margin:-60px 0 4px" />Tenant signature<br>`);
  }, [contract.html, contract.signatureData]);

  function print() {
    const w = frame.current?.contentWindow;
    if (!w) return;
    w.focus();
    w.print();
  }
  function download() {
    const blob = new Blob([htmlWithSignature], { type: "text/html" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `${contract.code}-v${contract.version}.html`;
    a.click();
    URL.revokeObjectURL(url);
  }
  async function regenerate() {
    setBusy(true);
    const res = await generateContract(contract.reservationId);
    setBusy(false);
    if (!res.ok) return toast.error(res.error);
    toast.success(`Contract v${res.data.version} generated`);
    router.push(`/contracts/${res.data.id}`);
  }

  return (
    <div className="grid gap-4 lg:grid-cols-[1fr_280px]">
      <Card className="overflow-hidden">
        <div className="flex flex-wrap items-center justify-between gap-2 border-b border-border px-4 py-2.5 no-print">
          <p className="text-xs text-fg-muted">Preview · PDF export uses the browser&apos;s “Save as PDF” in the print dialog.</p>
          <div className="flex items-center gap-1.5">
            <Button size="sm" variant="secondary" onClick={print}>
              <Printer /> Print / PDF
            </Button>
            <Button size="sm" variant="ghost" onClick={download}>
              <Download /> Download
            </Button>
          </div>
        </div>
        <iframe ref={frame} srcDoc={htmlWithSignature} title={`${contract.code} v${contract.version}`} className="h-[80vh] w-full bg-white" />
      </Card>
      <div className="space-y-4">
        <Card>
          <CardHeader title="Signature" description={contract.status === "SIGNED" ? "This version is signed." : "Capture the tenant's signature on screen or mark as signed on paper."} />
          <CardContent className="space-y-2">
            {contract.signatureData ? (
              // eslint-disable-next-line @next/next/no-img-element
              <img src={contract.signatureData} alt="Signature" className="h-16 rounded-md border border-border bg-white object-contain px-2" />
            ) : null}
            {canSign && contract.status !== "SIGNED" && contract.status !== "VOID" ? (
              <Button className="w-full" onClick={() => setSignOpen(true)}>
                <FileSignature /> Sign contract
              </Button>
            ) : null}
            {canSign && !["CANCELLED", "NO_SHOW"].includes(contract.reservationStatus) ? (
              <Button variant="secondary" className="w-full" loading={busy} onClick={regenerate}>
                <RefreshCw /> Generate new version
              </Button>
            ) : null}
          </CardContent>
        </Card>
        <Card>
          <CardHeader title="Versions" />
          <CardContent>
            <ul className="space-y-1.5">
              {versions.map((v) => (
                <li key={v.id}>
                  <Link href={`/contracts/${v.id}`} className={cn("flex items-center justify-between rounded-md px-2 py-1.5 text-sm hover:bg-surface-2", v.id === contract.id && "bg-surface-2 font-medium")}>
                    <span>
                      v{v.version} <span className="text-xs text-fg-subtle">· {fmtDateTime(v.createdAt)}</span>
                    </span>
                    <StatusBadge status={v.status} size="sm" />
                  </Link>
                </li>
              ))}
            </ul>
          </CardContent>
        </Card>
      </div>

      <Dialog open={signOpen} onOpenChange={setSignOpen}>
        <DialogContent size="md">
          <SignaturePad
            onCancel={() => setSignOpen(false)}
            onSave={async (data) => {
              setBusy(true);
              const res = await markContractSigned(contract.id, data ?? undefined);
              setBusy(false);
              if (!res.ok) return toast.error(res.error);
              toast.success("Contract marked as signed");
              setSignOpen(false);
              router.refresh();
            }}
            busy={busy}
          />
        </DialogContent>
      </Dialog>
    </div>
  );
}

function SignaturePad({ onSave, onCancel, busy }: { onSave: (data: string | null) => void; onCancel: () => void; busy: boolean }) {
  const canvas = React.useRef<HTMLCanvasElement>(null);
  const drawing = React.useRef(false);
  const [dirty, setDirty] = React.useState(false);
  React.useEffect(() => {
    const c = canvas.current;
    if (!c) return;
    const ratio = window.devicePixelRatio || 1;
    c.width = c.offsetWidth * ratio;
    c.height = 180 * ratio;
    const ctx = c.getContext("2d")!;
    ctx.scale(ratio, ratio);
    ctx.lineWidth = 2;
    ctx.lineCap = "round";
    ctx.strokeStyle = "#1c1917";
  }, []);
  const pos = (e: React.PointerEvent) => {
    const rect = canvas.current!.getBoundingClientRect();
    return { x: e.clientX - rect.left, y: e.clientY - rect.top };
  };
  return (
    <>
      <DialogHeader>
        <DialogTitle>Tenant signature</DialogTitle>
        <DialogDescription>Ask the guest to sign with finger, stylus or mouse. Or mark as signed on paper.</DialogDescription>
      </DialogHeader>
      <DialogBody>
        <canvas
          ref={canvas}
          className="h-[180px] w-full touch-none rounded-lg border border-border bg-white"
          onPointerDown={(e) => {
            drawing.current = true;
            const ctx = canvas.current!.getContext("2d")!;
            const p = pos(e);
            ctx.beginPath();
            ctx.moveTo(p.x, p.y);
            (e.target as HTMLElement).setPointerCapture(e.pointerId);
          }}
          onPointerMove={(e) => {
            if (!drawing.current) return;
            const ctx = canvas.current!.getContext("2d")!;
            const p = pos(e);
            ctx.lineTo(p.x, p.y);
            ctx.stroke();
            setDirty(true);
          }}
          onPointerUp={() => (drawing.current = false)}
          onPointerLeave={() => (drawing.current = false)}
        />
        <div className="mt-2 flex justify-between">
          <Button
            size="xs"
            variant="ghost"
            onClick={() => {
              const c = canvas.current!;
              c.getContext("2d")!.clearRect(0, 0, c.width, c.height);
              setDirty(false);
            }}
          >
            <Eraser /> Clear
          </Button>
          <Button size="xs" variant="ghost" onClick={() => onSave(null)} loading={busy}>
            Signed on paper
          </Button>
        </div>
      </DialogBody>
      <DialogFooter>
        <Button variant="secondary" onClick={onCancel}>
          Cancel
        </Button>
        <Button disabled={!dirty} loading={busy} onClick={() => onSave(canvas.current!.toDataURL("image/png"))}>
          <FileSignature /> Save signature
        </Button>
      </DialogFooter>
    </>
  );
}
