import { useState, useEffect, useRef } from "react";
import { Mail, Printer, Settings, Users, Plus, Save, Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Checkbox } from "@/components/ui/checkbox";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Badge } from "@/components/ui/badge";
import { supabase } from "@/integrations/supabase/client";
import { useAssociation } from "@/contexts/AssociationContext";
import { useToast } from "@/hooks/use-toast";

const ENVELOPE_SIZES = {
  "#10": { label: "#10 Standard (4⅛ × 9½ in)", width: "9.5in", height: "4.125in" },
  "#9": { label: "#9 Reply (3⅞ × 8⅞ in)", width: "8.875in", height: "3.875in" },
  "a7": { label: "A7 Invitation (5¼ × 7¼ in)", width: "7.25in", height: "5.25in" },
};

export default function BallotEnvelopeForm() {
  const { toast } = useToast();
  const associationCtx = useAssociation() || {};
  const selectedAssociation = associationCtx.selectedAssociation || "";

  const [envelopeSize, setEnvelopeSize] = useState("#10");
  const [printMode, setPrintMode] = useState("all-owners");
  const [associations, setAssociations] = useState([]);
  const [selectedAssoc, setSelectedAssoc] = useState(selectedAssociation || "");
  const [owners, setOwners] = useState([]);
  const [loadingOwners, setLoadingOwners] = useState(false);
  const [selectedOwnerIds, setSelectedOwnerIds] = useState(new Set());

  // Load associations
  useEffect(() => {
    (async () => {
      const { data } = await supabase
        .from("associations")
        .select("id, name, address, city, state, zip, care_of_address, mailing_address")
        .eq("status", "active")
        .order("name");
      setAssociations(data || []);
    })();
  }, []);

  // Sync with global association context
  useEffect(() => {
    if (selectedAssociation) setSelectedAssoc(selectedAssociation);
  }, [selectedAssociation]);

  // Load owners when association changes
  useEffect(() => {
    if (!selectedAssoc) {
      setOwners([]);
      setSelectedOwnerIds(new Set());
      setLoadingOwners(false);
      return;
    }

    let cancelled = false;
    const loadOwners = async () => {
      setLoadingOwners(true);
      try {
        const { data, error } = await supabase
          .from("owners")
          .select("id, first_name, last_name, mailing_address, property_address, street_address, unit_id, units(unit_number, address, city, state, zip)")
          .eq("association_id", selectedAssoc)
          .eq("status", "active")
          .order("last_name");

        if (error) throw error;
        if (!cancelled) {
          setOwners(data || []);
          setSelectedOwnerIds(new Set());
        }
      } catch (err) {
        console.error("Error loading owners:", err);
        if (!cancelled) setOwners([]);
      } finally {
        if (!cancelled) setLoadingOwners(false);
      }
    };

    loadOwners();
    return () => { cancelled = true; };
  }, [selectedAssoc]);

  const toggleOwner = (id) => {
    setSelectedOwnerIds((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };
  const selectAll = () => setSelectedOwnerIds(new Set(owners.map((o) => o.id)));
  const deselectAll = () => setSelectedOwnerIds(new Set());

  const getRecipients = () => {
    if (printMode === "selected") return owners.filter((o) => selectedOwnerIds.has(o.id));
    return owners;
  };

  const getAssocAddress = () => {
    const assoc = associations.find((a) => a.id === selectedAssoc);
    if (!assoc) return { name: "", line1: "", line2: "" };

    const mailingAddr = assoc.mailing_address || assoc.care_of_address;
    if (mailingAddr) {
      const lines = mailingAddr.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
      return {
        name: assoc.name,
        line1: lines[0] || "",
        line2: lines.slice(1).join(", ") || "",
      };
    }

    return {
      name: assoc.name,
      line1: assoc.address || "",
      line2: [assoc.city, assoc.state].filter(Boolean).join(", ") + (assoc.zip ? ` ${assoc.zip}` : ""),
    };
  };

  const getOwnerReturnBlock = (owner) => {
    const unit = Array.isArray(owner.units) ? owner.units[0] : owner.units;
    const name = `${owner.first_name || ""} ${owner.last_name || ""}`.trim();

    // Resolve property address
    let propAddr = owner.property_address || owner.street_address || "";
    if (!propAddr && unit) {
      propAddr = unit.address || unit.unit_number || "";
    }

    // Parse the address into lines
    const rawLines = propAddr.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((l) => l.trim()).filter(Boolean);
    let addrLine1 = "";
    let addrLine2 = "";

    if (rawLines.length >= 2) {
      addrLine1 = rawLines[0];
      addrLine2 = rawLines.slice(1).join(", ");
    } else if (rawLines.length === 1) {
      // Try to split at last comma before a state/zip pattern
      const single = rawLines[0];
      const match = single.match(/^(.+),\s*([A-Z]{2}\s+\d{5}(?:-\d{4})?.*)$/i);
      if (match) {
        addrLine1 = match[1].trim();
        addrLine2 = match[2].trim();
      } else {
        addrLine1 = single;
      }
    }

    return { name, addrLine1, addrLine2 };
  };

  const handlePrint = () => {
    const recipients = getRecipients();
    if (!recipients.length) {
      toast({ variant: "destructive", title: "No recipients", description: "Select an association and owners to print ballot envelopes." });
      return;
    }

    const size = ENVELOPE_SIZES[envelopeSize];
    const assocAddr = getAssocAddress();

    const printWindow = window.open("", "_blank");
    if (!printWindow) return;

    printWindow.document.write(`<!DOCTYPE html><html><head><title>Ballot Envelopes</title>
      <style>
        @page { size: ${size.width} ${size.height}; margin: 0; }
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body { font-family: Arial, sans-serif; }
        .envelope {
          width: ${size.width}; height: ${size.height};
          position: relative; page-break-after: always;
          padding: 0;
        }
        .envelope:last-child { page-break-after: auto; }

        /* Return address (top-left) — owner as designated voter */
        .return-address {
          position: absolute; top: 0.35in; left: 0.45in;
          font-size: 10px; line-height: 1.55;
        }
        .return-address .voter-label {
          font-style: italic; font-size: 9px; color: #555;
          margin-bottom: 1px;
        }
        .return-address .voter-name {
          font-weight: 600;
        }
        .return-address .addr-line {
          color: #333;
        }
        .return-address .sig-block {
          margin-top: 8px; font-size: 9px; color: #555;
        }
        .return-address .sig-line {
          display: inline-block;
          width: 160px;
          border-bottom: 1px solid #333;
          margin-left: 4px;
          vertical-align: bottom;
        }

        /* Recipient (center) — association */
        .recipient {
          position: absolute; top: 50%; left: 55%;
          transform: translate(-40%, -40%);
          font-size: 13px; line-height: 1.6; text-align: center;
        }
        .recipient .name { font-weight: 700; text-transform: uppercase; font-size: 12px; }
        .recipient .addr { color: #222; }

        /* Ballot label */
        .ballot-label {
          position: absolute; top: 0.3in; right: 0.5in;
          font-size: 9px; font-weight: 700; text-transform: uppercase;
          letter-spacing: 1.5px; color: #888;
          border: 1.5px solid #aaa; padding: 3px 10px; border-radius: 3px;
        }
      </style>
    </head><body>`);

    recipients.forEach((owner) => {
      const ret = getOwnerReturnBlock(owner);
      printWindow.document.write(`
        <div class="envelope">
          <div class="ballot-label">Official Ballot</div>
          <div class="return-address">
            <div class="voter-label">Designated Voter</div>
            <div class="voter-name">${ret.name}</div>
            ${ret.addrLine1 ? `<div class="addr-line">${ret.addrLine1}</div>` : ""}
            ${ret.addrLine2 ? `<div class="addr-line">${ret.addrLine2}</div>` : ""}
            <div class="sig-block">Signature: <span class="sig-line"></span></div>
          </div>
          <div class="recipient">
            <div class="name">${assocAddr.name}</div>
            ${assocAddr.line1 ? `<div class="addr">${assocAddr.line1}</div>` : ""}
            ${assocAddr.line2 ? `<div class="addr">${assocAddr.line2}</div>` : ""}
          </div>
        </div>
      `);
    });

    printWindow.document.write("</body></html>");
    printWindow.document.close();
    printWindow.focus();
    setTimeout(() => printWindow.print(), 500);
  };

  // Preview data
  const previewRecipient = getRecipients()[0];
  const previewReturn = previewRecipient ? getOwnerReturnBlock(previewRecipient) : null;
  const assocAddr = getAssocAddress();

  return (
    <div className="flex flex-col gap-6 p-6 max-w-5xl">
      {/* Header */}
      <div className="flex items-center gap-3">
        <div className="h-10 w-10 rounded-lg bg-primary/10 flex items-center justify-center">
          <Mail className="h-5 w-5 text-primary" />
        </div>
        <div>
          <h2 className="text-lg font-semibold text-foreground">Ballot Envelopes</h2>
          <p className="text-sm text-muted-foreground">
            Print envelopes addressed to the association with owner return addresses
          </p>
        </div>
      </div>

      <Separator />

      {/* Association Selector */}
      <div className="space-y-1.5">
        <Label className="text-xs font-medium">Association (Recipient)</Label>
        <Select value={selectedAssoc} onValueChange={setSelectedAssoc}>
          <SelectTrigger className="w-full max-w-md text-sm">
            <SelectValue placeholder="Select association..." />
          </SelectTrigger>
          <SelectContent>
            {associations.map((a) => (
              <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Settings & Preview */}
        <Card>
          <CardHeader className="pb-4">
            <CardTitle className="text-sm font-semibold flex items-center gap-2">
              <Settings className="h-4 w-4" /> Envelope Settings
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-1.5">
              <Label className="text-xs">Envelope Size</Label>
              <Select value={envelopeSize} onValueChange={setEnvelopeSize}>
                <SelectTrigger className="text-sm">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {Object.entries(ENVELOPE_SIZES).map(([k, v]) => (
                    <SelectItem key={k} value={k}>{v.label}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <Separator />

            {/* Preview */}
            <div className="space-y-1.5">
              <Label className="text-xs text-muted-foreground">Preview</Label>
              <div
                className="border border-dashed border-border rounded-lg bg-muted/20 relative overflow-hidden"
                style={{ aspectRatio: "9.5 / 4.125" }}
              >
                {/* Ballot label */}
                <div className="absolute top-2 right-3 text-[7px] font-bold tracking-widest text-muted-foreground/60 uppercase border border-muted-foreground/30 px-1.5 py-0.5 rounded-sm">
                  Official Ballot
                </div>

                {/* Return address (owner) */}
                <div className="absolute top-2.5 left-3 text-[8px] leading-tight text-muted-foreground">
                  <div className="italic text-[7px] text-muted-foreground/70">Designated Voter</div>
                  <div className="font-semibold">
                    {previewReturn ? previewReturn.name : "Owner Name"}
                  </div>
                  <div>{previewReturn ? previewReturn.addrLine1 : "123 Main Street"}</div>
                  {(previewReturn?.addrLine2 || !previewReturn) && (
                    <div>{previewReturn ? previewReturn.addrLine2 : "City, State ZIP"}</div>
                  )}
                  <div className="mt-1 text-[7px] text-muted-foreground/70">
                    Signature: <span className="inline-block w-16 border-b border-muted-foreground/40" />
                  </div>
                </div>

                {/* Recipient (association) */}
                <div className="absolute bottom-3 left-1/2 -translate-x-1/4 text-[9px] text-muted-foreground text-center">
                  <div className="font-bold uppercase text-[8px]">
                    {assocAddr.name || "Association Name"}
                  </div>
                  <div>{assocAddr.line1 || "Association Address"}</div>
                  {(assocAddr.line2) && <div>{assocAddr.line2}</div>}
                </div>
              </div>
            </div>
          </CardContent>
        </Card>

        {/* Owners (Voters) */}
        <Card>
          <CardHeader className="pb-4">
            <CardTitle className="text-sm font-semibold flex items-center gap-2">
              <Users className="h-4 w-4" /> Voters
              {owners.length > 0 && (
                <Badge variant="secondary" className="ml-auto text-[10px]">
                  {printMode === "selected" ? `${selectedOwnerIds.size} / ${owners.length}` : `${owners.length}`} owner(s)
                </Badge>
              )}
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <RadioGroup value={printMode} onValueChange={setPrintMode} className="space-y-3">
              <div className="flex items-start gap-2">
                <RadioGroupItem value="all-owners" id="ballot-all" className="mt-0.5" />
                <div>
                  <Label htmlFor="ballot-all" className="text-xs font-medium">All Owners</Label>
                  <p className="text-[11px] text-muted-foreground">Print a ballot envelope for every active owner</p>
                </div>
              </div>
              <div className="flex items-start gap-2">
                <RadioGroupItem value="selected" id="ballot-selected" className="mt-0.5" />
                <div>
                  <Label htmlFor="ballot-selected" className="text-xs font-medium">Selected Owners</Label>
                  <p className="text-[11px] text-muted-foreground">Choose specific owners below</p>
                </div>
              </div>
            </RadioGroup>

            {printMode === "selected" && (
              <>
                <Separator />
                <div className="flex items-center gap-2">
                  <Button variant="ghost" size="sm" className="text-[11px] h-6 px-2" onClick={selectAll}>Select All</Button>
                  <Button variant="ghost" size="sm" className="text-[11px] h-6 px-2" onClick={deselectAll}>Deselect All</Button>
                </div>
                {loadingOwners ? (
                  <div className="flex items-center gap-2 text-sm text-muted-foreground py-4">
                    <Loader2 className="h-4 w-4 animate-spin" /> Loading owners...
                  </div>
                ) : owners.length === 0 ? (
                  <p className="text-xs text-muted-foreground py-2">No owners found. Select an association first.</p>
                ) : (
                  <ScrollArea className="h-[240px]">
                    <div className="space-y-1 pr-3">
                      {owners.map((owner) => {
                        const ret = getOwnerReturnBlock(owner);
                        return (
                          <label
                            key={owner.id}
                            className={`flex items-start gap-2 p-2 rounded-md cursor-pointer hover:bg-muted/50 transition-colors ${
                              selectedOwnerIds.has(owner.id) ? "bg-primary/5 border border-primary/20" : "border border-transparent"
                            }`}
                          >
                            <Checkbox
                              checked={selectedOwnerIds.has(owner.id)}
                              onCheckedChange={() => toggleOwner(owner.id)}
                              className="mt-0.5"
                            />
                            <div className="min-w-0">
                              <div className="text-xs font-medium truncate">{ret.name}</div>
                              <div className="text-[10px] text-muted-foreground truncate">
                                {ret.addrLine1}{ret.addrLine2 ? `, ${ret.addrLine2}` : ""}
                              </div>
                            </div>
                          </label>
                        );
                      })}
                    </div>
                  </ScrollArea>
                )}
              </>
            )}

            {printMode === "all-owners" && !loadingOwners && owners.length > 0 && (
              <>
                <Separator />
                <p className="text-[11px] text-muted-foreground">
                  Will print {owners.length} ballot envelope(s) for all active owners.
                </p>
              </>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Print Button */}
      <div className="flex items-center gap-2 pt-2">
        <Button size="sm" className="gap-1.5 text-xs" onClick={handlePrint}>
          <Printer className="h-3.5 w-3.5" /> Print Ballot Envelopes ({getRecipients().length})
        </Button>
      </div>
    </div>
  );
}
