
import React, { useState, useEffect, useMemo, useRef } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { combineOwnerNames } from '@/lib/ownerAddressUtils';
import { 
  Plus, Trash2, Save, Upload, Calculator, 
  Loader2, GripVertical, FileUp, RotateCcw,
  FileDown, History, Database
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { useToast } from '@/components/ui/use-toast';
import { cn } from '@/lib/utils';
import { Combobox } from '@/components/Combobox';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Badge } from "@/components/ui/badge";
import { DragDropContext, Droppable as OriginalDroppable, Draggable } from '@hello-pangea/dnd';

// Fix for React 18 strict mode — Droppable doesn't render on first mount
function Droppable({ children, ...props }) {
  const [enabled, setEnabled] = React.useState(false);
  React.useEffect(() => {
    const animation = requestAnimationFrame(() => setEnabled(true));
    return () => {
      cancelAnimationFrame(animation);
      setEnabled(false);
    };
  }, []);
  if (!enabled) return <tbody>{/* placeholder while droppable mounts */}</tbody>;
  return <OriginalDroppable {...props}>{children}</OriginalDroppable>;
}
import { HtmlPreviewModal } from './HtmlPreviewModal';
import { CreditLineDialog } from './CreditLineDialog';
import { BankFeeDialog } from '@/components/BankFeeDialog';
import { calculateLedger } from '@/lib/ledgerCalculationUtils';
import ChartOfAccountsDropdown from '@/components/ChartOfAccountsDropdown';
import { jsPDF } from 'jspdf';
import autoTable from 'jspdf-autotable';
import { Alert, AlertDescription } from '@/components/ui/alert';

const DEFAULT_ROW = {
  id: null,
  entry_type: 'debit',
  date: new Date().toISOString().split('T')[0],
  description: '',
  chart_of_account_id: '',
  bankFee: 0,
  assessment: 0,
  lateFee: 0,
  adminFee: 0,
  legalFee: 0,
  violation: 0,
  interest: 0,
  payment: 0,
  isAutoInterest: false,
};

