"use client";

import { useEffect, useRef, useState } from "react";
import { X } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { BarcodeFormat, PageNumberFormat } from "@/lib/editor/objects";

const SIGNATURE_STORAGE_KEY = "u2p-saved-signature";

export function Modal({
  title,
  onClose,
  children,
}: {
  title: string;
  onClose: () => void;
  children: React.ReactNode;
}) {
  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      if (e.key === "Escape") onClose();
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" onMouseDown={onClose}>
      <div
        className="w-full max-w-md rounded-lg border border-slate-200 bg-white p-5 shadow-xl dark:border-slate-700 dark:bg-slate-800"
        onMouseDown={(e) => e.stopPropagation()}
      >
        <div className="mb-4 flex items-center justify-between">
          <h2 className="font-semibold text-slate-900 dark:text-slate-100">{title}</h2>
          <button
            type="button"
            aria-label="Close"
            onClick={onClose}
            className="text-slate-400 hover:text-slate-600 dark:hover:text-slate-200"
          >
            <X className="h-5 w-5" />
          </button>
        </div>
        {children}
      </div>
    </div>
  );
}

const labelCls = "mb-1 block text-sm font-medium text-slate-700 dark:text-slate-300";
const selectCls =
  "h-10 w-full rounded-md border border-slate-300 bg-white px-2 text-sm text-slate-900 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100";

// ---------- QR ----------

export function QrDialog({ onInsert, onClose }: { onInsert: (content: string) => void; onClose: () => void }) {
  const [content, setContent] = useState("https://");
  return (
    <Modal title="Insert QR code" onClose={onClose}>
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault();
          if (!content.trim()) return;
          onInsert(content.trim());
          onClose();
        }}
      >
        <div>
          <label className={labelCls}>Content (URL or text)</label>
          <Input value={content} onChange={(e) => setContent(e.target.value)} autoFocus />
        </div>
        <Button type="submit" className="w-full">
          Insert QR code
        </Button>
      </form>
    </Modal>
  );
}

// ---------- Barcode ----------

export function BarcodeDialog({
  onInsert,
  onClose,
}: {
  onInsert: (content: string, format: BarcodeFormat) => void;
  onClose: () => void;
}) {
  const [content, setContent] = useState("");
  const [format, setFormat] = useState<BarcodeFormat>("CODE128");
  return (
    <Modal title="Insert barcode" onClose={onClose}>
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault();
          if (!content.trim()) return;
          onInsert(content.trim(), format);
          onClose();
        }}
      >
        <div>
          <label className={labelCls}>Value</label>
          <Input
            value={content}
            onChange={(e) => setContent(e.target.value)}
            placeholder={format === "EAN13" ? "13 digits" : "Text or numbers"}
            autoFocus
          />
        </div>
        <div>
          <label className={labelCls}>Format</label>
          <select className={selectCls} value={format} onChange={(e) => setFormat(e.target.value as BarcodeFormat)}>
            <option value="CODE128">Code 128 (any text)</option>
            <option value="CODE39">Code 39</option>
            <option value="EAN13">EAN-13</option>
            <option value="UPC">UPC</option>
          </select>
        </div>
        <Button type="submit" className="w-full">
          Insert barcode
        </Button>
      </form>
    </Modal>
  );
}

// ---------- Table ----------

export function TableDialog({
  onInsert,
  onClose,
}: {
  onInsert: (rows: number, cols: number) => void;
  onClose: () => void;
}) {
  const [rows, setRows] = useState(3);
  const [cols, setCols] = useState(3);
  return (
    <Modal title="Insert table" onClose={onClose}>
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault();
          onInsert(Math.min(20, Math.max(1, rows)), Math.min(8, Math.max(1, cols)));
          onClose();
        }}
      >
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className={labelCls}>Rows</label>
            <Input type="number" min={1} max={20} value={rows} onChange={(e) => setRows(Number(e.target.value))} />
          </div>
          <div>
            <label className={labelCls}>Columns</label>
            <Input type="number" min={1} max={8} value={cols} onChange={(e) => setCols(Number(e.target.value))} />
          </div>
        </div>
        <p className="text-xs text-slate-500 dark:text-slate-400">
          Double-click a cell to edit its text. Drag the table to move it.
        </p>
        <Button type="submit" className="w-full">
          Insert table
        </Button>
      </form>
    </Modal>
  );
}

// ---------- Watermark ----------

