import React, { useState, useEffect, useRef } from 'react';
import { getAddressFormLines } from '@/lib/formatMailingAddress';
import { useSearchParams } from 'react-router-dom';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import { Separator } from '@/components/ui/separator';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { useToast } from '@/hooks/use-toast';
import { FileDown, Loader2, Scale, Settings, Plus, Trash2, FolderDown } from 'lucide-react';
import { jsPDF } from 'jspdf';
import { supabase } from '@/integrations/supabase/client';
import { Combobox } from '@/components/Combobox';
import { getHighQualityPdfSettings, applyHighQualityImageToPdf, loadImageHighQuality } from '@/lib/pdfQualityUtils';
import { drawBlock } from '@/lib/pdfGenerationUtils';
import { buildLedgerAccountBreakdown } from '@/lib/unitLedgerAccountBreakdown';
import { parseLocalDate, todayLocal } from '@/lib/dateUtils';
import { loadNotoSymbolsFont, registerNotoSymbolsFont } from '@/lib/fontManager';
import { SaveToDocumentsDialog } from '@/components/SaveToDocumentsDialog';
import { buildSecureStorageKey } from '@/lib/secureStorageNaming';
import PdfStylingControls from '@/components/forms/PdfStylingControls';

export default function NoticeOfIntentToLienForm() {
  const { toast } = useToast();
  const [searchParams] = useSearchParams();
  const prefillApplied = useRef(false);
  const [associations, setAssociations] = useState([]);
  const [owners, setOwners] = useState([]);
  const [loading, setLoading] = useState(false);
  const [selectedAssociationId, setSelectedAssociationId] = useState('');
  const [selectedOwnerId, setSelectedOwnerId] = useState('');
  const [showSaveDocsDialog, setShowSaveDocsDialog] = useState(false);
  const [showSaveResidentDialog, setShowSaveResidentDialog] = useState(false);

  // Queue
  const [batchQueue, setBatchQueue] = useState([]);

  // PDF Settings
  const [pdfConfig, setPdfConfig] = useState({
    font: 'Helvetica',
    fontSize: '9',
    textAlign: 'left'
  });

  // Form State
  const [formData, setFormData] = useState({
    letterDate: todayLocal(),
    dueDate: '',
    certifiedMailNumber: '',
    
    ownerName: '',
    ownerAddressLine1: '',
    ownerAddressLine2: '',
    ownerAddressLine3: '', 
    ownerAddressLine4: '', 
    
    propertyAddress: '',
    accountNo: '',
    
    assessments: '0.00',
    interest: '0.00',
    lateFees: '0.00',
    adminFees: '0.00',
    lessPayments: '0.00', 
    
    financialDescriptions: {
        assessments: 'Assessments -',
        interest: 'Interest -',
        lateFees: 'Late Fees -',
        adminFees: 'Admin Fees -',
        lessPayments: 'Less Payments'
    },

    interestRate: '18.00',
    
    associationName: '',
    paymentAddressLine1: 'P.O. Box 560099',
    paymentAddressLine2: 'Rockledge, Florida 32956',
    
    noticeLogo: '', 
    footerLogo: '',
    
    managementCompany: 'Avria Community Management, LLC',
    managementEmail: '',
    managementPhone: '(321) 405-2449',
    managementWebsite: ''
  });

  // Calculate Due Date (45 days from Letter Date)
  useEffect(() => {
    if (formData.letterDate) {
      const date = parseLocalDate(formData.letterDate);
      date.setDate(date.getDate() + 45);
      const y = date.getFullYear();
      const m = String(date.getMonth() + 1).padStart(2, '0');
      const d = String(date.getDate()).padStart(2, '0');
      setFormData(prev => ({ ...prev, dueDate: `${y}-${m}-${d}` }));
    }
  }, [formData.letterDate]);

  useEffect(() => {
    fetchAssociations();
  }, []);

  // Auto-fill from Outstanding Balances URL params
  useEffect(() => {
    if (prefillApplied.current || associations.length === 0) return;
    const associationId = searchParams.get('associationId');
    const ownerId = searchParams.get('ownerId');
    if (!associationId) return;

    prefillApplied.current = true;

    const assoc = associations.find(c => c.id === associationId);
    if (assoc) {
      setSelectedAssociationId(associationId);
      setFormData(prev => ({
        ...prev,
        associationName: assoc.name,
        managementEmail: assoc.email || prev.managementEmail,
        managementWebsite: assoc.website || prev.managementWebsite,
        managementPhone: assoc.phone || prev.managementPhone,
        noticeLogo: assoc.logo_url || ''
      }));
    }

    const doOwnerPrefill = async () => {
      const { data: ownerData } = await supabase
        .from('owners')
        .select('*, units(unit_number, account_number)')
        .eq('association_id', associationId)
        .order('last_name');
      
      if (ownerData) setOwners(ownerData);

      const owner = ownerId && ownerData ? ownerData.find(o => o.id === ownerId) : null;

      const ownerName = searchParams.get('ownerName') || '';
      const address = searchParams.get('address') || '';
      const assessments = searchParams.get('assessments') || '0.00';
      const lateFees = searchParams.get('lateFees') || '0.00';
      const interest = searchParams.get('interest') || '0.00';
      const adminFees = searchParams.get('adminFees') || '0.00';
      const legalFees = searchParams.get('legalFees') || '0.00';
      const payments = searchParams.get('payments') || '0.00';

      if (owner) {
        setSelectedOwnerId(owner.id);
        const addrLines = getAddressFormLines(owner, ownerName || undefined);

        setFormData(prev => ({
          ...prev,
          ownerName: ownerName || `${owner.first_name} ${owner.last_name}`.trim(),
          ownerAddressLine1: addrLines.line1,
          ownerAddressLine2: addrLines.line2,
          ownerAddressLine3: addrLines.line3,
          ownerAddressLine4: addrLines.line4,
          propertyAddress: owner.property_address || address,
          accountNo: owner.units?.account_number || owner.account_number || '',
          assessments,
          interest,
          lateFees,
          adminFees,
          lessPayments: payments,
        }));
      } else if (ownerName) {
        setFormData(prev => ({
          ...prev,
          ownerName,
          ownerAddressLine1: ownerName,
          propertyAddress: address,
          assessments,
          interest,
          lateFees,
          adminFees,
          lessPayments: payments,
        }));
      }
    };

    doOwnerPrefill();
  }, [associations, searchParams]);

  const fetchAssociations = async () => {
    const { data, error } = await supabase.from('associations').select('id, name, address, email, website, phone, logo_url').neq('status', 'archived');
    if (!error) setAssociations(data || []);
  };

  const fetchOwners = async (associationId) => {
    const { data, error } = await supabase
      .from('owners')
      .select('*, units(unit_number, account_number)')
      .eq('association_id', associationId)
      .order('last_name');
    
    if (!error) setOwners(data || []);
    else setOwners([]);
  };

  const handleAssociationChange = (associationId) => {
    setSelectedAssociationId(associationId);
    fetchOwners(associationId);
    setBatchQueue([]);
    
    const assoc = associations.find(c => c.id === associationId);
    if (assoc) {
      setFormData(prev => ({
        ...prev,
        associationName: assoc.name,
        managementEmail: assoc.email || prev.managementEmail,
        managementWebsite: assoc.website || prev.managementWebsite,
        managementPhone: assoc.phone || prev.managementPhone,
        noticeLogo: assoc.logo_url || ''
      }));
    }
  };

  const handleOwnerChange = async (ownerId) => {
    setSelectedOwnerId(ownerId);
    const owner = owners.find(o => o.id === ownerId);
    
    if (owner) {
      const ownerName = `${owner.first_name} ${owner.last_name}`.trim();
      const addrLines = getAddressFormLines(owner, ownerName);

      // Fetch ledger entries for this owner (and co-owners on same unit)
      const coOwners = owner.unit_id
        ? owners.filter(o => o.unit_id === owner.unit_id)
        : [owner];
      const ownerIds = coOwners.map(o => o.id);

      const { data: ledgerEntries } = await supabase
        .from('owner_ledger_entries')
        .select('id, transaction_type, debit, credit, date, created_at')
        .in('owner_id', ownerIds);

      let assessments = '0.00';
      let interest = '0.00';
      let lateFees = '0.00';
      let adminFees = '0.00';
      let lessPayments = '0.00';

      if (ledgerEntries && ledgerEntries.length > 0) {
        const { rows, totalPayments } = buildLedgerAccountBreakdown(ledgerEntries);

        for (const row of rows) {
          const val = Math.max(0, row.openBalance).toFixed(2);
          switch (row.type) {
            case 'assessment':
            case 'special_assessment':
              assessments = (parseFloat(assessments) + row.openBalance).toFixed(2);
              break;
            case 'interest':
              interest = val;
              break;
            case 'late_fee':
              lateFees = val;
              break;
            case 'admin_fee':
              adminFees = (parseFloat(adminFees) + row.openBalance).toFixed(2);
              break;
            case 'legal_fee':
              adminFees = (parseFloat(adminFees) + row.openBalance).toFixed(2);
              break;
            default:
              // Add other types into admin fees bucket
              if (row.openBalance > 0) {
                adminFees = (parseFloat(adminFees) + row.openBalance).toFixed(2);
              }
              break;
          }
        }

        // totalPayments is already applied in openBalance, so lessPayments stays 0
        lessPayments = '0.00';
      } else {
        assessments = owner.balance ? owner.balance.toString() : '0.00';
      }

      setFormData(prev => ({
        ...prev,
        ownerName,
        ownerAddressLine1: addrLines.line1,
        ownerAddressLine2: addrLines.line2,
        ownerAddressLine3: addrLines.line3,
        ownerAddressLine4: addrLines.line4,
        propertyAddress: owner.property_address || '',
        accountNo: owner.units?.account_number || owner.account_number || '',
        assessments,
        interest,
        lateFees,
        adminFees,
        lessPayments,
      }));
    }
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleDescriptionChange = (key, value) => {
    setFormData(prev => ({
        ...prev,
        financialDescriptions: {
            ...prev.financialDescriptions,
            [key]: value
        }
    }));
  };

  const getTotal = (data = formData) => {
    const a = parseFloat(data.assessments.toString().replace(/,/g, '')) || 0;
    const i = parseFloat(data.interest.toString().replace(/,/g, '')) || 0;
    const l = parseFloat(data.lateFees.toString().replace(/,/g, '')) || 0;
    const ad = parseFloat(data.adminFees.toString().replace(/,/g, '')) || 0;
    const p = parseFloat(data.lessPayments.toString().replace(/,/g, '')) || 0;
    return (a + i + l + ad - p).toFixed(2);
  };

  const addToQueue = () => {
      if(!formData.ownerName) {
          toast({ variant: "destructive", title: "Error", description: "Owner name is required."});
          return;
      }
      const item = { ...formData, id: Date.now() };
      setBatchQueue(prev => [...prev, item]);
      toast({ title: "Added to Queue", description: `${formData.ownerName} added.`});
  };

  const removeFromQueue = (id) => {
      setBatchQueue(prev => prev.filter(i => i.id !== id));
  };

  const formatCurrency = (val) => {
    const num = parseFloat(val) || 0;
    return num.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  };

  const formatDate = (dateString) => {
    if (!dateString) return '';
    const date = parseLocalDate(dateString);
    return date.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
  };

  const generatePDF = async (action = 'download') => {
    setLoading(true);
    let itemsToPrint = batchQueue.length > 0 ? batchQueue : [formData];
    
    try {
      await loadNotoSymbolsFont();
      const settings = getHighQualityPdfSettings('portrait', 'pt', 'letter');
      const doc = new jsPDF(settings);
      registerNotoSymbolsFont(doc);

      const pageWidth = doc.internal.pageSize.getWidth();
      const pageHeight = doc.internal.pageSize.getHeight();
      const margin = 54; 
      const baseFontSize = parseInt(pdfConfig.fontSize) || 10;
      const baseFont = 'Helvetica';

      let headerLogoData = null;
      if (itemsToPrint[0].noticeLogo) {
          headerLogoData = await loadImageHighQuality(itemsToPrint[0].noticeLogo);
      }
      
      const footerUrl = itemsToPrint[0].footerLogo;
      let footerLogoData = footerUrl ? await loadImageHighQuality(footerUrl) : null;

      for(let i=0; i<itemsToPrint.length; i++) {
        if(i > 0) doc.addPage();
        const data = itemsToPrint[i];
        
        const alignRight = (text, y, font = baseFont, style = "normal", size = baseFontSize) => {
            doc.setFont(font, style);
            doc.setFontSize(size);
            const w = doc.getTextWidth(text);
            doc.text(text, pageWidth - margin - w, y);
        };

        const centerText = (text, y, font = baseFont, style = "normal", size = baseFontSize) => {
            doc.setFont(font, style);
            doc.setFontSize(size);
            const w = doc.getTextWidth(text);
            doc.text(text, (pageWidth - w) / 2, y);
        };

        const textAlign = pdfConfig.textAlign || 'left';
        const paragraphGap = baseFontSize * 0.8;

        const justifyText = async (text, y, maxWidth) => {
             const block = {
                type: 'paragraph',
                content: text,
                styles: {
                    fontSize: baseFontSize,
                    fontFamily: baseFont,
                    textAlign: textAlign,
                    marginBottom: 0
                }
             };
             const endY = await drawBlock(doc, block, y, pageWidth, { left: margin, right: margin, top: margin, bottom: 50 });
             return endY + paragraphGap;
        };

        const drawFitText = (text, x, y, maxW, align = "left", startSize = 9, minSize = 6) => {
          doc.setFont("Helvetica", "normal");
          let size = startSize;
          doc.setFontSize(size);
          while (doc.getTextWidth(text) > maxW && size > minSize) {
            size -= 0.5;
            doc.setFontSize(size);
          }
          doc.text(text, x, y, { align });
          doc.setFontSize(startSize);
        };

        let currentY = margin;

        // --- 1. HEADER ---
        const returnAddressX = 38; 
        const returnAddressY = 60; 
        
        doc.setFont(baseFont, "normal");
        doc.setFontSize(9);
        
        let headerY = returnAddressY;
        doc.text(data.associationName, returnAddressX, headerY); headerY += 11;
        doc.text("c/o " + data.managementCompany, returnAddressX, headerY); headerY += 11;
        doc.text(data.paymentAddressLine1, returnAddressX, headerY); headerY += 11;
        doc.text(data.paymentAddressLine2, returnAddressX, headerY); headerY += 11;

        if (headerLogoData) {
            const maxW = 180;
            const maxH = 70;
            let finalW = maxW;
            let finalH = finalW * (headerLogoData.height / headerLogoData.width);
            if (finalH > maxH) { finalH = maxH; finalW = finalH * (headerLogoData.width / headerLogoData.height); }
            await applyHighQualityImageToPdf(doc, headerLogoData, pageWidth - margin - finalW, margin - 10, finalW, finalH);
            const dateY = margin - 10 + finalH + 15;
            doc.setFont(baseFont, "normal");
            doc.setFontSize(10);
            const dateText = formatDate(data.letterDate);
            const dateWidth = doc.getTextWidth(dateText);
            doc.text(dateText, pageWidth - margin - dateWidth, dateY);
        } else {
            doc.setFont(baseFont, "normal");
            doc.setFontSize(10);
            alignRight(formatDate(data.letterDate), margin);
        }

        currentY = Math.max(headerY + 20, 150); 
        
        // --- 2. RECIPIENT ---
        const recipientX = 60;
        let recipientY = 175;
        
        const addrBlockLines = [data.ownerAddressLine1, data.ownerAddressLine2, data.ownerAddressLine3, data.ownerAddressLine4].filter(l => l && l.trim().length > 0);

        if (addrBlockLines.length > 0) {
             doc.setFont(baseFont, "normal");
             doc.setFontSize(baseFontSize);
             addrBlockLines.forEach(line => { doc.text(String(line), recipientX, recipientY); recipientY += 12; });
        } else {
             doc.text((data.ownerName || '').trim(), recipientX, recipientY); recipientY += 12;
        }
        
        currentY = Math.max(currentY, recipientY + 20);

        // --- 3. CERTIFIED MAIL ---
        doc.setFont(baseFont, "bolditalic");
        doc.setFontSize(10);
        alignRight(`U.S. Certified Mail # ${data.certifiedMailNumber || ''}`, currentY, baseFont, "bolditalic", 10);
        currentY += 40;

        // --- 4. TITLE ---
        doc.setFont(baseFont, "bold");
        doc.setFontSize(11); 
        const title = "STATUTORY NOTICE OF INTENT TO RECORD A CLAIM OF LIEN";
        centerText(title, currentY, baseFont, "bold", 11);
        const titleW = doc.getTextWidth(title);
        doc.setLineWidth(1);
        doc.line((pageWidth - titleW)/2, currentY + 2, (pageWidth + titleW)/2, currentY + 2);
        currentY += 40;

        // --- 5. SALUTATION ---
        doc.setFont(baseFont, "normal");
        doc.setFontSize(baseFontSize);
        doc.text(`Dear ${data.ownerName || 'Homeowner'}`, margin, currentY);
        currentY += 20;

        // --- 6. BODY ---
        const maxTextW = pageWidth - (margin * 2);
        
        const p1 = `According to our records, you have failed to pay and have not responded to previous requests for payment of past-due fees and costs to ${data.associationName} (hereinafter "Association") for your property referenced above.`;
        currentY = await justifyText(p1, currentY, maxTextW);

        doc.setFont(baseFont, "bolditalic");
        const p2 = "If you are unable to pay in full, please submit a proposed payment plan in writing to us. Management will submit your payment plan to the Association for review.";
        currentY = await justifyText(p2, currentY, maxTextW);

        doc.setFont(baseFont, "normal");
        const p3 = `The following amounts are currently due on your account and must be paid within forty-five (45) days after your receipt of this letter. This letter shall serve as the association's notice of intent to record a Claim of Lien against your property no sooner than forty-five (45) days after your receipt of this letter, unless you pay in full the amounts set forth below:`;
        currentY = await justifyText(p3, currentY, maxTextW);
        currentY += 10;

        // --- 7. FINANCIAL TABLE ---
        const tableX = margin + 20;
        const dollarSignX = pageWidth - margin - 120;
        const amountRightEdge = pageWidth - margin - 60;

        const drawRow = (label, amount, isTotal = false) => {
            if (isTotal) doc.setFont(baseFont, "bolditalic");
            else doc.setFont(baseFont, "normal");
            doc.setFontSize(baseFontSize);
            doc.text(label, tableX, currentY);
            doc.text("$", dollarSignX, currentY);
            doc.text(formatCurrency(amount), amountRightEdge, currentY, { align: 'right' });
            currentY += 15;
        };

        const descs = data.financialDescriptions || { assessments: 'Assessments -', interest: 'Interest -', lateFees: 'Late Fees -', adminFees: 'Admin Fees -', lessPayments: 'Less Payments' };

        drawRow(descs.assessments, data.assessments);
        drawRow(descs.interest, data.interest);
        drawRow(descs.lateFees, data.lateFees);
        drawRow(descs.adminFees, data.adminFees);
        doc.setFont(baseFont, "bolditalic");
        drawRow(descs.lessPayments, data.lessPayments);
        
        doc.setLineWidth(1);
        doc.line(tableX, currentY - 10, amountRightEdge + 10, currentY - 10);
        currentY += 5;
        drawRow("Total Outstanding", getTotal(data), true);
        currentY += 20;

        // --- 8. ADDITIONAL NOTES ---
        doc.setFont(baseFont, "normal");
        doc.setFontSize(9); 
        doc.text(`* Interest accrues at the rate of eighteen percent (${data.interestRate}%) per annum.`, margin, currentY);
        currentY += 15;

        doc.setFontSize(baseFontSize);
        const totalStr = "$" + getTotal(data);
        const dueDateStr = formatDate(data.dueDate);
        
        const p4 = `The amount of ${totalStr}, which represents past due assessment balance and additional costs, must be paid by ${dueDateStr}, or the Association will be forced to transfer your file to the Association counsel for legal proceedings. Additionally, you are responsible for any assessments and past-due fees that may accrue before ${dueDateStr}.`;
        currentY = await justifyText(p4, currentY, maxTextW);

        doc.setFont(baseFont, "bolditalic");
        const p5 = `Payment should be in the form of a cashier's check or money order payable to ${data.associationName}, and mailed to c/o ${data.managementCompany}, ${data.paymentAddressLine1}, ${data.paymentAddressLine2}.`;
        currentY = await justifyText(p5, currentY, maxTextW);

        const p6 = "PLEASE NOTE: Payment tendered for less than the full amount due and owing will NOT satisfy the debt and result in placing your account in collections.";
        currentY = await justifyText(p6, currentY, maxTextW);
        currentY += 10;

        const p7 = "Pursuant to the Fair Debt Collection Practices Act, 15 U.S.C. Section 1601 as amended, this is your notice that:";
        currentY = await justifyText(p7, currentY, maxTextW);

        const listItems = [
            "1. You have the right to dispute the debt within 30 days of receipt of this notice",
            "2. If you dispute the debt in writing, we must cease collection efforts until we provide verification",
            "3. We will not contact you if you request in writing that we cease communications",
            "4. Any communication from us is an attempt to collect a debt",
            "5. Any information obtained will be used for collection purposes",
            "6. If you are represented by an attorney, contact should be made to your attorney"
        ];

        const listIndentation = 20;
        const listMaxWidth = maxTextW - listIndentation;
        const listX = margin + listIndentation;

        listItems.forEach(item => {
             const lines = doc.splitTextToSize(item, listMaxWidth);
             const lineHeight = baseFontSize * 1.2;
             const bottomLimit = pageHeight - 120;
             if (currentY + (lines.length * lineHeight) > bottomLimit) {
                 doc.addPage();
                 currentY = margin + 30;
             }
             doc.text(lines, listX, currentY);
             currentY += (lines.length * lineHeight) + 4; 
        });
        currentY += 10;

        const p8 = "IF YOU REQUEST, IN WRITING, PROOF OF THE DEBT OR THE NAME AND ADDRESS OF THE ORIGINAL CREDITOR WITHIN THE 30-DAY PERIOD WHICH BEGINS WITH YOUR RECEIPT OF THIS NOTICE, THE LAW REQUIRES US TO SUSPEND OUR EFFORTS TO COLLECT THE DEBT UNTIL WE MAIL THE REQUESTED INFORMATION TO YOU. THEREAFTER, THE LEGAL PROCEEDINGS OF THE CLAIM WILL CONTINUE.";
        currentY = await justifyText(p8, currentY, maxTextW);

        const p9 = `You may submit your request for a payment plan, in writing, by fax to (321) 405-2449 or email to ${data.managementEmail}.`;
        currentY = await justifyText(p9, currentY, maxTextW);
        currentY += 10;

        if (currentY + 50 > pageHeight - 120) {
             doc.addPage();
             currentY = margin + 30;
        }

        doc.text("Sincerely,", margin, currentY); currentY += 15;
        doc.text("Avria Community Management, LLC", margin, currentY); currentY += 15;
        doc.text(`Managing Agent for ${data.associationName}`, margin, currentY);

        // --- 9. FOOTER ---
        const footerBottomPad = 15;
        const footerRuleY = pageHeight - footerBottomPad - 15;
        const contactY = footerRuleY - 15;
        const logoMaxH = 34;
        const logoY2 = contactY - logoMaxH - 12;

        if (currentY > logoY2 - 20) { doc.addPage(); }

        const innerW = pageWidth - (margin * 2);
        const colW = innerW / 3;
        const leftX = margin;
        const centerX2 = margin + colW + colW / 2;
        const rightX = margin + (2 * colW) + colW;

        const phoneTxt = `(Phone) ${data.managementPhone || ""}`;
        const emailTxt = (data.managementEmail || "").trim();
        const webTxt = (data.managementWebsite || "").trim();

        if (footerLogoData) {
          const ratio = footerLogoData.width / footerLogoData.height;
          let h = logoMaxH;
          let w = h * ratio;
          const maxLogoW = innerW * 0.6;
          if (w > maxLogoW) { w = maxLogoW; h = w / ratio; }
          const logoX = (pageWidth - w) / 2;
          await applyHighQualityImageToPdf(doc, footerLogoData, logoX, logoY2, w, h);
        } else {
          doc.setFont("Helvetica", "bold");
          doc.setFontSize(18);
          doc.text("ACM", pageWidth / 2, logoY2 + 22, { align: "center" });
          doc.setFontSize(9);
        }

        doc.setFont("Helvetica", "normal");
        drawFitText(phoneTxt, leftX, contactY, colW - 5, "left", 9, 6);
        drawFitText(emailTxt, centerX2, contactY, colW - 5, "center", 9, 6);
        drawFitText(webTxt, rightX, contactY, colW - 5, "right", 9, 6);

        doc.setLineWidth(0.5);
        doc.line(margin, footerRuleY, pageWidth - margin, footerRuleY);

        doc.setFontSize(9);
        doc.text(String(i + 1), pageWidth - margin, pageHeight - 12, { align: "right" });

      }

      if (action === 'blob') {
          return doc.output('blob');
      } else {
          const fileName = itemsToPrint.length > 1 ? `Batch_IntentToLien_${new Date().toISOString().split('T')[0]}.pdf` : `Intent_to_Lien_${formData.ownerName.replace(/\s+/g, '_')}.pdf`;
          doc.save(fileName);
          toast({ title: "Success", description: `Intent to Lien PDF Generated (${itemsToPrint.length} letters).` });
      }

    } catch (err) {
      console.error(err);
      toast({ variant: "destructive", title: "Error", description: "Failed to generate PDF" });
      return null;
    } finally {
      setLoading(false);
    }
  };

  const handleSaveToDocuments = async (metadata) => {
    try {
        const blob = await generatePDF('blob');
        if (!blob) throw new Error("Failed to generate PDF blob.");

        const { data: userData } = await supabase.auth.getUser();
        if (!userData?.user) throw new Error("Not authenticated");

        // Display name kept human-readable; storage key is randomized so the
        // public URL doesn't leak the real document name.
        const displayFileName = `${metadata.name.replace(/[^a-zA-Z0-9._ -]+/g, '_').trim()}.pdf`;
        const filePath = buildSecureStorageKey('doc.pdf', userData.user.id);

        const { error: uploadError } = await supabase.storage
            .from('files')
            .upload(filePath, blob, { contentType: 'application/pdf' });
        if (uploadError) throw uploadError;

        const { data: { publicUrl } } = supabase.storage
            .from('files')
            .getPublicUrl(filePath);

        const { error: docError } = await supabase.from('documents').insert({
            title: metadata.name,
            file_url: publicUrl,
            file_name: displayFileName,
            file_size: blob.size,
            association_id: metadata.clientId,
            category: metadata.category || 'general',
            uploaded_by: userData.user.id,
        });

        if (docError) throw docError;

        toast({ title: 'Success', description: 'Document saved successfully.' });
        return { blob };
    } catch (err) {
        console.error(err);
        toast({ variant: 'destructive', title: 'Error saving document', description: err.message });
        throw err;
    }
  };

  return (
    <div className="max-w-5xl mx-auto">
      <Card>
        <CardHeader className="bg-muted/50 border-b">
          <div className="flex justify-between items-start">
              <CardTitle className="text-xl flex items-center gap-2">
                  <Scale className="w-5 h-5 text-destructive" />
                  Statutory Notice of Intent to Lien (45 Day)
              </CardTitle>
          </div>
        </CardHeader>
        <CardContent className="p-6 space-y-8">
          
          {/* Association & Date */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
            <div className="space-y-2">
              <Label>Select Association</Label>
              <Select onValueChange={handleAssociationChange} value={selectedAssociationId}>
                <SelectTrigger>
                  <SelectValue placeholder="Select Association" />
                </SelectTrigger>
                <SelectContent>
                  {associations.map((assoc) => (
                    <SelectItem key={assoc.id} value={assoc.id}>{assoc.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                    <Label>Letter Date</Label>
                    <Input type="date" name="letterDate" value={formData.letterDate} onChange={handleChange} />
                </div>
                <div className="space-y-2">
                    <Label>Due Date (Calculated)</Label>
                    <Input value={formData.dueDate} readOnly className="bg-muted" />
                    <p className="text-[10px] text-muted-foreground">Auto-set to +45 days</p>
                </div>
            </div>
          </div>

          <Separator />

          {/* Owner Selection */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
             <div className="space-y-4">
                 <div className="flex justify-between items-center">
                    <h3 className="font-semibold text-foreground">Recipient Information</h3>
                    <Button size="sm" variant="ghost" className="text-primary" onClick={addToQueue}>
                      <Plus className="w-4 h-4 mr-1" /> Add to Queue
                    </Button>
                 </div>
                 <div className="space-y-2">
                     <Label>Select Owner (Autofill)</Label>
                     <Combobox
                       options={owners.map(o => ({
                         value: o.id,
                         label: `${o.first_name} ${o.last_name} - ${o.property_address || ''}`
                       }))}
                       value={selectedOwnerId}
                       onChange={handleOwnerChange}
                       placeholder="Select Owner"
                       disabled={!selectedAssociationId}
                       className="w-full"
                     />
                 </div>

                 <div className="space-y-2">
                    <Label>Owner Name</Label>
                    <Input name="ownerName" value={formData.ownerName} onChange={handleChange} />
                 </div>
                 
                 <div className="bg-muted/50 p-3 rounded border">
                     <p className="text-xs font-semibold text-muted-foreground mb-2 uppercase">Mailing Address</p>
                     <div className="space-y-2">
                        <Input name="ownerAddressLine1" value={formData.ownerAddressLine1} onChange={handleChange} placeholder="Line 1" className="h-8 text-sm"/>
                        <Input name="ownerAddressLine2" value={formData.ownerAddressLine2} onChange={handleChange} placeholder="Line 2" className="h-8 text-sm"/>
                        <Input name="ownerAddressLine3" value={formData.ownerAddressLine3} onChange={handleChange} placeholder="Line 3" className="h-8 text-sm"/>
                        <Input name="ownerAddressLine4" value={formData.ownerAddressLine4} onChange={handleChange} placeholder="Line 4" className="h-8 text-sm"/>
                     </div>
                 </div>

                 <div className="space-y-2">
                    <Label>Property Address (Reference)</Label>
                    <Input name="propertyAddress" value={formData.propertyAddress} onChange={handleChange} />
                 </div>
                 <div className="space-y-2">
                    <Label>Certified Mail #</Label>
                    <Input name="certifiedMailNumber" value={formData.certifiedMailNumber} onChange={handleChange} placeholder="XXXX-XXXX-XXXX-XXXX" />
                 </div>
             </div>

             {/* Financials */}
             <div className="space-y-4">
                 <h3 className="font-semibold text-foreground">Financial Breakdown</h3>
                 <div className="bg-muted/50 p-4 rounded-lg border space-y-3">
                     {[
                       { key: 'assessments', field: 'assessments' },
                       { key: 'interest', field: 'interest' },
                       { key: 'lateFees', field: 'lateFees' },
                       { key: 'adminFees', field: 'adminFees' },
                     ].map(({ key, field }) => (
                       <div key={key} className="grid grid-cols-12 gap-2 items-center">
                         <div className="col-span-5">
                           {key === 'assessments' && <Label className="text-[10px] text-muted-foreground uppercase tracking-wider mb-1 block">Description</Label>}
                           <Input 
                             className="h-8 text-xs font-medium bg-background" 
                             value={formData.financialDescriptions[key]}
                             onChange={(e) => handleDescriptionChange(key, e.target.value)}
                             maxLength={40}
                           />
                         </div>
                         <div className="col-span-7">
                           {key === 'assessments' && <Label className="text-[10px] text-muted-foreground uppercase tracking-wider mb-1 block text-right">Amount</Label>}
                           <Input className="text-right h-8" name={field} value={formData[field]} onChange={handleChange} />
                         </div>
                       </div>
                     ))}

                     <div className="grid grid-cols-12 gap-2 items-center">
                        <div className="col-span-5">
                           <Input 
                             className="h-8 text-xs font-medium bg-background text-destructive" 
                             value={formData.financialDescriptions.lessPayments}
                             onChange={(e) => handleDescriptionChange('lessPayments', e.target.value)}
                             maxLength={40}
                           />
                        </div>
                        <div className="col-span-7">
                           <Input className="text-right h-8 text-destructive" name="lessPayments" value={formData.lessPayments} onChange={handleChange} />
                        </div>
                     </div>
                     
                     <div className="border-t pt-2 mt-2 flex justify-between items-center">
                        <span className="font-bold text-sm">Total Outstanding:</span>
                        <span className="font-bold text-lg">${getTotal()}</span>
                     </div>
                 </div>
                 <div className="space-y-2">
                    <Label>Interest Rate (% per annum)</Label>
                    <Input name="interestRate" value={formData.interestRate} onChange={handleChange} />
                 </div>
             </div>
          </div>

          {/* PDF Styling */}
          <PdfStylingControls pdfConfig={pdfConfig} onChange={setPdfConfig} />

          <Accordion type="single" collapsible className="w-full bg-muted/50 rounded-lg border">
            <AccordionItem value="branding" className="border-none">
              <AccordionTrigger className="px-4 py-3 text-muted-foreground font-medium hover:no-underline">
                <div className="flex items-center gap-2">
                  <Settings className="w-4 h-4" />
                  Branding & Config
                </div>
              </AccordionTrigger>
              <AccordionContent className="px-4 pb-4 pt-2 bg-background rounded-b-lg border-t">
                 <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div className="space-y-2"><Label>Header Logo URL</Label><Input name="noticeLogo" value={formData.noticeLogo} onChange={handleChange} /></div>
                    <div className="space-y-2"><Label>Footer Logo URL</Label><Input name="footerLogo" value={formData.footerLogo} onChange={handleChange} /></div>
                    <div className="space-y-2"><Label>Payment Addr Line 1</Label><Input name="paymentAddressLine1" value={formData.paymentAddressLine1} onChange={handleChange} /></div>
                    <div className="space-y-2"><Label>Payment Addr Line 2</Label><Input name="paymentAddressLine2" value={formData.paymentAddressLine2} onChange={handleChange} /></div>
                    <div className="space-y-2"><Label>Management Email</Label><Input name="managementEmail" value={formData.managementEmail} onChange={handleChange} /></div>
                    <div className="space-y-2"><Label>Management Website</Label><Input name="managementWebsite" value={formData.managementWebsite} onChange={handleChange} /></div>
                 </div>
              </AccordionContent>
            </AccordionItem>
          </Accordion>
          
           {/* Queue */}
           {batchQueue.length > 0 && (
              <div className="space-y-4 pt-4 border-t">
                  <h3 className="font-semibold text-foreground">Batch Generation Queue ({batchQueue.length})</h3>
                  <div className="border rounded-md max-h-60 overflow-y-auto">
                    <Table>
                        <TableHeader><TableRow>
                            <TableHead>Owner</TableHead><TableHead>Property</TableHead><TableHead>Total Due</TableHead><TableHead></TableHead>
                        </TableRow></TableHeader>
                        <TableBody>
                            {batchQueue.map(item => (
                                <TableRow key={item.id}>
                                    <TableCell>{item.ownerName}</TableCell>
                                    <TableCell>{item.propertyAddress}</TableCell>
                                    <TableCell>${getTotal(item)}</TableCell>
                                    <TableCell>
                                        <Button variant="ghost" size="sm" onClick={() => removeFromQueue(item.id)}>
                                            <Trash2 className="w-4 h-4 text-destructive" />
                                        </Button>
                                    </TableCell>
                                </TableRow>
                            ))}
                        </TableBody>
                    </Table>
                  </div>
              </div>
          )}

          <div className="flex justify-end pt-4 gap-4">
             <Button variant="outline" onClick={() => setShowSaveDocsDialog(true)} disabled={loading}>
                <FolderDown className="w-4 h-4 mr-2" /> Save to Docs
             </Button>
             {(() => {
               const sel = owners.find(o => o.id === selectedOwnerId);
               const unitNum = sel?.units?.unit_number;
               if (!unitNum || batchQueue.length > 0) return null;
               return (
                 <Button
                   variant="outline"
                   onClick={() => setShowSaveResidentDialog(true)}
                   disabled={loading}
                   title={`Save to Resident Files / ${unitNum}`}
                 >
                   <FolderDown className="w-4 h-4 mr-2" /> Save to Resident File
                 </Button>
               );
             })()}
             <Button 
              onClick={() => generatePDF('download')} 
              disabled={loading}
              variant="destructive"
              className="min-w-[200px]"
            >
              {loading ? <Loader2 className="w-4 h-4 animate-spin mr-2" /> : <FileDown className="w-4 h-4 mr-2" />}
              {batchQueue.length > 0 ? `Generate Batch PDF (${batchQueue.length})` : "Generate Intent to Lien"}
            </Button>
          </div>

        </CardContent>
      </Card>
      
      <SaveToDocumentsDialog
        open={showSaveDocsDialog}
        onOpenChange={setShowSaveDocsDialog}
        onSave={handleSaveToDocuments}
        defaultName={batchQueue.length > 0 ? `Batch Intent to Lien` : `Intent to Lien - ${formData.ownerName}`}
        defaultClientId={selectedAssociationId}
      />

      <SaveToDocumentsDialog
        open={showSaveResidentDialog}
        onOpenChange={setShowSaveResidentDialog}
        onSave={handleSaveToDocuments}
        defaultName={`Intent to Lien - ${formData.ownerName}`}
        defaultClientId={selectedAssociationId}
        residentFileMode
        unitId={(owners.find(o => o.id === selectedOwnerId)?.unit_id) || ""}
        unitNumber={(owners.find(o => o.id === selectedOwnerId)?.units?.unit_number) || ""}
      />
    </div>
  );
}