export default function CustomLedgerForm() {
  const { toast } = useToast();
  const fileInputRef = useRef(null);
      
  // Metadata State
  const [ledgerName, setLedgerName] = useState('');
  const [selectedClient, setSelectedClient] = useState('');
  const [selectedProperty, setSelectedProperty] = useState('');
  const [clients, setClients] = useState([]);
  const [properties, setProperties] = useState([]);
  const [savedLedgers, setSavedLedgers] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [loadDialogOpen, setLoadDialogOpen] = useState(false);
  const [currentLedgerId, setCurrentLedgerId] = useState(null);

  // Dialog State
  const [creditDialogOpen, setCreditDialogOpen] = useState(false);
  const [bankFeeDialogOpen, setBankFeeDialogOpen] = useState(false);

  // Preview State
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewHtml, setPreviewHtml] = useState('');

  // Ledger State
  const [rows, setRows] = useState([{ ...DEFAULT_ROW, id: crypto.randomUUID() }]);
  const [interestRate, setInterestRate] = useState("0.015"); // 1.5% default (18% annual)

  // Fetch initial data - associations as clients
  useEffect(() => {
    const fetchData = async () => {
      const { data: assocData } = await supabase.from('associations').select('id, name').order('name');
      setClients(assocData || []);
      fetchSavedLedgers();
    };
    fetchData();
  }, []);

  // Fetch owners when association changes
  useEffect(() => {
    if (selectedClient) {
      const fetchProps = async () => {
        const { data } = await supabase
          .from('owners')
          .select('id, first_name, last_name, property_address, mailing_address, alternate_address_1, alternate_address_2, unit_id, units(unit_number, account_number)')
          .eq('association_id', selectedClient)
          .eq('status', 'active')
          .order('last_name');
        
        // Group by unit to combine co-owner names
        const ownersByUnit = {};
        for (const owner of (data || [])) {
          const key = owner.unit_id || owner.id;
          if (!ownersByUnit[key]) ownersByUnit[key] = [];
          ownersByUnit[key].push(owner);
        }
        
        setProperties(Object.values(ownersByUnit).map(group => {
          const primary = group[0];
          return {
            id: primary.id,
            owner_name: combineOwnerNames(group),
            property_address: primary.property_address || primary.units?.unit_number || '',
            account_number: primary.units?.account_number || '',
            mailing_address: primary.mailing_address || '',
            alternate_address_1: group.flatMap(o => [o.alternate_address_1]).filter(Boolean)[0] || '',
            alternate_address_2: group.flatMap(o => [o.alternate_address_2]).filter(Boolean)[0] || '',
          };
        }));
      };
      fetchProps();
    } else {
      setProperties([]);
    }
  }, [selectedClient]);

  const fetchSavedLedgers = async () => {
    const { data } = await supabase.from('custom_ledgers').select('id, name, created_at').order('created_at', { ascending: false });
    setSavedLedgers(data || []);
  };

  // --- Core Calculation Logic ---
  const calculatedData = useMemo(() => {
    const numericRate = parseFloat(interestRate);
    return calculateLedger(rows, isNaN(numericRate) ? 0 : numericRate);
  }, [rows, interestRate]);

  // Handle Drag & Drop
  const handleOnDragEnd = (result) => {
    if (!result.destination) return;
    const items = Array.from(rows);
    const [reorderedItem] = items.splice(result.source.index, 1);
    items.splice(result.destination.index, 0, reorderedItem);
    setRows(items);
  };

  const handleImportAutomations = () => {
     const simulatedEntries = [
         { ...DEFAULT_ROW, id: crypto.randomUUID(), entry_type: 'late_fee', description: '[AUTO] Late Fee applied', lateFee: 25.00 },
         { ...DEFAULT_ROW, id: crypto.randomUUID(), entry_type: 'interest', description: '[AUTO] Interest applied', interest: 12.50 },
     ];
     setRows([...rows, ...simulatedEntries]);
     toast({ title: 'Audit Trail Imported', description: 'Fetched automated ledger entries for this property.' });
  };

  // Handle CSV Upload
  const handleCsvUpload = (e) => {
    const file = e.target.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (event) => {
      try {
        const text = event.target.result;
        const lines = text.split(/\r?\n/);
        
        const newRows = [];
        const parseCSVLine = (str) => {
            const result = [];
            let current = '';
            let inQuote = false;
            for (let i = 0; i < str.length; i++) {
                const char = str[i];
                if (char === '"') {
                    if (inQuote && str[i + 1] === '"') { current += '"'; i++; } else { inQuote = !inQuote; }
                } else if (char === ',' && !inQuote) { result.push(current); current = ''; } else { current += char; }
            }
            result.push(current);
            return result;
        };
        
        lines.forEach((line, index) => {
          if (!line.trim()) return;
          if (line.includes('TOTALS') || line.startsWith(',,TOTALS')) return;
          const cols = parseCSVLine(line).map(c => c.trim());
          if (index === 0 && cols.join(',').toLowerCase().includes('date') && cols.join(',').toLowerCase().includes('description')) return;
          
          if (cols.length >= 10) { 
             const row = { ...DEFAULT_ROW, id: crypto.randomUUID() };
             const dateVal = new Date(cols[0]);
             if (!isNaN(dateVal.getTime())) row.date = dateVal.toISOString().split('T')[0];
             row.description = cols[1] ? cols[1].replace(/^"|"$/g, '') : '';
             
             const parseVal = (v) => { const num = parseFloat(v); return isNaN(num) ? 0 : num; };

             row.assessment = parseVal(cols[2]);
             row.lateFee = parseVal(cols[3]);
             row.adminFee = parseVal(cols[4]);
             row.legalFee = parseVal(cols[5]);
             row.violation = parseVal(cols[6]);
             row.interest = parseVal(cols[7]);
             row.bankFee = parseVal(cols[8]); 
             row.payment = Math.abs(parseVal(cols[9])); // Ensure payments are positive
             
             if (row.bankFee > 0) row.entry_type = 'bank_fee';
             if (row.description.toLowerCase().includes('credit') || row.payment > 0) row.entry_type = 'credit';
             
             newRows.push(row);
          }
        });

        if (newRows.length > 0) {
            setRows(prev => [...prev, ...newRows]);
            toast({ title: 'Success', description: `Imported ${newRows.length} rows.` });
        } else {
            toast({ variant: "destructive", title: 'Import Failed', description: 'Could not parse CSV data.' });
        }
      } catch (err) {
        toast({ variant: "destructive", title: 'Error', description: 'Failed to parse CSV file.' });
      }
      if (fileInputRef.current) fileInputRef.current.value = '';
    };
    reader.readAsText(file);
  };

  const formatCurrency = (val) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(val || 0);
  const formatBalance = (val) => {
    const amount = Number(val || 0);
    return amount < 0 ? `(${formatCurrency(Math.abs(amount))})` : formatCurrency(amount);
  };

  const handleDownloadPDF = () => {
    try {
      const doc = new jsPDF('landscape', 'pt', 'letter');
      const pageWidth = doc.internal.pageSize.getWidth();
      const margin = 40;
      
      // Data Gathering
      const clientName = clients.find(c => c.id === selectedClient)?.name || 'N/A';
      let prop = properties.find(p => p.id === selectedProperty) || {};
      
      const ownerName = prop.owner_name || 'N/A';
      const propertyAddress = prop.property_address || 'N/A';
      const accountNumber = prop.account_number || 'N/A';
      const mailingAddress = prop.mailing_address || '';
      const statementDate = new Date().toLocaleDateString('en-US');

      // --- 1. Header Section ---
      doc.setFont('helvetica', 'bold');
      doc.setFontSize(22);
      doc.setTextColor(0, 0, 0);
      doc.text("ACCOUNT STATEMENT", pageWidth - margin, margin + 15, { align: 'right' });
      
      doc.setFontSize(10);
      doc.setFont('helvetica', 'normal');
      doc.text(`Statement Date: ${statementDate}`, pageWidth - margin, margin + 30, { align: 'right' });
      doc.text(`Association: ${clientName}`, pageWidth - margin, margin + 45, { align: 'right' });

      // Owner & Property Info Block
      let currentY = margin + 15;
      
      doc.setFont('helvetica', 'bold');
      doc.setFontSize(10);
      doc.text("ACCOUNT HOLDER:", margin, currentY);
      currentY += 14;
      
      doc.setFont('helvetica', 'normal');
      doc.text(ownerName, margin, currentY);
      currentY += 14;
      
      if (mailingAddress) {
        mailingAddress.split('\n').filter(Boolean).forEach(line => {
          doc.text(line, margin, currentY);
          currentY += 14;
        });
      }
      
      currentY += 10;
      doc.setFont('helvetica', 'bold');
      doc.text("PROPERTY ADDRESS:", margin, currentY);
      currentY += 14;
      doc.setFont('helvetica', 'normal');
      doc.text(propertyAddress, margin, currentY);

      // --- 2. Summary Tables Section ---
      const summaryYStart = Math.max(currentY + 30, margin + 70);
      
      // Left: Amounts Due Breakdown
      autoTable(doc, {
        startY: summaryYStart,
        margin: { left: margin },
        tableWidth: 280,
        head: [['Amounts Due Breakdown', 'Amount']],
        body: [
          ['Assessments', formatCurrency(calculatedData.buckets.assessment)],
          ['Late Fees', formatCurrency(calculatedData.buckets.late)],
          ['Admin Fees', formatCurrency(calculatedData.buckets.admin)],
          ['Legal Fees', formatCurrency(calculatedData.buckets.legal)],
          ['Violations', formatCurrency(calculatedData.buckets.violation)],
          [`Interest @ ${(parseFloat(interestRate) * 100).toFixed(2)}%`, formatCurrency(calculatedData.buckets.interest)],
          ['Bank Fees', formatCurrency(calculatedData.buckets.bankFee)],
        ],
        theme: 'grid',
        headStyles: { fillColor: [0, 0, 0], textColor: 255, halign: 'left', fontStyle: 'bold' },
        columnStyles: { 
            0: { halign: 'left', cellPadding: 4 }, 
            1: { halign: 'right', cellPadding: 4 } 
        },
        styles: { fontSize: 9, lineColor: [200, 200, 200] },
      });
      const breakdownBottomY = doc.lastAutoTable.finalY;

      // Right: Account Summary
      autoTable(doc, {
        startY: summaryYStart,
        margin: { left: pageWidth - margin - 280 },
        tableWidth: 280,
        head: [['Account Number', 'Due Date', 'Total Due']],
        body: [[
          accountNumber,
          'Upon Receipt',
          formatBalance(calculatedData.totals.totalDue)
        ]],
        theme: 'grid',
        headStyles: { fillColor: [0, 0, 0], textColor: 255, halign: 'center', fontStyle: 'bold' },
        bodyStyles: { halign: 'center', fontStyle: 'bold', fontSize: 11, cellPadding: 6 },
        styles: { lineColor: [200, 200, 200] }
      });
      const accountInfoBottomY = doc.lastAutoTable.finalY;

      // --- 3. Main Ledger Table ---
      const tableColumn = ["Date", "Description", "Assess", "Late", "Admin", "Legal", "Viol", "Int", "Bank", "Pay (AR)", "Balance"];
      const tableRows = [];

      const getCellData = (row, field) => {
          const allocationVal = row.allocations?.[field];
          const showAllocation = field !== 'payment' && allocationVal > 0 && (!row[field] || parseFloat(row[field]) === 0);
          if (showAllocation) {
              return { content: formatCurrency(-Math.abs(allocationVal)), styles: { textColor: [100, 116, 139], fontStyle: 'italic' } };
          }
          return formatCurrency(row[field] || 0);
      };

      calculatedData.rows.forEach(row => {
        const rowData = [
          row.date,
          row.description || '-',
          getCellData(row, 'assessment'),
          getCellData(row, 'lateFee'),
          getCellData(row, 'adminFee'),
          getCellData(row, 'legalFee'),
          getCellData(row, 'violation'),
          getCellData(row, 'interest'),
          getCellData(row, 'bankFee'),
          parseFloat(row.payment) > 0 
            ? { content: formatCurrency(row.payment), styles: { textColor: [5, 150, 105], fontStyle: 'bold' } }
            : formatCurrency(row.payment || 0),
          formatBalance(row.balance)
        ];
        tableRows.push(rowData);
      });

      // Totals Row for Main Table
      const totalsRow = [
        "TOTALS",
        "",
        formatCurrency(calculatedData.totals.assessment),
        formatCurrency(calculatedData.totals.lateFee),
        formatCurrency(calculatedData.totals.adminFee),
        formatCurrency(calculatedData.totals.legalFee),
        formatCurrency(calculatedData.totals.violation),
        formatCurrency(calculatedData.totals.interest),
        formatCurrency(calculatedData.totals.bankFee),
        formatCurrency(calculatedData.totals.payment),
        formatBalance(calculatedData.totals.totalDue)
      ];
      tableRows.push(totalsRow);

      const tableStartY = Math.max(breakdownBottomY, accountInfoBottomY) + 30;

      autoTable(doc, {
        head: [tableColumn],
        body: tableRows,
        startY: tableStartY,
        margin: { left: margin, right: margin },
        theme: 'grid',
        styles: { fontSize: 8, cellPadding: 4, lineColor: [220, 220, 220] },
        headStyles: { fillColor: [0, 0, 0], textColor: 255, fontStyle: 'bold', halign: 'center' },
        columnStyles: {
           0: { cellWidth: 50, halign: 'center' },
           1: { cellWidth: 'auto' },
           2: { halign: 'right', cellWidth: 55 },
           3: { halign: 'right', cellWidth: 50 },
           4: { halign: 'right', cellWidth: 50 },
           5: { halign: 'right', cellWidth: 50 },
           6: { halign: 'right', cellWidth: 50 },
           7: { halign: 'right', cellWidth: 50 },
           8: { halign: 'right', cellWidth: 50 },
           9: { halign: 'right', cellWidth: 55 },
           10: { halign: 'right', cellWidth: 65, fontStyle: 'bold', fillColor: [248, 248, 248] }
        },
        didParseCell: function(data) {
           if (data.row.index === tableRows.length - 1 && data.section === 'body') {
               data.cell.styles.fontStyle = 'bold';
               data.cell.styles.fillColor = [240, 240, 240];
               data.cell.styles.textColor = [0, 0, 0];
           }
        }
      });

      // --- 4. Footer ---
      const pageCount = doc.internal.getNumberOfPages();
      for (let i = 1; i <= pageCount; i++) {
        doc.setPage(i);
        doc.setFontSize(8);
        doc.setTextColor(150, 150, 150);
        doc.text(
          `Generated by Avria Community Management • Page ${i} of ${pageCount} • Printed on ${new Date().toLocaleString()}`,
          pageWidth / 2,
          doc.internal.pageSize.getHeight() - 20,
          { align: 'center' }
        );
      }

      // Save
      const fileNameDate = new Date().toISOString().split('T')[0];
      const safePropName = (prop.owner_name || 'ledger').replace(/[^a-z0-9]/gi, '_').toLowerCase();
      doc.save(`account-statement-${safePropName}-${fileNameDate}.pdf`);
      
      toast({ title: "Success", description: "Account statement PDF downloaded." });
    } catch (error) {
      console.error("PDF generation failed", error);
      toast({ variant: "destructive", title: "Error", description: "Failed to generate professional PDF." });
    }
  };

  const updateRow = (id, field, value) => {
    setRows(prev => prev.map(r => {
      if (r.id === id) {
        const updated = { ...r, [field]: value };
        if (field === 'interest') updated.isAutoInterest = false;
        
        if (field === 'payment' && parseFloat(value) > 0) {
           updated.entry_type = 'credit';
        }

        return updated;
      }
      return r;
    }));
  };

  const addRow = () => setRows([...rows, { ...DEFAULT_ROW, id: crypto.randomUUID() }]);

  const addInterestRow = () => {
    setRows([...rows, { 
      ...DEFAULT_ROW, 
      id: crypto.randomUUID(), 
      description: `Interest @ ${(parseFloat(interestRate) * 100).toFixed(2)}%`,
      isAutoInterest: true 
    }]);
  };
  
  const handleAddCredit = ({ entryType, amount, category, description }) => {
    const absAmount = Math.abs(amount);
    const newRow = { 
      ...DEFAULT_ROW, id: crypto.randomUUID(), entry_type: 'credit', description: description || 'Credit Adjustment / AR Payment', credit_amount: absAmount, payment: absAmount
    };
    if (category && category !== 'payment') newRow[category] = -absAmount;
    setRows([...rows, newRow]);
  };
  
  const handleAddBankFee = ({ amount, description }) => {
    const newRow = { ...DEFAULT_ROW, id: crypto.randomUUID(), entry_type: 'bank_fee', description: description || 'Bank Fee', bankFee: amount, payment: 0 };
    setRows([...rows, newRow]);
  };

  const removeRow = (id) => {
    if (rows.length > 1) setRows(rows.filter(r => r.id !== id));
  };

  const handleReset = () => {
    if (confirm("Are you sure? This will clear the current form.")) {
        setCurrentLedgerId(null);
        setLedgerName('');
        setSelectedClient('');
        setSelectedProperty('');
        setRows([{ ...DEFAULT_ROW, id: crypto.randomUUID() }]);
        setInterestRate("0.015");
        toast({ title: "Reset", description: "Form cleared for new ledger." });
    }
  };

  const handleSave = async () => {
    if (!ledgerName) return toast({ variant: 'destructive', title: 'Error', description: 'Please enter a ledger name.' });
    if (!selectedClient) return toast({ variant: 'destructive', title: 'Error', description: 'Please select a client.' });

    const hasNegativePayments = rows.some(r => parseFloat(r.payment) < 0);
    if (hasNegativePayments) {
        return toast({ variant: 'destructive', title: 'Validation Error', description: 'Payment amounts must be positive numbers.' });
    }

    setIsLoading(true);
    try {
      const { data: { user } } = await supabase.auth.getUser();

      const cleanedRows = rows.map(r => ({
        ...r,
        entry_type: parseFloat(r.payment) > 0 ? 'credit' : r.entry_type
      }));

      const payload = {
        name: ledgerName,
        association_id: selectedClient,
        owner_id: selectedProperty || null,
        rows: cleanedRows,
        settings: { interestRate },
        updated_at: new Date().toISOString()
      };

      if (currentLedgerId) {
        const { error } = await supabase.from('custom_ledgers').update(payload).eq('id', currentLedgerId);
        if (error) throw error;
        toast({ title: 'Success', description: 'Ledger updated successfully.' });
      } else {
        const insertPayload = { ...payload, created_by: user?.id };
        const { data, error } = await supabase.from('custom_ledgers').insert([insertPayload]).select('id').single();
        if (error) throw error;
        if (data) setCurrentLedgerId(data.id); 
        toast({ title: 'Success', description: 'Ledger created successfully.' });
      }

      // Auto-sync to unit ledger
      try {
        await syncToUnitLedger();
      } catch (syncErr) {
        console.warn('Unit ledger sync warning:', syncErr);
      }

      fetchSavedLedgers();
    } catch (err) {
      toast({ variant: 'destructive', title: 'Error', description: 'Failed to save ledger.' });
    } finally {
      setIsLoading(false);
    }
  };

  const handleLoad = async (ledger) => {
    setIsLoading(true);
    try {
      const { data, error } = await supabase.from('custom_ledgers').select('*').eq('id', ledger.id).single();
      if (error) throw error;

      setCurrentLedgerId(data.id); 
      setLedgerName(data.name);
      setSelectedClient(data.association_id || '');
      setSelectedProperty(data.owner_id || '');
      
      const loadedRows = (data.rows || []).map(r => {
        if (r.entry_type === 'bank_fee' && !r.bankFee && r.payment < 0) {
            return { ...r, bankFee: Math.abs(r.payment), payment: 0 };
        }
        return {
          ...r,
          chart_of_account_id: r.chart_of_account_id || ''
        };
      });

      setRows(loadedRows);
      if (data.settings?.interestRate) setInterestRate(data.settings.interestRate);
      
      setLoadDialogOpen(false);
      toast({ title: 'Loaded', description: `Ledger "${data.name}" loaded.` });
    } catch (err) {
      toast({ variant: 'destructive', title: 'Error', description: 'Failed to load ledger.' });
    } finally {
      setIsLoading(false);
    }
  };

  // Load from Unit Ledger (owner_ledger_entries)
  // If sinceLastZero is true, only load entries AFTER the most recent $0.00 running balance.
  const handleLoadFromUnitLedger = async (sinceLastZero = false) => {
    if (!selectedClient) return toast({ variant: 'destructive', title: 'Error', description: 'Please select a client first.' });
    if (!selectedProperty) return toast({ variant: 'destructive', title: 'Error', description: 'Please select a property/owner first.' });

    setIsLoading(true);
    try {
      // Find the owner's unit_id
      const { data: ownerData } = await supabase
        .from('owners')
        .select('id, unit_id')
        .eq('id', selectedProperty)
        .single();

      if (!ownerData?.unit_id) {
        toast({ variant: 'destructive', title: 'No Unit', description: 'This owner has no unit linked. Cannot load ledger.' });
        setIsLoading(false);
        return;
      }

      // Fetch all ledger entries for this unit (paginated)
      const allEntries = [];
      let from = 0;
      const pageSize = 1000;
      while (true) {
        const { data: page, error } = await supabase
          .from('owner_ledger_entries')
          .select('*')
          .eq('unit_id', ownerData.unit_id)
          .order('date', { ascending: true })
          .range(from, from + pageSize - 1);
        if (error) throw error;
        allEntries.push(...(page || []));
        if (!page || page.length < pageSize) break;
        from += pageSize;
      }

      if (allEntries.length === 0) {
        toast({ title: 'No Entries', description: 'No ledger entries found for this unit.' });
        setIsLoading(false);
        return;
      }

      let workingEntries = allEntries;
      if (sinceLastZero) {
        // Walk entries to find the most recent point where running balance hit $0.00
        let bal = 0;
        let lastZeroIdx = -1;
        allEntries.forEach((e, i) => {
          bal += Number(e.debit || 0) - Number(e.credit || 0);
          if (Math.abs(bal) < 0.01) lastZeroIdx = i;
        });
        if (lastZeroIdx >= 0) {
          workingEntries = allEntries.slice(lastZeroIdx + 1);
        }
        if (workingEntries.length === 0) {
          toast({ title: 'Account at $0', description: 'No entries since the last zero balance — account is currently at $0.' });
          setIsLoading(false);
          return;
        }
      }

      // Map ledger entries to custom ledger row format
      const mapTypeToColumn = (entry) => {
        const row = { ...DEFAULT_ROW, id: crypto.randomUUID() };
        row.date = entry.date || new Date().toISOString().split('T')[0];
        row.description = entry.description || '';
        row._ledgerEntryId = entry.id; // Track source for sync

        const type = (entry.transaction_type || '').toLowerCase();
        const debit = Number(entry.debit || 0);
        const credit = Number(entry.credit || 0);

        if (type === 'payment' || credit > 0) {
          row.entry_type = 'credit';
          row.payment = credit || Math.abs(debit);
        } else if (type === 'late_fee') {
          row.entry_type = 'late_fee';
          row.lateFee = debit;
        } else if (type === 'interest') {
          row.entry_type = 'interest';
          row.interest = debit;
        } else if (type === 'legal_fee') {
          row.entry_type = 'debit';
          row.legalFee = debit;
        } else if (type === 'admin_fee') {
          row.entry_type = 'debit';
          row.adminFee = debit;
        } else if (type === 'violation') {
          row.entry_type = 'debit';
          row.violation = debit;
        } else if (type === 'bank_fee') {
          row.entry_type = 'bank_fee';
          row.bankFee = debit;
        } else if (type === 'special_assessment') {
          row.entry_type = 'debit';
          row.assessment = debit;
        } else {
          // Default: assessment
          row.entry_type = 'debit';
          row.assessment = debit;
        }

        return row;
      };

      const mappedRows = workingEntries.map(mapTypeToColumn);
      setRows(mappedRows);
      if (!ledgerName) {
        const ownerLabel = properties.find(p => p.id === selectedProperty)?.owner_name || 'Unknown';
        setLedgerName(sinceLastZero ? `Ledger since last $0 — ${ownerLabel}` : `Unit Ledger — ${ownerLabel}`);
      }
      toast({
        title: 'Loaded',
        description: sinceLastZero
          ? `Loaded ${mappedRows.length} entries since the last $0 balance.`
          : `Loaded ${mappedRows.length} entries from unit ledger.`,
      });
    } catch (err) {
      console.error('Load from unit ledger error:', err);
      toast({ variant: 'destructive', title: 'Error', description: 'Failed to load unit ledger entries.' });
    } finally {
      setIsLoading(false);
    }
  };

  // Sync rows back to owner_ledger_entries on save
  const syncToUnitLedger = async () => {
    if (!selectedClient || !selectedProperty) return;

    const { data: ownerData } = await supabase
      .from('owners')
      .select('id, unit_id')
      .eq('id', selectedProperty)
      .single();

    if (!ownerData?.unit_id) return;

    const { data: { user } } = await supabase.auth.getUser();

    for (const row of rows) {
      // Determine transaction_type and debit/credit from columns
      let transaction_type = 'assessment';
      let debit = 0;
      let credit = 0;

      const payment = parseFloat(row.payment) || 0;
      if (payment > 0) {
        transaction_type = 'payment';
        credit = payment;
      } else if (parseFloat(row.bankFee) > 0) {
        transaction_type = 'bank_fee';
        debit = parseFloat(row.bankFee);
      } else if (parseFloat(row.interest) > 0) {
        transaction_type = 'interest';
        debit = parseFloat(row.interest);
      } else if (parseFloat(row.lateFee) > 0) {
        transaction_type = 'late_fee';
        debit = parseFloat(row.lateFee);
      } else if (parseFloat(row.legalFee) > 0) {
        transaction_type = 'legal_fee';
        debit = parseFloat(row.legalFee);
      } else if (parseFloat(row.adminFee) > 0) {
        transaction_type = 'admin_fee';
        debit = parseFloat(row.adminFee);
      } else if (parseFloat(row.violation) > 0) {
        transaction_type = 'violation';
        debit = parseFloat(row.violation);
      } else if (parseFloat(row.assessment) > 0) {
        transaction_type = 'assessment';
        debit = parseFloat(row.assessment);
      }

      if (debit === 0 && credit === 0) continue; // skip empty rows

      if (row._ledgerEntryId) {
        // Update existing entry
        await supabase.from('owner_ledger_entries').update({
          date: row.date,
          description: row.description,
          transaction_type,
          debit,
          credit,
        }).eq('id', row._ledgerEntryId);
      } else {
        // Insert new entry
        const { data: inserted } = await supabase.from('owner_ledger_entries').insert({
          association_id: selectedClient,
          owner_id: selectedProperty,
          unit_id: ownerData.unit_id,
          date: row.date,
          description: row.description,
          transaction_type,
          debit,
          credit,
          created_by: user?.id || null,
        }).select('id').single();

        if (inserted) row._ledgerEntryId = inserted.id;
      }
    }
  };

  const handleDeleteSaved = async (id, e) => {
    e.stopPropagation();
    if (!confirm('Are you sure you want to delete this template?')) return;
    await supabase.from('custom_ledgers').delete().eq('id', id);
    if (currentLedgerId === id) setCurrentLedgerId(null); 
    fetchSavedLedgers();
    toast({ title: 'Deleted', description: 'Ledger template deleted.' });
  };


  return (
    <div className="space-y-6">
      <Alert className="bg-blue-50 border-blue-200 dark:bg-blue-950/30 dark:border-blue-800">
         <AlertDescription className="text-blue-800 dark:text-blue-300 text-xs">
            <strong>Accounting Rules Enforced:</strong> All Income Charges are treated as Debits (increases balance). Payments should be entered as positive numbers and are automatically treated as Credits against Accounts Receivable (AR).
         </AlertDescription>
      </Alert>

      <div className="bg-background p-6 rounded-xl border shadow-sm space-y-4">
        <div className="flex flex-col md:flex-row gap-4 justify-between items-start md:items-end">
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4 w-full">
            <div className="space-y-2">
              <Label>Ledger Name</Label>
              <Input placeholder="e.g. 2025 Annual Assessment" value={ledgerName} onChange={e => setLedgerName(e.target.value)} />
            </div>
            <div className="space-y-2">
              <Label>Client Association</Label>
              <Select value={selectedClient} onValueChange={setSelectedClient}>
                <SelectTrigger><SelectValue placeholder="Select Client" /></SelectTrigger>
                <SelectContent>{clients.map(c => <SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>)}</SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Property / Owner</Label>
              <Combobox options={properties.map(p => ({ value: p.id, label: `${p.owner_name} - ${p.property_address}` }))} value={selectedProperty} onChange={setSelectedProperty} placeholder="Select Property..." disabled={!selectedClient} />
            </div>
          </div>
          
          <div className="flex gap-2 shrink-0">
             <Button onClick={handleDownloadPDF} className="bg-slate-900 text-white hover:bg-slate-800 dark:bg-slate-100 dark:text-slate-900 dark:hover:bg-slate-200">
                <FileDown className="w-4 h-4 mr-2" /> Export Statement
             </Button>
             <Dialog open={loadDialogOpen} onOpenChange={setLoadDialogOpen}>
                <DialogTrigger asChild><Button variant="outline"><Upload className="w-4 h-4 mr-2" /> Load</Button></DialogTrigger>
                <DialogContent>
                   <DialogHeader><DialogTitle>Load Saved Ledger</DialogTitle></DialogHeader>
                   <div className="space-y-2 max-h-[300px] overflow-y-auto">
                      {savedLedgers.length === 0 ? <p className="text-muted-foreground text-sm">No saved ledgers found.</p> : 
                         savedLedgers.map(l => (
                           <div key={l.id} className="flex justify-between items-center p-3 hover:bg-muted/50 border rounded cursor-pointer" onClick={() => handleLoad(l)}>
                              <div><p className="font-medium">{l.name}</p><p className="text-xs text-muted-foreground">{new Date(l.created_at).toLocaleDateString()}</p></div>
                              <Button variant="ghost" size="sm" onClick={(e) => handleDeleteSaved(l.id, e)} className="text-destructive hover:text-destructive hover:bg-destructive/10"><Trash2 className="w-4 h-4" /></Button>
                           </div>
                         ))
                      }
                   </div>
                </DialogContent>
             </Dialog>
             <Button variant="outline" onClick={() => handleLoadFromUnitLedger(false)} disabled={isLoading || !selectedProperty} title="Load entries from the unit's actual ledger">
                <Database className="w-4 h-4 mr-2" /> Load from Unit Ledger
             </Button>
             <Button variant="outline" onClick={() => handleLoadFromUnitLedger(true)} disabled={isLoading || !selectedProperty} title="Load only entries since the most recent $0 balance">
                <Database className="w-4 h-4 mr-2" /> From Last $0 Balance
             </Button>
             <Button variant="outline" onClick={handleReset} title="Create New / Reset Form">
                <RotateCcw className="w-4 h-4" />
             </Button>
             <Button onClick={handleSave} disabled={isLoading} className="bg-primary text-primary-foreground hover:bg-primary/90 min-w-[140px]">
                {isLoading ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4 mr-2" />} 
                {currentLedgerId ? 'Update Ledger' : 'Create Ledger'}
             </Button>
          </div>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t">
          <div className="flex items-center gap-4">
            <div className="flex items-center gap-2">
                <Label>Interest Rate:</Label>
                <Select value={interestRate} onValueChange={setInterestRate}>
                  <SelectTrigger className="w-[200px]"><SelectValue /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="0.01">12% / Year (1% Monthly)</SelectItem>
                    <SelectItem value="0.015">18% / Year (1.5% Monthly)</SelectItem>
                    <SelectItem value="custom">Custom Override...</SelectItem>
                  </SelectContent>
                </Select>
                {!["0.01", "0.015"].includes(interestRate) || interestRate === "custom" ? null : null}
                {(interestRate === "custom" || (interestRate !== "0.01" && interestRate !== "0.015")) && (
                  <div className="flex items-center gap-1">
                    <Input
                      type="number"
                      step="0.001"
                      min="0"
                      placeholder="e.g. 1.5"
                      className="w-[110px]"
                      value={interestRate === "custom" ? "" : (parseFloat(interestRate) * 100).toString()}
                      onChange={(e) => {
                        const pct = parseFloat(e.target.value);
                        if (isNaN(pct)) {
                          setInterestRate("custom");
                        } else {
                          setInterestRate((pct / 100).toString());
                        }
                      }}
                    />
                    <span className="text-sm text-muted-foreground">% / month</span>
                  </div>
                )}
            </div>
            <div className="text-xs text-muted-foreground italic">* Interest is calculated on the Assessment Balance.</div>
          </div>
          
          <div className="flex items-center justify-end gap-2">
            <Button variant="outline" className="text-purple-600 border-purple-200 hover:bg-purple-50 dark:text-purple-400 dark:border-purple-800 dark:hover:bg-purple-950" onClick={handleImportAutomations}>
              <History className="w-4 h-4 mr-2" /> Sync Automated History
            </Button>
            <input type="file" ref={fileInputRef} className="hidden" accept=".csv,text/csv" onChange={handleCsvUpload} />
            <Button variant="outline" className="text-emerald-600 border-emerald-200 hover:bg-emerald-50 dark:text-emerald-400 dark:border-emerald-800 dark:hover:bg-emerald-950" onClick={() => fileInputRef.current?.click()}><FileUp className="w-4 h-4 mr-2" /> Import CSV</Button>
          </div>
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
        <Card className="md:col-span-1 bg-slate-900 text-white border-none shadow-md dark:bg-slate-800">
          <CardHeader className="pb-2"><CardTitle className="text-sm font-medium opacity-80 uppercase tracking-wider">{calculatedData.totals.totalDue < 0 ? 'Credit Balance' : 'Total Due'}</CardTitle></CardHeader>
          <CardContent><div className="text-3xl font-bold">{formatBalance(calculatedData.totals.totalDue)}</div><p className="text-xs opacity-60 mt-1">Outstanding Balance</p></CardContent>
        </Card>

        <Card className="md:col-span-3 shadow-sm">
           <CardHeader className="pb-2 py-3 border-b"><CardTitle className="text-sm font-bold uppercase">Amount Due Breakdown (In Priority Order)</CardTitle></CardHeader>
           <CardContent className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-7 gap-4 pt-4">
               <div className="bg-red-50 dark:bg-red-950/30 p-2 rounded border border-red-100 dark:border-red-900">
                  <p className="text-xs text-red-600 dark:text-red-400 font-bold uppercase mb-1">1. Bank Fees</p>
                  <p className="text-lg font-bold text-red-800 dark:text-red-300">{formatCurrency(calculatedData.buckets.bankFee)}</p>
               </div>
               <div><p className="text-xs text-muted-foreground font-medium uppercase">2. Interest</p><p className="text-lg font-bold">{formatCurrency(calculatedData.buckets.interest)}</p></div>
               <div><p className="text-xs text-muted-foreground font-medium uppercase">3. Late Fees</p><p className="text-lg font-bold">{formatCurrency(calculatedData.buckets.late)}</p></div>
               <div><p className="text-xs text-muted-foreground font-medium uppercase">4. Legal Fees</p><p className="text-lg font-bold">{formatCurrency(calculatedData.buckets.legal)}</p></div>
               <div><p className="text-xs text-muted-foreground font-medium uppercase">5. Admin Fees</p><p className="text-lg font-bold">{formatCurrency(calculatedData.buckets.admin)}</p></div>
               <div><p className="text-xs text-muted-foreground font-medium uppercase">6. Violations</p><p className="text-lg font-bold">{formatCurrency(calculatedData.buckets.violation)}</p></div>
               <div><p className="text-xs text-muted-foreground font-medium uppercase">7. Assessments</p><p className="text-lg font-bold">{formatCurrency(calculatedData.buckets.assessment)}</p></div>
           </CardContent>
        </Card>
      </div>

      <div className="bg-background rounded-xl border shadow-sm overflow-hidden">
         <DragDropContext onDragEnd={handleOnDragEnd}>
             <Table>
                <TableHeader className="bg-muted/50">
                   <TableRow>
                      <TableHead className="w-[30px]"></TableHead>
                      <TableHead className="w-[110px]">Date</TableHead>
                      <TableHead className="min-w-[150px]">Description</TableHead>
                      <TableHead className="w-[150px]">Account</TableHead>
                      <TableHead className="w-[90px] text-right bg-blue-50/50 dark:bg-blue-950/20">Assess ($)</TableHead>
                      <TableHead className="w-[90px] text-right">Late ($)</TableHead>
                      <TableHead className="w-[90px] text-right">Admin ($)</TableHead>
                      <TableHead className="w-[90px] text-right">Legal ($)</TableHead>
                      <TableHead className="w-[90px] text-right">Viol ($)</TableHead>
                      <TableHead className="w-[90px] text-right">Int ($)</TableHead>
                      <TableHead className="w-[90px] text-right bg-red-50/50 dark:bg-red-950/20 text-red-700 dark:text-red-400">Bank ($)</TableHead>
                      <TableHead className="w-[90px] text-right bg-green-50/50 dark:bg-green-950/20">Pay (AR) ($)</TableHead>
                      <TableHead className="w-[100px] text-right font-bold bg-muted">Balance</TableHead>
                      <TableHead className="w-[50px]"></TableHead>
                   </TableRow>
                </TableHeader>
                <Droppable droppableId="ledger-rows">
                  {(provided) => (
                    <TableBody ref={provided.innerRef} {...provided.droppableProps}>
                       {calculatedData.rows.map((row, index) => {
                          const isCredit = row.entry_type === 'credit';
                          const isBankFee = row.entry_type === 'bank_fee';
                          const isAuto = row.entry_type === 'late_fee' || row.entry_type === 'interest' || (row.description || '').includes('[AUTO]');
                          const fields = ['assessment', 'lateFee', 'adminFee', 'legalFee', 'violation', 'interest', 'bankFee', 'payment'];
                          
                          return (
                          <Draggable key={row.id} draggableId={row.id} index={index}>
                            {(provided) => (
                              <TableRow 
                                ref={provided.innerRef} 
                                {...provided.draggableProps} 
                                className={cn(
                                  "group hover:bg-muted/50", 
                                  isCredit ? "bg-emerald-50/70 dark:bg-emerald-950/20 hover:bg-emerald-50 dark:hover:bg-emerald-950/30 border-l-4 border-emerald-500" : "", 
                                  isBankFee && !isCredit ? "bg-red-50/40 dark:bg-red-950/10 hover:bg-red-50 dark:hover:bg-red-950/20" : "", 
                                  isAuto && !isCredit && !isBankFee ? "bg-purple-50/30 dark:bg-purple-950/10 hover:bg-purple-50/50 dark:hover:bg-purple-950/20" : "",
                                  !isCredit && !isBankFee && !isAuto ? "bg-background" : ""
                                )} 
                                style={{ ...provided.draggableProps.style }}
                              >
                                 <TableCell className="p-1 text-center align-middle">
                                    <div {...provided.dragHandleProps} className="cursor-grab hover:text-foreground text-muted-foreground flex items-center justify-center h-full w-full"><GripVertical className="w-4 h-4" /></div>
                                 </TableCell>
                                 <TableCell className="p-1">
                                    <Input type="date" value={row.date} onChange={e => updateRow(row.id, 'date', e.target.value)} className="h-8 text-xs border-transparent focus:border-border bg-transparent" />
                                 </TableCell>
                                 <TableCell className="p-1 relative group-cell">
                                    <div className="flex items-center gap-1">
                                       {isCredit && <Badge variant="outline" className="h-5 px-1 bg-emerald-100 dark:bg-emerald-900 text-emerald-700 dark:text-emerald-300 border-emerald-200 dark:border-emerald-700 text-[10px] mr-1 whitespace-nowrap">AR PAY</Badge>}
                                       {isBankFee && !isCredit && <Badge variant="outline" className="h-5 px-1 bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-300 border-red-200 dark:border-red-700 text-[10px] mr-1 whitespace-nowrap">BANK FEE</Badge>}
                                       {isAuto && <Badge variant="outline" className="h-5 px-1 bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300 border-purple-200 dark:border-purple-700 text-[10px] mr-1 whitespace-nowrap">AUTO</Badge>}
                                       <Input type="text" placeholder="Description" value={row.description} onChange={e => updateRow(row.id, 'description', e.target.value)} className={cn("h-8 text-xs border-transparent focus:border-border bg-transparent flex-1", isCredit && "text-emerald-900 dark:text-emerald-300", isBankFee && !isCredit && "text-red-900 dark:text-red-300")} />
                                    </div>
                                 </TableCell>
                                 <TableCell className="p-1">
                                   <ChartOfAccountsDropdown 
                                      value={row.chart_of_account_id}
                                      onChange={(v) => updateRow(row.id, 'chart_of_account_id', v)}
                                      className="h-8 py-0 px-2 text-xs border-transparent bg-transparent"
                                      placeholder="Account"
                                      associationId={selectedClient}
                                   />
                                 </TableCell>
                                 {fields.map(field => {
                                    const allocationVal = row.allocations?.[field];
                                    const showAllocation = field !== 'payment' && allocationVal > 0 && (!row[field] || parseFloat(row[field]) === 0);
                                    const hasValue = row[field] && parseFloat(row[field]) !== 0;

                                    return (
                                       <TableCell key={field} className={cn("p-1", field === 'assessment' && "bg-blue-50/30 dark:bg-blue-950/10", field === 'payment' && "bg-green-50/30 dark:bg-green-950/10", field === 'bankFee' && "bg-red-50/30 dark:bg-red-950/10")}>
                                          {showAllocation ? (
                                              <div className="h-8 text-xs text-right flex items-center justify-end px-3 italic font-medium text-muted-foreground">
                                                 {formatCurrency(-Math.abs(allocationVal))}
                                              </div>
                                          ) : (
                                              <div className="relative">
                                                <Input 
                                                  type="number" 
                                                  step="0.01" 
                                                  value={row.isAutoInterest && field === 'interest' ? row.interest.toFixed(2) : (row[field] || '')} 
                                                  readOnly={row.isAutoInterest && field === 'interest'} 
                                                  onChange={e => updateRow(row.id, field, e.target.value)} 
                                                  className={cn(
                                                    "h-8 text-xs text-right border-transparent focus:border-border bg-transparent", 
                                                    row.isAutoInterest && field === 'interest' && "text-muted-foreground italic bg-muted cursor-not-allowed", 
                                                    !hasValue && "text-muted-foreground italic", 
                                                    hasValue && field === 'payment' && parseFloat(row[field]) > 0 && "text-emerald-600 dark:text-emerald-400 font-bold",
                                                    hasValue && field !== 'payment' && parseFloat(row[field]) < 0 && "text-muted-foreground font-bold"
                                                  )} 
                                                  placeholder="0.00" 
                                                />
                                              </div>
                                          )}
                                       </TableCell>
                                    );
                                 })}
                                  <TableCell className={cn("text-right font-bold text-sm bg-muted/50 p-2 align-middle", row.balance < 0 && "text-emerald-600 dark:text-emerald-400")}>{formatBalance(row.balance)}</TableCell>
                                 <TableCell className="p-1 text-center align-middle">
                                    <Button variant="ghost" size="icon" className="h-6 w-6 text-muted-foreground hover:text-destructive" onClick={() => removeRow(row.id)}><Trash2 className="w-3.5 h-3.5" /></Button>
                                 </TableCell>
                              </TableRow>
                            )}
                          </Draggable>
                       );})}
                       {provided.placeholder}
                       <TableRow className="border-t-2 bg-muted/70 font-bold hover:bg-muted/70">
                           <TableCell colSpan={4} className="text-right text-xs uppercase tracking-wider text-muted-foreground">Totals:</TableCell>
                           <TableCell className="text-right text-xs">{formatCurrency(calculatedData.totals.assessment)}</TableCell>
                           <TableCell className="text-right text-xs">{formatCurrency(calculatedData.totals.lateFee)}</TableCell>
                           <TableCell className="text-right text-xs">{formatCurrency(calculatedData.totals.adminFee)}</TableCell>
                           <TableCell className="text-right text-xs">{formatCurrency(calculatedData.totals.legalFee)}</TableCell>
                           <TableCell className="text-right text-xs">{formatCurrency(calculatedData.totals.violation)}</TableCell>
                           <TableCell className="text-right text-xs">{formatCurrency(calculatedData.totals.interest)}</TableCell>
                           <TableCell className="text-right text-xs text-red-700 dark:text-red-400">{formatCurrency(calculatedData.totals.bankFee)}</TableCell>
                           <TableCell className="text-right text-xs text-green-700 dark:text-green-400">{formatCurrency(calculatedData.totals.payment)}</TableCell>
                            <TableCell className={cn("text-right text-sm bg-muted border-l", calculatedData.totals.totalDue < 0 && "text-emerald-600 dark:text-emerald-400")}>{formatBalance(calculatedData.totals.totalDue)}</TableCell>
                           <TableCell></TableCell>
                       </TableRow>
                    </TableBody>
                  )}
                </Droppable>
             </Table>
         </DragDropContext>
         
         <div className="p-4 border-t bg-muted/30 flex gap-2">
            <Button variant="outline" size="sm" onClick={addRow} className="text-blue-600 hover:text-blue-700 hover:bg-blue-50 border-blue-200 dark:text-blue-400 dark:border-blue-800 dark:hover:bg-blue-950"><Plus className="w-4 h-4 mr-2" /> Add Charge (Debit)</Button>
            <Button variant="outline" size="sm" onClick={() => setCreditDialogOpen(true)} className="text-emerald-600 hover:text-emerald-700 hover:bg-emerald-50 border-emerald-200 dark:text-emerald-400 dark:border-emerald-800 dark:hover:bg-emerald-950"><Plus className="w-4 h-4 mr-2" /> Add Payment (AR Credit)</Button>
             <Button variant="outline" size="sm" onClick={() => setBankFeeDialogOpen(true)} className="text-red-600 hover:text-red-700 hover:bg-red-50 border-red-200 dark:text-red-400 dark:border-red-800 dark:hover:bg-red-950"><Plus className="w-4 h-4 mr-2" /> Add Bank Fee</Button>
            <Button variant="outline" size="sm" onClick={addInterestRow} className="text-indigo-600 hover:text-indigo-700 hover:bg-indigo-50 border-indigo-200 dark:text-indigo-400 dark:border-indigo-800 dark:hover:bg-indigo-950"><Calculator className="w-4 h-4 mr-2" /> Calculate Interest Row</Button>
         </div>
      </div>
      
      <CreditLineDialog open={creditDialogOpen} onOpenChange={setCreditDialogOpen} onAddCredit={handleAddCredit} />
      <BankFeeDialog open={bankFeeDialogOpen} onOpenChange={setBankFeeDialogOpen} onAddBankFee={handleAddBankFee} />
      <HtmlPreviewModal open={previewOpen} onOpenChange={setPreviewOpen} htmlContent={previewHtml} fileName={ledgerName ? ledgerName.replace(/\s+/g, '_') : 'ledger_preview'} orientation="landscape" />
    </div>
  );
}