export function WatermarkDialog({
  onInsert,
  onClose,
}: {
  onInsert: (text: string, opacity: number, allPages: boolean) => void;
  onClose: () => void;
}) {
  const [text, setText] = useState("CONFIDENTIAL");
  const [opacity, setOpacity] = useState(0.3);
  const [allPages, setAllPages] = useState(true);
  return (
    <Modal title="Add watermark" onClose={onClose}>
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault();
          if (!text.trim()) return;
          onInsert(text.trim(), opacity, allPages);
          onClose();
        }}
      >
        <div>
          <label className={labelCls}>Text</label>
          <Input value={text} onChange={(e) => setText(e.target.value)} autoFocus />
        </div>
        <div>
          <label className={labelCls}>Opacity — {Math.round(opacity * 100)}%</label>
          <input
            type="range"
            min={0.05}
            max={1}
            step={0.05}
            value={opacity}
            onChange={(e) => setOpacity(Number(e.target.value))}
            className="w-full"
          />
        </div>
        <label className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
          <input type="checkbox" checked={allPages} onChange={(e) => setAllPages(e.target.checked)} />
          Apply to all pages
        </label>
        <Button type="submit" className="w-full">
          Add watermark
        </Button>
      </form>
    </Modal>
  );
}

// ---------- Header / Footer ----------

export function HeaderFooterDialog({
  where,
  onInsert,
  onClose,
}: {
  where: "header" | "footer";
  onInsert: (text: string, allPages: boolean) => void;
  onClose: () => void;
}) {
  const [text, setText] = useState("");
  const [allPages, setAllPages] = useState(true);
  return (
    <Modal title={where === "header" ? "Add header" : "Add footer"} onClose={onClose}>
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault();
          if (!text.trim()) return;
          onInsert(text.trim(), allPages);
          onClose();
        }}
      >
        <div>
          <label className={labelCls}>Text</label>
          <Input value={text} onChange={(e) => setText(e.target.value)} placeholder="Company report" autoFocus />
        </div>
        <label className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
          <input type="checkbox" checked={allPages} onChange={(e) => setAllPages(e.target.checked)} />
          Apply to all pages
        </label>
        <Button type="submit" className="w-full">
          Add {where}
        </Button>
      </form>
    </Modal>
  );
}

// ---------- Page numbers ----------

export function PageNumberDialog({
  onInsert,
  onClose,
}: {
  onInsert: (format: PageNumberFormat, position: "left" | "center" | "right") => void;
  onClose: () => void;
}) {
  const [format, setFormat] = useState<PageNumberFormat>("n");
  const [position, setPosition] = useState<"left" | "center" | "right">("center");
  return (
    <Modal title="Add page numbers" onClose={onClose}>
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault();
          onInsert(format, position);
          onClose();
        }}
      >
        <div>
          <label className={labelCls}>Format</label>
          <select className={selectCls} value={format} onChange={(e) => setFormat(e.target.value as PageNumberFormat)}>
            <option value="n">1</option>
            <option value="n-of-total">1 / N</option>
            <option value="page-n">Page 1</option>
          </select>
        </div>
        <div>
          <label className={labelCls}>Position (bottom of page)</label>
          <select
            className={selectCls}
            value={position}
            onChange={(e) => setPosition(e.target.value as "left" | "center" | "right")}
          >
            <option value="left">Left</option>
            <option value="center">Center</option>
            <option value="right">Right</option>
          </select>
        </div>
        <p className="text-xs text-slate-500 dark:text-slate-400">Numbers are added to every page.</p>
        <Button type="submit" className="w-full">
          Add page numbers
        </Button>
      </form>
    </Modal>
  );
}

// ---------- Signature ----------

