import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useRef, useState, useEffect } from "react";
import { accounting } from "@/lib/accountingClient";
import { supabase } from "@/integrations/supabase/client";
import { useCompanyId } from "./lib/useCompanyId";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Upload, X, Eye, Printer, Save, Info, Loader2 } from "lucide-react";
import { toast } from "sonner";
import { generateCheckPDF, generateTestAlignmentPDF, CHECK_FIELD_KEYS, CHECK_FIELD_LABELS } from "./lib/checkPdf";

export default function AccountingCheckSetupPage() {
  const { companyId, loading: companyLoading, error: companyError, associationId } = useCompanyId();
  const cid = companyId ?? "";
  const qc = useQueryClient();
  const sigRef = useRef<HTMLInputElement>(null);
  const [saving, setSaving] = useState(false);
  const [uploadingSig, setUploadingSig] = useState(false);

  const [bankName, setBankName] = useState("");
  const [bankAddress, setBankAddress] = useState("");
  const [routingNumber, setRoutingNumber] = useState("");
  const [accountNumber, setAccountNumber] = useState("");
  const [fractionalRouting, setFractionalRouting] = useState("");
  const [printSignature, setPrintSignature] = useState(false);
  const [signatureUrl, setSignatureUrl] = useState("");
  const [defaultStyle, setDefaultStyle] = useState("voucher");
  const [defaultPosition, setDefaultPosition] = useState("top");
  const [fontSize, setFontSize] = useState("medium");
  const [nextCheckNumber, setNextCheckNumber] = useState(1001);
  const [offsetX, setOffsetX] = useState(0);
  const [offsetY, setOffsetY] = useState(0);
  const [micrOffsetY, setMicrOffsetY] = useState(0);
  const [micrGap1, setMicrGap1] = useState(1);
  const [micrGap2, setMicrGap2] = useState(1);
  const [fieldPositions, setFieldPositions] = useState({});

  const { data: settings } = useQuery({
    queryKey: ["check-settings", cid],
    enabled: !!cid,
    queryFn: async () =>
      (await accounting.from("check_settings").select("*").eq("company_id", cid).maybeSingle()).data,
  });

  const { data: company } = useQuery({
    queryKey: ["company-detail", cid],
    enabled: !!cid,
    queryFn: async () =>
      (await accounting.from("companies").select("name,address,logo_url").eq("id", cid).single()).data,
  });

  useEffect(() => {
    if (!settings) return;
    const s = settings as any;
    setBankName(s.bank_name ?? "");
    setBankAddress(s.bank_address ?? "");
    setRoutingNumber(s.routing_number ?? "");
    setAccountNumber(s.account_number ?? "");
    setFractionalRouting(s.fractional_routing ?? "");
    setPrintSignature(s.print_signature ?? false);
    setSignatureUrl(s.signature_url ?? "");
    setDefaultStyle(s.default_style ?? "voucher");
    setDefaultPosition(s.default_position ?? "top");
    setFontSize(s.font_size ?? "medium");
    setNextCheckNumber(s.next_check_number ?? 1001);
    setOffsetX(Number(s.offset_x ?? 0));
    setOffsetY(Number(s.offset_y ?? 0));
    setMicrOffsetY(Number(s.micr_offset_y ?? 0));
    setMicrGap1(Number(s.micr_gap_1 ?? 1));
    setMicrGap2(Number(s.micr_gap_2 ?? 1));
    setFieldPositions(s.field_positions ?? {});
  }, [settings]);

  const routingValid = /^\d{9}$/.test(routingNumber.replace(/\D/g, ""));
  const accountValid = accountNumber.replace(/\D/g, "").length >= 4;

  const save = async () => {
    setSaving(true);
    const { error } = await accounting.from("check_settings").upsert({
      company_id: cid,
      bank_name: bankName || null,
      bank_address: bankAddress || null,
      routing_number: routingNumber.replace(/\D/g, "") || null,
      account_number: accountNumber.replace(/\D/g, "") || null,
      fractional_routing: fractionalRouting || null,
      print_signature: printSignature,
      signature_url: signatureUrl || null,
      default_style: defaultStyle,
      default_position: defaultPosition,
      font_size: fontSize,
      next_check_number: nextCheckNumber,
      offset_x: offsetX,
      offset_y: offsetY,
      micr_offset_y: micrOffsetY,
      micr_gap_1: micrGap1,
      micr_gap_2: micrGap2,
      field_positions: fieldPositions,
    }, { onConflict: "company_id" });
    setSaving(false);
    if (error) return toast.error(error.message);
    toast.success("Check settings saved");
    qc.invalidateQueries({ queryKey: ["check-settings", cid] });
  };

  const uploadSignature = async (file: File) => {
    setUploadingSig(true);
    const path = `${cid}/signature.png`;
    const { error } = await supabase.storage.from("signatures").upload(path, file, {
      contentType: file.type, upsert: true,
    });
    if (error) { toast.error(error.message); setUploadingSig(false); return; }
    const { data } = supabase.storage.from("signatures").getPublicUrl(path);
    setSignatureUrl(data.publicUrl + `?t=${Date.now()}`);
    toast.success("Signature uploaded — save to keep it");
    setUploadingSig(false);
  };

  const previewCheck = () => {
    const dataUrl = generateCheckPDF([{
      companyName: (company as any)?.name ?? "Association Name",
      companyAddress: (company as any)?.address ?? undefined,
      bankName: bankName || undefined,
      bankAddress: bankAddress || undefined,
      routingNumber: routingNumber.replace(/\D/g, "") || undefined,
      accountNumber: accountNumber.replace(/\D/g, "") || undefined,
      fractionalRouting: fractionalRouting || undefined,
      checkNumber: nextCheckNumber,
      date: new Date().toLocaleDateString("en-US", { month: "2-digit", day: "2-digit", year: "numeric" }),
      payee: "Sample Payee Name",
      amount: 1234.56,
      memo: "Sample memo line",
      printSignature,
      signatureDataUrl: signatureUrl || undefined,
    }], {
      style: defaultStyle as any,
      position: defaultPosition as any,
      fontSize: fontSize as any,
      offsetX, offsetY, micrOffsetY, micrGap1, micrGap2, fieldPositions,
    });
    const w = window.open("");
    if (w) w.document.write(`<iframe src="${dataUrl}" style="border:0;width:100%;height:100vh"></iframe>`);
  };

  const printAlignment = () => {
    const dataUrl = generateTestAlignmentPDF({
      style: defaultStyle as any,
      position: defaultPosition as any,
      fontSize: fontSize as any,
      offsetX, offsetY, micrOffsetY, micrGap1, micrGap2, fieldPositions,
    });
    const w = window.open("");
    if (w) w.document.write(`<iframe src="${dataUrl}" style="border:0;width:100%;height:100vh" onload="this.contentWindow.print()"></iframe>`);
  };

  const updateFieldPos = (key, patch) =>
    setFieldPositions((prev) => ({ ...prev, [key]: { ...(prev[key] || {}), ...patch } }));
  const resetFieldPos = (key) =>
    setFieldPositions((prev) => { const n = { ...prev }; delete n[key]; return n; });

  if (!associationId) return <p className="text-sm text-muted-foreground">Select an association.</p>;
  if (companyLoading) return <div className="flex justify-center py-12"><Loader2 className="h-6 w-6 animate-spin text-muted-foreground" /></div>;
  if (companyError || !companyId) return <p className="text-sm text-muted-foreground text-center py-12">{companyError || "Accounting setup is not ready."}</p>;

  return (
    <div className="space-y-6 max-w-2xl">

      {/* ── Bank Account ── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-base">Bank Account</CardTitle>
          <CardDescription>Printed on the check face and MICR line.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-1">
              <Label>Bank name</Label>
              <Input value={bankName} onChange={(e) => setBankName(e.target.value)} placeholder="First National Bank" />
            </div>
            <div className="space-y-1">
              <Label>Bank city / address</Label>
              <Input value={bankAddress} onChange={(e) => setBankAddress(e.target.value)} placeholder="Largo, FL" />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-1">
              <div className="flex items-center justify-between">
                <Label>Routing number (ABA)</Label>
                {routingNumber.length > 0 && (
                  <span className={`text-xs font-medium ${routingValid ? "text-emerald-600" : "text-red-500"}`}>
                    {routingValid ? "✓ Valid" : "Must be 9 digits"}
                  </span>
                )}
              </div>
              <Input
                value={routingNumber}
                onChange={(e) => setRoutingNumber(e.target.value.replace(/\D/g, "").slice(0, 9))}
                placeholder="123456789"
                className="font-mono"
                maxLength={9}
              />
            </div>
            <div className="space-y-1">
              <div className="flex items-center justify-between">
                <Label>Account number</Label>
                {accountNumber.length > 0 && (
                  <span className={`text-xs font-medium ${accountValid ? "text-emerald-600" : "text-amber-600"}`}>
                    {accountValid ? "✓ Set" : "Too short"}
                  </span>
                )}
              </div>
              <Input
                value={accountNumber}
                onChange={(e) => setAccountNumber(e.target.value.replace(/\D/g, ""))}
                placeholder="1234567890"
                className="font-mono"
              />
            </div>
          </div>

          <div className="space-y-1">
            <Label>
              Fractional routing{" "}
              <span className="text-muted-foreground text-xs font-normal">(optional — e.g. 12-3456/0789)</span>
            </Label>
            <Input
              value={fractionalRouting}
              onChange={(e) => setFractionalRouting(e.target.value)}
              placeholder="12-3456/0789"
              className="font-mono max-w-[200px]"
            />
          </div>

          <p className="text-xs text-muted-foreground flex items-start gap-1.5">
            <Info className="h-3.5 w-3.5 mt-0.5 shrink-0" />
            These numbers print in the MICR band at the bottom of every check. Ensure they exactly match your bank account.
          </p>
        </CardContent>
      </Card>

      {/* ── Signature ── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-base">Authorized Signature</CardTitle>
          <CardDescription>Upload a signature image to auto-print on checks.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="flex items-start gap-5">
            <div className="shrink-0 w-52 h-20 rounded-md border-2 border-dashed border-border bg-muted/30 flex items-center justify-center overflow-hidden">
              {signatureUrl
                ? <img src={signatureUrl} alt="Signature preview" className="max-h-full max-w-full object-contain p-1" />
                : <span className="text-xs text-muted-foreground">No signature uploaded</span>
              }
            </div>
            <div className="space-y-2 pt-1">
              <div className="flex gap-2 flex-wrap">
                <Button variant="outline" size="sm" onClick={() => sigRef.current?.click()} disabled={uploadingSig}>
                  <Upload className="h-3.5 w-3.5 mr-1" />
                  {uploadingSig ? "Uploading…" : "Upload signature"}
                </Button>
                {signatureUrl && (
                  <Button variant="ghost" size="sm" onClick={() => { setSignatureUrl(""); setPrintSignature(false); }}>
                    <X className="h-3.5 w-3.5 mr-1" /> Remove
                  </Button>
                )}
              </div>
              <p className="text-xs text-muted-foreground">PNG with transparent background recommended. Max 400×100px.</p>
              <input
                ref={sigRef}
                type="file"
                accept="image/png,image/jpeg,image/gif,image/webp"
                className="hidden"
                onChange={(e) => { const f = e.target.files?.[0]; if (f) uploadSignature(f); e.target.value = ""; }}
              />
            </div>
          </div>

          <div className="flex items-center gap-3 pt-1">
            <Switch
              id="print-sig"
              checked={printSignature}
              onCheckedChange={setPrintSignature}
              disabled={!signatureUrl}
            />
            <Label htmlFor="print-sig" className="cursor-pointer">
              Auto-print signature on checks
              {!signatureUrl && <span className="ml-1 text-xs text-muted-foreground">(upload a signature first)</span>}
            </Label>
          </div>
        </CardContent>
      </Card>

      {/* ── Print Settings ── */}
      <Card>
        <CardHeader>
          <CardTitle className="text-base">Print Settings</CardTitle>
          <CardDescription>Default layout applied when printing from Bills or Banking.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-5">

          <div className="grid grid-cols-3 gap-4">
            <div className="space-y-1">
              <Label>Check style</Label>
              <Select value={defaultStyle} onValueChange={setDefaultStyle}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="voucher">Voucher (3-part)</SelectItem>
                  <SelectItem value="standard">Check only</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label>Position</Label>
              <Select value={defaultPosition} onValueChange={setDefaultPosition}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="top">Top of page</SelectItem>
                  <SelectItem value="middle">Middle</SelectItem>
                  <SelectItem value="bottom">Bottom</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label>Font size</Label>
              <Select value={fontSize} onValueChange={setFontSize}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="small">Small</SelectItem>
                  <SelectItem value="medium">Medium</SelectItem>
                  <SelectItem value="large">Large</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="space-y-1 max-w-[160px]">
            <Label>Next check number</Label>
            <Input
              type="number"
              min={1}
              value={nextCheckNumber}
              onChange={(e) => setNextCheckNumber(parseInt(e.target.value) || 1001)}
              className="font-mono"
            />
          </div>

          <div className="rounded-md border bg-muted/20 p-4 space-y-3">
            <p className="text-sm font-medium">Position adjustments <span className="text-xs font-normal text-muted-foreground">(inches)</span></p>
            <div className="grid grid-cols-3 gap-6">
              <OffsetControl label="X offset (←/→)" hint="+right / −left" value={offsetX} onChange={setOffsetX} />
              <OffsetControl label="Y offset (↑/↓)" hint="+down / −up" value={offsetY} onChange={setOffsetY} />
              <OffsetControl label="MICR Y only" hint="Fine-tune MICR band" value={micrOffsetY} onChange={setMicrOffsetY} />
            </div>
            <p className="text-xs text-muted-foreground">
              Run the alignment test first, measure the offset on blank paper, then adjust here and preview again.
            </p>
            <div className="border-t pt-3">
              <p className="text-sm font-medium">MICR gaps <span className="text-xs font-normal text-muted-foreground">(spaces between segments)</span></p>
              <div className="grid grid-cols-2 gap-6 mt-2">
                <GapControl label="Check # → Routing" value={micrGap1} onChange={setMicrGap1} />
                <GapControl label="Routing → Account" value={micrGap2} onChange={setMicrGap2} />
              </div>
            </div>

            <div className="border-t pt-3">
              <p className="text-sm font-medium">Element positions <span className="text-xs font-normal text-muted-foreground">(nudge any element; inches, +right / +down)</span></p>
              <div className="mt-2 grid grid-cols-12 gap-2 text-xs font-semibold text-muted-foreground px-1">
                <div className="col-span-5">Element</div>
                <div className="col-span-2 text-center">Show</div>
                <div className="col-span-2">X</div>
                <div className="col-span-2">Y</div>
                <div className="col-span-1" />
              </div>
              {CHECK_FIELD_KEYS.map((key) => {
                const fp = fieldPositions[key] || {};
                return (
                  <div key={key} className="grid grid-cols-12 gap-2 items-center px-1 py-1 rounded hover:bg-background">
                    <div className="col-span-5 text-sm">{CHECK_FIELD_LABELS[key]}</div>
                    <div className="col-span-2 flex justify-center">
                      <Switch checked={fp.hidden !== true} onCheckedChange={(v) => updateFieldPos(key, { hidden: !v })} />
                    </div>
                    <div className="col-span-2">
                      <Input type="number" step="0.05" className="h-7 text-xs font-mono" value={fp.dx ?? 0}
                        onChange={(e) => updateFieldPos(key, { dx: parseFloat(e.target.value) || 0 })} />
                    </div>
                    <div className="col-span-2">
                      <Input type="number" step="0.05" className="h-7 text-xs font-mono" value={fp.dy ?? 0}
                        onChange={(e) => updateFieldPos(key, { dy: parseFloat(e.target.value) || 0 })} />
                    </div>
                    <div className="col-span-1 text-right">
                      <button type="button" onClick={() => resetFieldPos(key)} title="Reset"
                        className="text-xs text-muted-foreground hover:text-foreground">↺</button>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>

          <div className="flex gap-2 flex-wrap">
            <Button variant="outline" onClick={previewCheck}>
              <Eye className="h-4 w-4 mr-1" /> Preview sample check
            </Button>
            <Button variant="outline" onClick={printAlignment}>
              <Printer className="h-4 w-4 mr-1" /> Print alignment test
            </Button>
          </div>
        </CardContent>
      </Card>

      <div className="flex justify-end">
        <Button onClick={save} disabled={saving}>
          <Save className="h-4 w-4 mr-1" />
          {saving ? "Saving…" : "Save check settings"}
        </Button>
      </div>
    </div>
  );
}

function GapControl({ label, value, onChange }: {
  label: string; value: number; onChange: (v: number) => void;
}) {
  const adj = (d: number) => onChange(Math.max(0, Math.round(value + d)));
  return (
    <div className="space-y-1.5">
      <p className="text-xs font-medium text-foreground">{label}</p>
      <div className="flex items-center gap-1">
        <button onClick={() => adj(-1)}
          className="h-7 w-7 rounded border bg-background hover:bg-muted flex items-center justify-center font-bold text-sm shrink-0">
          −
        </button>
        <Input
          type="number"
          min={0}
          step={1}
          value={value}
          onChange={(e) => onChange(Math.max(0, parseInt(e.target.value) || 0))}
          className="h-7 text-center font-mono text-xs"
        />
        <button onClick={() => adj(1)}
          className="h-7 w-7 rounded border bg-background hover:bg-muted flex items-center justify-center font-bold text-sm shrink-0">
          +
        </button>
      </div>
    </div>
  );
}

function OffsetControl({ label, hint, value, onChange }: {
  label: string; hint: string; value: number; onChange: (v: number) => void;
}) {
  const STEP = 0.05;
  const adj = (d: number) => onChange(Math.round((value + d) * 1000) / 1000);

  return (
    <div className="space-y-1.5">
      <p className="text-xs font-medium text-foreground">{label}</p>
      <div className="flex items-center gap-1">
        <button onClick={() => adj(-STEP)}
          className="h-7 w-7 rounded border bg-background hover:bg-muted flex items-center justify-center font-bold text-sm shrink-0">
          −
        </button>
        <Input
          type="number"
          step={STEP}
          value={value}
          onChange={(e) => onChange(parseFloat(e.target.value) || 0)}
          className="h-7 text-center font-mono text-xs"
        />
        <button onClick={() => adj(STEP)}
          className="h-7 w-7 rounded border bg-background hover:bg-muted flex items-center justify-center font-bold text-sm shrink-0">
          +
        </button>
      </div>
      <p className="text-[10px] text-muted-foreground leading-tight">{hint}</p>
    </div>
  );
}