export function SignatureDialog({
  onInsertImage,
  onInsertTyped,
  onClose,
}: {
  onInsertImage: (dataUrl: string) => void;
  onInsertTyped: (name: string) => void;
  onClose: () => void;
}) {
  const [tab, setTab] = useState<"draw" | "type" | "upload">("draw");
  const [typedName, setTypedName] = useState("");
  const [savedSignature, setSavedSignature] = useState<string | null>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const drawingRef = useRef(false);
  const hasInkRef = useRef(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    try {
      setSavedSignature(localStorage.getItem(SIGNATURE_STORAGE_KEY));
    } catch {
      // localStorage unavailable — ignore
    }
  }, []);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas || tab !== "draw") return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;
    ctx.lineWidth = 2.5;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.strokeStyle = "#1e3a8a";

    function pos(e: PointerEvent) {
      const rect = canvas!.getBoundingClientRect();
      return { x: e.clientX - rect.left, y: e.clientY - rect.top };
    }
    function down(e: PointerEvent) {
      drawingRef.current = true;
      hasInkRef.current = true;
      const p = pos(e);
      ctx!.beginPath();
      ctx!.moveTo(p.x, p.y);
      canvas!.setPointerCapture(e.pointerId);
    }
    function move(e: PointerEvent) {
      if (!drawingRef.current) return;
      const p = pos(e);
      ctx!.lineTo(p.x, p.y);
      ctx!.stroke();
    }
    function up() {
      drawingRef.current = false;
    }
    canvas.addEventListener("pointerdown", down);
    canvas.addEventListener("pointermove", move);
    canvas.addEventListener("pointerup", up);
    return () => {
      canvas.removeEventListener("pointerdown", down);
      canvas.removeEventListener("pointermove", move);
      canvas.removeEventListener("pointerup", up);
    };
  }, [tab]);

  function clearPad() {
    const canvas = canvasRef.current;
    canvas?.getContext("2d")?.clearRect(0, 0, canvas.width, canvas.height);
    hasInkRef.current = false;
  }

  function insertDrawn(save: boolean) {
    const canvas = canvasRef.current;
    if (!canvas || !hasInkRef.current) {
      toast.error("Draw your signature first");
      return;
    }
    const dataUrl = canvas.toDataURL("image/png");
    if (save) {
      try {
        localStorage.setItem(SIGNATURE_STORAGE_KEY, dataUrl);
      } catch {
        // quota exceeded — still insert without saving
      }
    }
    onInsertImage(dataUrl);
    onClose();
  }

  function handleUpload(file: File | undefined) {
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => {
      onInsertImage(String(reader.result));
      onClose();
    };
    reader.readAsDataURL(file);
  }

  const tabCls = (active: boolean) =>
    `flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${
      active
        ? "bg-brand-600 text-white"
        : "bg-slate-100 text-slate-600 hover:bg-slate-200 dark:bg-slate-700 dark:text-slate-300"
    }`;

  return (
    <Modal title="Add signature" onClose={onClose}>
      <div className="mb-4 flex gap-2">
        <button type="button" className={tabCls(tab === "draw")} onClick={() => setTab("draw")}>
          Draw
        </button>
        <button type="button" className={tabCls(tab === "type")} onClick={() => setTab("type")}>
          Type
        </button>
        <button type="button" className={tabCls(tab === "upload")} onClick={() => setTab("upload")}>
          Upload
        </button>
      </div>

      {tab === "draw" && (
        <div className="space-y-3">
          <canvas
            ref={canvasRef}
            width={400}
            height={160}
            className="w-full touch-none rounded-md border border-dashed border-slate-300 bg-white dark:border-slate-600"
          />
          <div className="flex gap-2">
            <Button variant="secondary" size="sm" onClick={clearPad}>
              Clear
            </Button>
            <Button size="sm" className="flex-1" onClick={() => insertDrawn(true)}>
              Insert &amp; save for reuse
            </Button>
          </div>
          {savedSignature && (
            <button
              type="button"
              className="flex w-full items-center gap-3 rounded-md border border-slate-200 p-2 hover:border-brand-400 dark:border-slate-700"
              onClick={() => {
                onInsertImage(savedSignature);
                onClose();
              }}
            >
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img src={savedSignature} alt="Saved signature" className="h-10 bg-white" />
              <span className="text-sm text-slate-600 dark:text-slate-300">Use saved signature</span>
            </button>
          )}
        </div>
      )}

      {tab === "type" && (
        <form
          className="space-y-3"
          onSubmit={(e) => {
            e.preventDefault();
            if (!typedName.trim()) return;
            onInsertTyped(typedName.trim());
            onClose();
          }}
        >
          <Input value={typedName} onChange={(e) => setTypedName(e.target.value)} placeholder="Your name" autoFocus />
          {typedName.trim() && (
            <p className="rounded-md border border-slate-200 bg-white px-3 py-2 text-3xl text-blue-900 dark:border-slate-700" style={{ fontFamily: "Brush Script MT, cursive" }}>
              {typedName}
            </p>
          )}
          <Button type="submit" className="w-full">
            Insert signature
          </Button>
        </form>
      )}

      {tab === "upload" && (
        <div className="space-y-3">
          <input
            ref={fileInputRef}
            type="file"
            accept="image/png,image/jpeg"
            className="hidden"
            onChange={(e) => handleUpload(e.target.files?.[0])}
          />
          <Button variant="secondary" className="w-full" onClick={() => fileInputRef.current?.click()}>
            Choose image (PNG with transparency works best)
          </Button>
        </div>
      )}
    </Modal>
  );
}
