import { useState, useEffect, useMemo, useRef } from 'react';
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts';
import { DashboardBanner } from '../../lib/dashboardBanner';
import { useLocation, useNavigate } from 'react-router-dom';
import Layout from '../../components/Layout';
import SortTh from '../../components/SortTh';
import StatusBadge from '../../components/StatusBadge';
import { useSortable } from '../../hooks/useSortable';
import { supabase } from '../../lib/supabase';
import { readPageCache, writePageCache } from '../../lib/pageCache';
import { exportCPAPackage, generateSubcontractorPOPDF } from '../../lib/invoice';
import { blobToEmailAttachment, sendEmail } from '../../lib/email';
import { popupOverlayStyle, popupSurfaceStyle } from '../../lib/popupStyles';

const CATEGORIES = ['Software', 'Contractor', 'Advertising', 'Office', 'Travel', 'Meals', 'Equipment', 'Other'];
const statusColor = { draft: 'not_started', sent: 'in_progress', paid: 'client_approved' };
const poStatusColor = {
  draft: 'not_started',
  sent: 'in_progress',
  approved: 'client_approved',
  ready_to_pay: 'in_progress',
  paid: 'client_approved',
  cancelled: 'needs_revision',
};
const poStatusLabel = {
  draft: 'Draft',
  sent: 'Sent',
  approved: 'Approved',
  ready_to_pay: 'Ready to Pay',
  paid: 'Paid',
  cancelled: 'Cancelled',
};
const invoiceStatusBadgeLabel = (status) => {
  if (status === 'sent') return 'Invoiced';
  return status ? status.charAt(0).toUpperCase() + status.slice(1) : '—';
};
const RECEIPT_BUCKET = 'expense-receipts';
const FIELD_LABEL_STYLE = { fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: 0.8, display: 'block', marginBottom: 4 };
const FIELD_INPUT_STYLE = { minHeight: 42, margin: 0 };

const blankExpense = () => ({
  date: new Date().toISOString().slice(0, 10),
  description: '',
  category: 'Other',
  amount: '',
  notes: '',
  receipt: null,
  receipt_path: null,
  receipt_name: null,
  removeReceipt: false,
});

function getFileExt(name = '') {
  const clean = String(name).split('.').pop()?.toLowerCase();
  return clean && clean !== name ? clean.replace(/[^a-z0-9]/g, '') : 'bin';
}

const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

function FinancesChartTooltip({ active, payload, label, year }) {
  if (!active || !payload?.length) return null;
  return (
    <div style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 4, padding: '10px 14px', fontSize: 12 }}>
      <div style={{ fontWeight: 600, marginBottom: 6, color: 'var(--text-primary)' }}>{label} {year}</div>
      {payload.map(p => (
        <div key={p.dataKey} style={{ color: p.color, marginBottom: 2 }}>{p.name}: <strong>${p.value.toLocaleString('en-US', { minimumFractionDigits: 2 })}</strong></div>
      ))}
    </div>
  );
}

export default function Invoices() {
  const navigate = useNavigate();
  const location = useLocation();
  const cached = readPageCache('team_invoices');
  const [invoices, setInvoices] = useState(() => cached?.invoices || []);
  const [loading, setLoading] = useState(() => !cached);
  const [activeTab, setActiveTab] = useState(() => location.state?.tab || 'invoices');
  const [financeTab, setFinanceTab] = useState('overview');
  const [filter, setFilter] = useState('all');
  const { sortKey: invSortKey, sortDir: invSortDir, toggle: invToggle, sort: invSort } = useSortable('invoice_date');
  const { sortKey: expSortKey, sortDir: expSortDir, toggle: expToggle, sort: expSort } = useSortable('date');
  const { sortKey: subSortKey, sortDir: subSortDir, toggle: subToggle, sort: subSort } = useSortable('submitted_at');
  const { sortKey: ovExpKey, sortDir: ovExpDir, toggle: ovExpToggle } = useSortable('date');
  const { sortKey: ovSubKey, sortDir: ovSubDir, toggle: ovSubToggle } = useSortable('date');
  const { sortKey: ovInvKey, sortDir: ovInvDir, toggle: ovInvToggle } = useSortable('invoice_date');
  const [filterCompany, setFilterCompany] = useState('');
  const initMonth = () => { const n = new Date(); return { month: n.getMonth(), year: n.getFullYear() }; };
  const [ovMonth1, setOvMonth1] = useState(initMonth);
  const [ovMonth2, setOvMonth2] = useState(initMonth);
  const [ovMonth3, setOvMonth3] = useState(initMonth);
  const [exportYear, setExportYear] = useState(new Date().getFullYear());
  const [exporting, setExporting] = useState(false);

  const [expenses, setExpenses] = useState([]);
  const [expensesLoading, setExpensesLoading] = useState(true);
  const [expensesError, setExpensesError] = useState('');
  const [newExpense, setNewExpense] = useState(blankExpense());
  const [addingExpense, setAddingExpense] = useState(false);
  const [editingExpenseId, setEditingExpenseId] = useState('');
  const [showExpenseForm, setShowExpenseForm] = useState(false);
  const [expenseFilter, setExpenseFilter] = useState('all');
  const [subcontractorPOs, setSubcontractorPOs] = useState([]);
  const [subcontractorLoading, setSubcontractorLoading] = useState(true);
  const [subcontractorError, setSubcontractorError] = useState('');
  const [selectedSubcontractorPOId, setSelectedSubcontractorPOId] = useState('');
  const [subInvoices, setSubInvoices] = useState([]);
  const [subInvoicesLoading, setSubInvoicesLoading] = useState(true);
  const [subInvoicesError, setSubInvoicesError] = useState('');
  const [markingPaid, setMarkingPaid] = useState('');
  const [expandedSubInvoiceId, setExpandedSubInvoiceId] = useState(null);

  useEffect(() => {
    async function load() {
      const { data } = await supabase
        .from('invoices')
        .select('*, company:companies(name)')
        .order('created_at', { ascending: false });
      setInvoices(data || []);
      writePageCache('team_invoices', { invoices: data || [] });
      setLoading(false);
    }
    load();
  }, []);

  useEffect(() => {
    async function loadExpenses() {
      const [{ data, error }, { data: purchaseOrders, error: purchaseOrdersError }] = await Promise.all([
        supabase.from('expenses').select('*').order('date', { ascending: false }),
        supabase
          .from('subcontractor_payments')
          .select('*, profile:profiles!subcontractor_payments_profile_id_fkey(id, name, email), project:projects(id, name, company:companies(name)), items:subcontractor_po_items(*, task:tasks(id, title))')
          .order('date', { ascending: false }),
      ]);
      if (error) {
        console.error('Failed to load expenses:', error);
        setExpensesError(error.message || 'Failed to load expenses.');
        setExpenses([]);
      } else {
        setExpenses(data || []);
        setExpensesError('');
      }
      if (purchaseOrdersError) {
        console.error('Failed to load subcontractor POs:', purchaseOrdersError);
        setSubcontractorError(purchaseOrdersError.message || 'Failed to load subcontractor POs.');
        setSubcontractorPOs([]);
      } else {
        setSubcontractorPOs(purchaseOrders || []);
        setSubcontractorError('');
      }
      setExpensesLoading(false);
      setSubcontractorLoading(false);
    }
    loadExpenses();
  }, []);

  useEffect(() => {
    async function loadSubInvoices() {
      const { data, error: err } = await supabase
        .from('subcontractor_invoices')
        .select('*, profile:profiles!subcontractor_invoices_profile_id_fkey(id, name, email), items:subcontractor_invoice_items(*)')
        .order('created_at', { ascending: false });
      if (err) { setSubInvoicesError(err.message); setSubInvoicesLoading(false); return; }
      setSubInvoices(data || []);
      setSubInvoicesLoading(false);
    }
    loadSubInvoices();
  }, []);

  const startEditExpense = (expense) => {
    setEditingExpenseId(expense.id);
    setNewExpense({
      date: expense.date,
      description: expense.description || '',
      category: expense.category || 'Other',
      amount: String(expense.amount ?? ''),
      notes: expense.notes || '',
      receipt: null,
      receipt_path: expense.receipt_path || null,
      receipt_name: expense.receipt_name || null,
      removeReceipt: false,
    });
    setExpensesError('');
    setShowExpenseForm(true);
  };

  const cancelExpenseEdit = () => {
    setEditingExpenseId('');
    setNewExpense(blankExpense());
    setExpensesError('');
    setShowExpenseForm(false);
  };

  const handleAddExpense = async (e) => {
    e.preventDefault();
    if (!newExpense.description.trim() || !newExpense.amount) return;
    setAddingExpense(true);
    setExpensesError('');
    try {
      const existingExpense = editingExpenseId ? expenses.find(expense => expense.id === editingExpenseId) : null;
      let receiptPath = existingExpense?.receipt_path || newExpense.receipt_path || null;
      let receiptName = existingExpense?.receipt_name || newExpense.receipt_name || null;

      if (newExpense.removeReceipt && existingExpense?.receipt_path) {
        await supabase.storage.from(RECEIPT_BUCKET).remove([existingExpense.receipt_path]);
        receiptPath = null;
        receiptName = null;
      }

      if (newExpense.receipt) {
        const ext = getFileExt(newExpense.receipt.name);
        receiptName = newExpense.receipt.name;
        receiptPath = `${newExpense.date}/${Date.now()}-${crypto.randomUUID()}.${ext}`;
        const { error: uploadError } = await supabase.storage.from(RECEIPT_BUCKET).upload(receiptPath, newExpense.receipt, { upsert: false });
        if (uploadError) throw uploadError;
        if (existingExpense?.receipt_path) {
          await supabase.storage.from(RECEIPT_BUCKET).remove([existingExpense.receipt_path]);
        }
      }

      const payload = {
        date: newExpense.date,
        description: newExpense.description.trim(),
        category: newExpense.category,
        amount: Number(newExpense.amount),
        notes: newExpense.notes.trim(),
        receipt_path: receiptPath,
        receipt_name: receiptName,
      };

      const query = editingExpenseId
        ? supabase.from('expenses').update(payload).eq('id', editingExpenseId)
        : supabase.from('expenses').insert(payload);
      const { data, error } = await query.select().single();

      if (error) {
        if (newExpense.receipt && receiptPath) {
          await supabase.storage.from(RECEIPT_BUCKET).remove([receiptPath]);
        }
        throw error;
      }

      if (data) {
        setExpenses(prev => editingExpenseId
          ? prev.map(expense => expense.id === editingExpenseId ? data : expense)
          : [data, ...prev]
        );
        setNewExpense(blankExpense());
        setEditingExpenseId('');
        setShowExpenseForm(false);
      }
    } catch (error) {
      console.error(`Failed to ${editingExpenseId ? 'update' : 'add'} expense:`, error);
      setExpensesError(error.message || `Failed to ${editingExpenseId ? 'update' : 'add'} expense.`);
      alert(`Failed to ${editingExpenseId ? 'update' : 'add'} expense: ${error.message || 'unknown error'}`);
    }
    setAddingExpense(false);
  };

  const handleDeleteExpense = async (id) => {
    if (!window.confirm('Delete this expense?')) return;
    const expense = expenses.find(e => e.id === id);
    if (expense?.receipt_path) {
      await supabase.storage.from(RECEIPT_BUCKET).remove([expense.receipt_path]);
    }
    await supabase.from('expenses').delete().eq('id', id);
    setExpenses(prev => prev.filter(e => e.id !== id));
  };

  const handleViewReceipt = async (expense) => {
    if (!expense.receipt_path) return;
    const { data, error } = await supabase.storage.from(RECEIPT_BUCKET).createSignedUrl(expense.receipt_path, 3600, {
      download: expense.receipt_name || undefined,
    });
    if (error || !data?.signedUrl) {
      const message = error?.message || 'Failed to open receipt.';
      setExpensesError(message);
      alert(message);
      return;
    }
    window.open(data.signedUrl, '_blank', 'noopener,noreferrer');
  };

  const updateSubcontractorPO = async (po, updates, errorLabel = 'Failed to update PO') => {
    const { data, error } = await supabase
      .from('subcontractor_payments')
      .update(updates)
      .eq('id', po.id)
      .select('*, profile:profiles!subcontractor_payments_profile_id_fkey(id, name, email), project:projects(id, name, company:companies(name)), items:subcontractor_po_items(*, task:tasks(id, title))')
      .single();
    if (error) {
      alert(`${errorLabel}: ${error.message}`);
      return null;
    }
    if (data) {
      setSubcontractorPOs(prev => prev.map(row => row.id === po.id ? data : row));
      setSelectedSubcontractorPOId(current => current === po.id ? data.id : current);
    }
    return data;
  };

  const handleSendSubcontractorPO = async (po) => {
    const sentPO = await updateSubcontractorPO(po, { status: 'sent', sent_at: new Date().toISOString() }, 'Failed to send PO');
    if (!sentPO?.profile?.email) return;
    try {
      await sendEmail('subcontractor_po_sent', sentPO.profile.email, {
        poNumber: sentPO.po_number || 'Purchase Order',
        subcontractorName: sentPO.profile?.name || 'there',
        projectName: sentPO.project?.name || 'Subcontractor Work',
        companyName: sentPO.project?.company?.name || 'Fourge Branding',
        amount: `$${Number(sentPO.amount).toFixed(2)}`,
        dueDate: sentPO.due_date ? new Date(sentPO.due_date).toLocaleDateString() : 'Not set',
        terms: sentPO.terms || 'Net 15',
        scope: sentPO.items?.length
          ? sentPO.items.map(item => `${item.description} — $${Number(item.amount).toFixed(2)}`).join('\n')
          : sentPO.description,
        portalUrl: 'https://portal.fourgebranding.com/my-purchase-orders',
      });
    } catch (emailError) {
      console.error('Failed to email subcontractor PO:', emailError);
      alert(`PO was marked sent, but the email failed: ${emailError.message || 'unknown error'}`);
    }
  };

  const handleReadyToPaySubcontractorPO = (po) => {
    updateSubcontractorPO(po, { status: 'ready_to_pay' }, 'Failed to mark ready to pay');
  };

  const handleMarkSubcontractorPaid = async (po) => {
    const paidAt = new Date().toISOString().slice(0, 10);
    updateSubcontractorPO(po, { status: 'paid', paid_at: paidAt }, 'Failed to mark as paid');
  };

  const handleMarkSubInvoicePaid = async (invoice) => {
    setMarkingPaid(invoice.id);
    try {
      const paidAt = new Date().toISOString();
      const { error } = await supabase.from('subcontractor_invoices').update({ status: 'paid', paid_at: paidAt }).eq('id', invoice.id);
      if (error) throw error;
      const items = invoice.items || [];
      const total = items.reduce((s, i) => s + Number(i.unit_price || 0) * Number(i.quantity || 1), 0);
      let pdfBlob = null;
      try {
        pdfBlob = await generateSubcontractorPOPDF({
          po_number: invoice.invoice_number,
          status: 'paid',
          profile: invoice.profile,
          project: { name: 'Subcontractor Invoice', company: { name: 'Fourge Branding' } },
          date: invoice.created_at?.split('T')[0],
          due_date: paidAt.split('T')[0],
          amount: total,
          description: 'Payment for completed subcontractor work.',
          notes: invoice.notes,
          items: items.map((item, idx) => ({
            description: item.description,
            amount: Number(item.unit_price) * Number(item.quantity || 1),
            sort_order: item.sort_order ?? idx,
          })),
        }, { output: 'blob' });
      } catch (pdfErr) {
        console.error('PDF generation failed:', pdfErr);
      }
      if (invoice.profile?.email) {
        try {
          const attachments = pdfBlob ? [await blobToEmailAttachment(pdfBlob, `${invoice.invoice_number}-receipt.pdf`)] : [];
          await sendEmail('receipt_sent', invoice.profile.email, {
            invoiceNumber: invoice.invoice_number,
            billTo: invoice.profile.name || invoice.profile.email,
            total: total.toFixed(2),
            paidDate: new Date(paidAt).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }),
          }, attachments);
        } catch (emailErr) {
          console.error('Email failed:', emailErr);
          alert(`Marked paid, but email failed: ${emailErr.message || 'unknown error'}`);
        }
      }
      setSubInvoices(prev => prev.map(i => i.id === invoice.id ? { ...i, status: 'paid', paid_at: paidAt } : i));
    } catch (err) {
      alert(`Failed to mark as paid: ${err.message}`);
    }
    setMarkingPaid('');
  };

  const handleReopenSubcontractorPO = async (po) => {
    updateSubcontractorPO(po, { status: 'draft', paid_at: null, cancelled_at: null }, 'Failed to reopen PO');
  };

  const handleCancelSubcontractorPO = async (po) => {
    if (!window.confirm(`Cancel ${po.po_number || 'this PO'}?`)) return;
    updateSubcontractorPO(po, { status: 'cancelled', cancelled_at: new Date().toISOString() }, 'Failed to cancel PO');
  };

  const handleDeleteSubcontractorPO = async (id) => {
    if (!window.confirm('Delete this subcontractor PO?')) return;
    await supabase.from('subcontractor_payments').delete().eq('id', id);
    setSubcontractorPOs(prev => prev.filter(po => po.id !== id));
    setSelectedSubcontractorPOId(current => current === id ? '' : current);
  };

  const handleDownloadSubcontractorPO = async (po) => {
    try {
      await generateSubcontractorPOPDF(po);
    } catch (error) {
      console.error('Failed to download subcontractor PO:', error);
      alert(`Failed to download PO: ${error.message || 'unknown error'}`);
    }
  };

  const handleCPAExport = async () => {
    setExporting(true);
    try {
      const yearInvoices = invoices.filter(inv =>
        inv.status === 'paid' && new Date(inv.invoice_date).getFullYear() === exportYear
      );
      const yearExpenses = expenses.filter(exp =>
        new Date(exp.date).getFullYear() === exportYear
      );
      const yearSubcontractorExpenses = subcontractorPOs
        .filter(po => po.status === 'paid' && new Date(po.paid_at || po.date).getFullYear() === exportYear)
        .map(po => ({
          date: po.paid_at || po.date,
          category: 'Contractor',
          description: `Subcontractor: ${po.profile?.name || 'External'} — ${po.items?.length ? po.items.map(item => item.description).join('; ') : po.description}`,
          amount: po.amount,
          notes: [po.po_number, po.project?.name, po.notes || po.profile?.email || ''].filter(Boolean).join(' · '),
        }));
      const exportExpenses = [...yearExpenses, ...yearSubcontractorExpenses];
      if (!yearInvoices.length && !exportExpenses.length) {
        alert(`No data found for ${exportYear}.`);
        return;
      }
      const { data: allItems } = yearInvoices.length ? await supabase
        .from('invoice_items')
        .select('invoice_id, description')
        .in('invoice_id', yearInvoices.map(i => i.id)) : { data: [] };
      const itemsByInvoice = (allItems || []).reduce((acc, item) => {
        (acc[item.invoice_id] = acc[item.invoice_id] || []).push(item);
        return acc;
      }, {});
      await exportCPAPackage(yearInvoices, itemsByInvoice, exportExpenses, exportYear);
    } finally {
      setExporting(false);
    }
  };

  const paidYears = [...new Set(
    invoices.filter(i => i.status === 'paid').map(i => new Date(i.invoice_date).getFullYear())
  )].sort((a, b) => b - a);

  const companyNames = [...new Set(invoices.map(inv => inv.company?.name).filter(Boolean))].sort();
  const filtered = invoices.filter(inv => {
    if (filter !== 'all' && inv.status !== filter) return false;
    if (filterCompany && inv.company?.name !== filterCompany) return false;
    return true;
  });

  const totals = {
    all: invoices.reduce((s, i) => s + Number(i.total), 0),
    draft: invoices.filter(i => i.status === 'draft').reduce((s, i) => s + Number(i.total), 0),
    sent: invoices.filter(i => i.status === 'sent').reduce((s, i) => s + Number(i.total), 0),
    paid: invoices.filter(i => i.status === 'paid').reduce((s, i) => s + Number(i.total), 0),
    netReceived: invoices.filter(i => i.status === 'paid').reduce((s, i) => s + Number(i.total) - Number(i.stripe_fee || 0), 0),
  };

  const filteredExpenses = expenseFilter === 'all'
    ? expenses
    : expenses.filter(e => e.category === expenseFilter);
  const paidSubcontractorPOs = subcontractorPOs.filter(po => po.status === 'paid');
  const payableSubcontractorPOs = subcontractorPOs.filter(po => ['approved', 'ready_to_pay'].includes(po.status));
  const selectedSubcontractorPO = subcontractorPOs.find(po => po.id === selectedSubcontractorPOId);
  const subInvoiceItemTotal = (inv) => (inv.items || []).reduce((a, x) => a + Number(x.unit_price || 0) * Number(x.quantity || 1), 0);
  const paidSubInvoices = subInvoices.filter(i => i.status === 'paid');
  const totalPaidSubInvoices = paidSubInvoices.reduce((s, i) => s + subInvoiceItemTotal(i), 0);
  const totalPaidSubcontractors = paidSubcontractorPOs.reduce((s, po) => s + Number(po.amount), 0) + totalPaidSubInvoices;
  const totalPayableSubcontractorPOs = payableSubcontractorPOs.reduce((s, po) => s + Number(po.amount), 0);
  const totalPayableSubInvoices = subInvoices.filter(i => i.status === 'submitted').reduce((s, i) => s + subInvoiceItemTotal(i), 0);
  const totalPayableSubcontractors = totalPayableSubcontractorPOs + totalPayableSubInvoices;
  const payableSubcontractorCount = payableSubcontractorPOs.length + subInvoices.filter(i => i.status === 'submitted').length;
  const totalExpenses = filteredExpenses.reduce((s, e) => s + Number(e.amount), 0);
  const currentYear = new Date().getFullYear();
  const yearExpenses = expenses.filter(e => new Date(e.date).getFullYear() === currentYear);
  const currentYearExpenseTotal = yearExpenses.reduce((s, e) => s + Number(e.amount), 0);
  const currentYearPaidSubcontractorPOs = paidSubcontractorPOs
    .filter(po => new Date(po.paid_at || po.date).getFullYear() === currentYear)
    .reduce((s, po) => s + Number(po.amount), 0);
  const currentYearPaidSubInvoices = paidSubInvoices
    .filter(i => new Date(i.paid_at).getFullYear() === currentYear)
    .reduce((s, i) => s + subInvoiceItemTotal(i), 0);
  const currentYearTotalExpenses = currentYearExpenseTotal + currentYearPaidSubcontractorPOs + currentYearPaidSubInvoices;
  const revenue = totals.paid;
  const profit = totals.netReceived - expenses.reduce((s, e) => s + Number(e.amount), 0) - totalPaidSubcontractors;

  const chartYear = exportYear;
  const chartData = useMemo(() => MONTHS.map((month, mi) => {
    const paid = invoices
      .filter(inv => inv.status === 'paid' && new Date(inv.invoice_date).getFullYear() === chartYear && new Date(inv.invoice_date).getMonth() === mi)
      .reduce((s, inv) => s + Number(inv.total || 0), 0);
    const outstanding = invoices
      .filter(inv => inv.status === 'sent' && new Date(inv.invoice_date).getFullYear() === chartYear && new Date(inv.invoice_date).getMonth() === mi)
      .reduce((s, inv) => s + Number(inv.total || 0), 0);
    const exp = expenses
      .filter(e => new Date(e.date).getFullYear() === chartYear && new Date(e.date).getMonth() === mi)
      .reduce((s, e) => s + Number(e.amount || 0), 0);
    const subExp = subInvoices
      .filter(i => i.status === 'paid' && new Date(i.created_at).getFullYear() === chartYear && new Date(i.created_at).getMonth() === mi)
      .reduce((s, i) => s + (i.items || []).reduce((a, x) => a + Number(x.unit_price || 0) * Number(x.quantity || 1), 0), 0);
    const totalExp = exp + subExp;
    return { month, Revenue: +paid.toFixed(2), Outstanding: +outstanding.toFixed(2), Expenses: +totalExp.toFixed(2), Profit: +(paid - totalExp).toFixed(2) };
  }), [invoices, expenses, subInvoices, chartYear]);


  return (
    <Layout>
      <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      {/* Top row: 60% chart + 40% stat cards */}
      {(() => {
        const yr = chartData.reduce((s, m) => s + m.Revenue, 0);
        const yp = chartData.reduce((s, m) => s + m.Profit, 0);
        const ye = chartData.reduce((s, m) => s + m.Expenses, 0);
        const yo = chartData.reduce((s, m) => s + m.Outstanding, 0);
        const fmt = v => v >= 100000 ? `$${(v/1000).toFixed(0)}k` : `$${v.toFixed(2)}`;
        const CARD = { background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)' };
        const StatCard = ({ label, value, sub, iconBg, iconColor, iconSvg }) => (
          <div style={{ ...CARD, display: 'flex', alignItems: 'stretch', gap: 21, minHeight: 120 }}>
            <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
              <div style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 5 }}>{label}</div>
              <div style={{ flex: 1, display: 'flex', alignItems: 'center' }}>
                <div style={{ fontSize: 30, fontWeight: 400, color: 'var(--text-primary)', letterSpacing: -0.5, lineHeight: 1.1 }}>{value}</div>
              </div>
              {sub && <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 5 }}>{sub}</div>}
            </div>
            <div style={{ flexShrink: 0, display: 'flex', flexDirection: 'column', alignItems: 'flex-end', justifyContent: 'flex-start' }}>
              <div style={{ width: 27, height: 27, borderRadius: '50%', background: iconBg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke={iconColor} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">{iconSvg}</svg>
              </div>
            </div>
          </div>
        );
        return (
          <div style={{ display: 'grid', gridTemplateColumns: '3fr 2fr', gap: 24, flexShrink: 0 }}>
            <div style={{ ...CARD }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
                <span style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase' }}>Revenue Overview</span>
                <select className="filter-select" value={chartYear} onChange={e => setChartYear(Number(e.target.value))} style={{ width: 90, borderRadius: 8, fontSize: 11, fontWeight: 500 }}>
                  {(paidYears.length > 0 ? paidYears : [new Date().getFullYear()]).map(y => <option key={y} value={y}>{y}</option>)}
                </select>
              </div>
              <ResponsiveContainer width="100%" height={160}>
                <AreaChart data={chartData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>
                  <defs>
                    <linearGradient id="gc2Revenue" x1="0" y1="0" x2="0" y2="1"><stop offset="5%" stopColor="#F5A523" stopOpacity={0.25}/><stop offset="95%" stopColor="#F5A523" stopOpacity={0}/></linearGradient>
                    <linearGradient id="gc2Profit" x1="0" y1="0" x2="0" y2="1"><stop offset="5%" stopColor="#4ade80" stopOpacity={0.25}/><stop offset="95%" stopColor="#4ade80" stopOpacity={0}/></linearGradient>
                    <linearGradient id="gc2Expenses" x1="0" y1="0" x2="0" y2="1"><stop offset="5%" stopColor="#ef4444" stopOpacity={0.2}/><stop offset="95%" stopColor="#ef4444" stopOpacity={0}/></linearGradient>
                    <linearGradient id="gc2Outstanding" x1="0" y1="0" x2="0" y2="1"><stop offset="5%" stopColor="#60a5fa" stopOpacity={0.2}/><stop offset="95%" stopColor="#60a5fa" stopOpacity={0}/></linearGradient>
                  </defs>
                  <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" vertical={false} />
                  <XAxis dataKey="month" tick={{ fontSize: 11, fill: 'var(--text-muted)' }} axisLine={false} tickLine={false} />
                  <YAxis tick={{ fontSize: 11, fill: 'var(--text-muted)' }} axisLine={false} tickLine={false} tickFormatter={v => `$${v >= 1000 ? (v/1000).toFixed(0)+'k' : v}`} width={45} />
                  <Tooltip content={<FinancesChartTooltip year={chartYear} />} />
                  <Legend wrapperStyle={{ fontSize: 11, paddingTop: 8 }} />
                  <Area type="monotone" dataKey="Revenue" stroke="#F5A523" strokeWidth={2} fill="url(#gc2Revenue)" dot={false} activeDot={{ r: 4 }} />
                  <Area type="monotone" dataKey="Profit" stroke="#4ade80" strokeWidth={2} fill="url(#gc2Profit)" dot={false} activeDot={{ r: 4 }} />
                  <Area type="monotone" dataKey="Expenses" stroke="#ef4444" strokeWidth={2} fill="url(#gc2Expenses)" dot={false} activeDot={{ r: 4 }} />
                  <Area type="monotone" dataKey="Outstanding" stroke="#60a5fa" strokeWidth={2} fill="url(#gc2Outstanding)" dot={false} activeDot={{ r: 4 }} />
                </AreaChart>
              </ResponsiveContainer>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24, alignContent: 'start' }}>
              <StatCard label="Revenue" value={fmt(yr)} sub={`${chartYear} · paid invoices`} iconBg="rgba(245,165,35,0.15)" iconColor="#F5A523" iconSvg={<><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5,12 12,5 19,12"/></>} />
              <StatCard label="Outstanding" value={fmt(yo)} sub={`${chartYear} · sent & unpaid`} iconBg="rgba(96,165,250,0.15)" iconColor="#60a5fa" iconSvg={<><circle cx="12" cy="12" r="8"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></>} />
              <StatCard label="Expenses" value={fmt(ye)} sub={`${chartYear} · total spend`} iconBg="rgba(239,68,68,0.15)" iconColor="#ef4444" iconSvg={<><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19,12 12,19 5,12"/></>} />
              <StatCard label="Net Profit" value={fmt(yp)} sub={`${chartYear} · after expenses`} iconBg="rgba(74,222,128,0.15)" iconColor="#4ade80" iconSvg={<><polyline points="4,13 9,18 20,7"/></>} />
            </div>
          </div>
        );
      })()}

      <div style={{ display: 'grid', gridTemplateColumns: '7fr 3fr', gap: 24, marginTop: 24, marginBottom: 10, flexShrink: 0, alignItems: 'center' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, minHeight: 'var(--btn-height)' }}>
          {[
            { id: 'overview',       label: 'Overview' },
            { id: 'expenses',       label: 'Expenses' },
            { id: 'subcontractors', label: 'Subcontractors' },
            { id: 'invoices',       label: 'Invoices' },
            { id: 'legacy',         label: 'Legacy' },
          ].map(t => (
            <button
              key={t.id}
              type="button"
              onClick={() => setFinanceTab(t.id)}
              className={`section-tab-btn${financeTab === t.id ? ' is-active' : ''}`}
            >{t.label}</button>
          ))}
          {financeTab === 'expenses' && (
            <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 8 }}>
              <button className="btn btn-outline" onClick={() => { setEditingExpenseId(''); setNewExpense(blankExpense()); setExpensesError(''); setShowExpenseForm(true); }}>+ Expense</button>
            </div>
          )}
          {financeTab === 'invoices' && (
            <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 8 }}>
              <button className="btn btn-outline" onClick={() => navigate('/invoices/new')}>+ Invoice</button>
            </div>
          )}
        </div>
        <div />
      </div>

      {financeTab === 'overview' && (() => {
        const CARD = { background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)' };
        const TH = { fontSize: 10, fontWeight: 500, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.6, padding: '0 0 12px 0', border: 'none', background: 'transparent', textAlign: 'left' };
        const TD = { fontSize: 13, color: 'var(--text-primary)', padding: '5px 0', border: 'none', background: 'transparent', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
        const sortRows = (arr, key, dir, getter) => [...arr].sort((a, b) => {
          const av = getter(a, key), bv = getter(b, key);
          if (av < bv) return dir === 'asc' ? -1 : 1;
          if (av > bv) return dir === 'asc' ? 1 : -1;
          return 0;
        });
        const fmtDate = d => d ? new Date(d).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) : '—';
        const fmtAmt = v => `$${Number(v).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;

        const now = new Date();
        const curM = now.getMonth(), curY = now.getFullYear();
        const stepMonth = (p, dir) => dir === -1
          ? (p.month === 0 ? { month: 11, year: p.year - 1 } : { month: p.month - 1, year: p.year })
          : (p.month === 11 ? { month: 0, year: p.year + 1 } : { month: p.month + 1, year: p.year });
        const MonthNav = ({ m, setter }) => {
          const atCurrent = m.month === curM && m.year === curY;
          return (
            <div style={{ display: 'flex', alignItems: 'center', gap: 0, flexShrink: 0 }}>
              <button type="button" onClick={() => setter(p => stepMonth(p, -1))} style={{ background: 'none', border: 'none', padding: '0 6px', cursor: 'pointer', color: 'var(--text-secondary)', fontSize: 18, lineHeight: 1 }}>‹</button>
              <button type="button" onClick={() => setter(p => stepMonth(p, 1))} disabled={atCurrent} style={{ background: 'none', border: 'none', padding: '0 6px', cursor: atCurrent ? 'default' : 'pointer', color: 'var(--text-secondary)', fontSize: 18, lineHeight: 1, opacity: atCurrent ? 0.25 : 1 }}>›</button>
            </div>
          );
        };

        // Card 1: Expenses
        const m1 = ovMonth1.month, y1 = ovMonth1.year;
        const thisMonthExp = expenses.filter(e => { const d = new Date(e.date); return d.getFullYear() === y1 && d.getMonth() === m1; });
        const thisMonthTotal = thisMonthExp.reduce((s, e) => s + Number(e.amount || 0), 0);
        const thisCatTotals = CATEGORIES.map(cat => ({ cat, total: thisMonthExp.filter(e => e.category === cat).reduce((s, e) => s + Number(e.amount || 0), 0) })).filter(c => c.total > 0).sort((a, b) => b.total - a.total).slice(0, 4);

        // Card 2: Sub payments this month (paid sub invoices)
        const ovInvTotal = inv => (inv.items || []).reduce((s, i) => s + Number(i.unit_price || 0) * Number(i.quantity || 1), 0);
        const m2 = ovMonth2.month, y2 = ovMonth2.year;
        const pendingSubs = [...subInvoices.filter(i => { const d = new Date(i.paid_at || i.submitted_at); return d.getFullYear() === y2 && d.getMonth() === m2; })].sort((a, b) => new Date(b.paid_at || b.submitted_at) - new Date(a.paid_at || a.submitted_at));
        const pendingSubsTotal = pendingSubs.reduce((s, i) => s + ovInvTotal(i), 0);

        // Card 3: All invoices issued this month
        const m3 = ovMonth3.month, y3 = ovMonth3.year;
        const monthInvoices = [...invoices.filter(i => { const d = new Date(i.invoice_date); return d.getFullYear() === y3 && d.getMonth() === m3; })];
        const outstandingTotal = monthInvoices.reduce((s, i) => s + Number(i.total || 0), 0);

        const PIE_COLORS = ['#F5A523', '#4ade80', '#60a5fa', '#c084fc', '#f472b6', '#fb923c', '#34d399', '#a78bfa'];

        // pie by subcontractor
        const subPieData = Object.values(pendingSubs.reduce((acc, inv) => {
          const name = inv.profile?.name || 'Unknown';
          if (!acc[name]) acc[name] = { name, value: 0 };
          acc[name].value += ovInvTotal(inv);
          return acc;
        }, {})).sort((a, b) => b.value - a.value);

        // pie by company (outstanding invoices)
        const invPieData = Object.values(monthInvoices.reduce((acc, inv) => {
          const name = inv.company?.name || inv.bill_to || 'Unknown';
          if (!acc[name]) acc[name] = { name, value: 0 };
          acc[name].value += Number(inv.total || 0);
          return acc;
        }, {})).sort((a, b) => b.value - a.value);

        const PieTooltipContent = ({ active, payload }) => {
          if (!active || !payload?.length) return null;
          return (
            <div style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 4, padding: '8px 12px', fontSize: 12 }}>
              <div style={{ color: payload[0].payload.fill, fontWeight: 500 }}>{payload[0].name}</div>
              <div style={{ color: 'var(--text-primary)' }}>{fmtAmt(payload[0].value)}</div>
            </div>
          );
        };

        const PieLegend = ({ data, colors }) => (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginTop: 14 }}>
            {data.map((d, i) => (
              <div key={d.name} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
                  <div style={{ width: 8, height: 8, borderRadius: '50%', background: colors[i % colors.length], flexShrink: 0 }} />
                  <span style={{ fontSize: 12, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{d.name}</span>
                </div>
                <span style={{ fontSize: 12, color: 'var(--text-primary)', fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>{fmtAmt(d.value)}</span>
              </div>
            ))}
          </div>
        );

        return (
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 24, flex: 1, minHeight: 0 }}>
            {/* Card 1: This Month Expenses by category */}
            <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0, overflowY: 'auto' }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 5, flexShrink: 0 }}>
                <span style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase' }}>{MONTHS[m1]} {y1 !== curY ? y1 : ''} Expenses</span>
                <MonthNav m={ovMonth1} setter={setOvMonth1} />
              </div>
              <div style={{ fontSize: 30, fontWeight: 400, letterSpacing: -0.5, lineHeight: 1.1, color: '#ef4444', fontVariantNumeric: 'tabular-nums', marginBottom: 14, flexShrink: 0 }}>{fmtAmt(thisMonthTotal)}</div>
              <ResponsiveContainer width="100%" height={160}>
                <PieChart>
                  <Pie data={thisCatTotals.length ? thisCatTotals : [{ cat: 'None', total: 1 }]} dataKey="total" nameKey="cat" cx="50%" cy="50%" innerRadius={45} outerRadius={72} strokeWidth={0}>
                    {thisCatTotals.length ? thisCatTotals.map((_, i) => <Cell key={i} fill={PIE_COLORS[i % PIE_COLORS.length]} />) : <Cell fill="var(--border)" />}
                  </Pie>
                  {thisCatTotals.length > 0 && <Tooltip content={({ active, payload }) => {
                    if (!active || !payload?.length) return null;
                    return <div style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 4, padding: '8px 12px', fontSize: 12 }}><div style={{ color: payload[0].payload.fill, fontWeight: 500 }}>{payload[0].name}</div><div style={{ color: 'var(--text-primary)' }}>{fmtAmt(payload[0].value)}</div></div>;
                  }} />}
                </PieChart>
              </ResponsiveContainer>
              {thisCatTotals.length > 0 && <PieLegend data={thisCatTotals.map(c => ({ name: c.cat, value: c.total }))} colors={PIE_COLORS} />}
            </div>

            {/* Card 2: Pending Sub Payments by subcontractor */}
            <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0, overflowY: 'auto' }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 5, flexShrink: 0 }}>
                <span style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase' }}>{MONTHS[m2]} {y2 !== curY ? y2 : ''} Sub Payments</span>
                <MonthNav m={ovMonth2} setter={setOvMonth2} />
              </div>
              <div style={{ fontSize: 30, fontWeight: 400, letterSpacing: -0.5, lineHeight: 1.1, color: '#F5A523', fontVariantNumeric: 'tabular-nums', marginBottom: 14, flexShrink: 0 }}>{fmtAmt(pendingSubsTotal)}</div>
              <ResponsiveContainer width="100%" height={160}>
                <PieChart>
                  <Pie data={subPieData.length ? subPieData : [{ name: 'None', value: 1 }]} dataKey="value" nameKey="name" cx="50%" cy="50%" innerRadius={45} outerRadius={72} strokeWidth={0}>
                    {subPieData.length ? subPieData.map((_, i) => <Cell key={i} fill={PIE_COLORS[i % PIE_COLORS.length]} />) : <Cell fill="var(--border)" />}
                  </Pie>
                  {subPieData.length > 0 && <Tooltip content={({ active, payload }) => {
                    if (!active || !payload?.length) return null;
                    return <div style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 4, padding: '8px 12px', fontSize: 12 }}><div style={{ color: payload[0].payload.fill, fontWeight: 500 }}>{payload[0].name}</div><div style={{ color: 'var(--text-primary)' }}>{fmtAmt(payload[0].value)}</div></div>;
                  }} />}
                </PieChart>
              </ResponsiveContainer>
              {subPieData.length > 0 && <PieLegend data={subPieData} colors={PIE_COLORS} />}
            </div>

            {/* Card 3: Invoiced this month by company */}
            <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0, overflowY: 'auto' }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 5, flexShrink: 0 }}>
                <span style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase' }}>{MONTHS[m3]} {y3 !== curY ? y3 : ''} Invoiced</span>
                <MonthNav m={ovMonth3} setter={setOvMonth3} />
              </div>
              <div style={{ fontSize: 30, fontWeight: 400, letterSpacing: -0.5, lineHeight: 1.1, color: '#4ade80', fontVariantNumeric: 'tabular-nums', marginBottom: 14, flexShrink: 0 }}>{fmtAmt(outstandingTotal)}</div>
              <ResponsiveContainer width="100%" height={160}>
                <PieChart>
                  <Pie data={invPieData.length ? invPieData : [{ name: 'None', value: 1 }]} dataKey="value" nameKey="name" cx="50%" cy="50%" innerRadius={45} outerRadius={72} strokeWidth={0}>
                    {invPieData.length ? invPieData.map((_, i) => <Cell key={i} fill={PIE_COLORS[i % PIE_COLORS.length]} />) : <Cell fill="var(--border)" />}
                  </Pie>
                  {invPieData.length > 0 && <Tooltip content={({ active, payload }) => {
                    if (!active || !payload?.length) return null;
                    return <div style={{ background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 4, padding: '8px 12px', fontSize: 12 }}><div style={{ color: payload[0].payload.fill, fontWeight: 500 }}>{payload[0].name}</div><div style={{ color: 'var(--text-primary)' }}>{fmtAmt(payload[0].value)}</div></div>;
                  }} />}
                </PieChart>
              </ResponsiveContainer>
              {invPieData.length > 0 && <PieLegend data={invPieData} colors={PIE_COLORS} />}
            </div>
          </div>
        );
      })()}

      {financeTab === 'expenses' && (() => {
        const CARD = { background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)' };
        const TH = { fontSize: 10, fontWeight: 500, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.6, padding: '0 0 12px 0', border: 'none', background: 'transparent', textAlign: 'left' };
        const TD = { fontSize: 13, color: 'var(--text-primary)', padding: '5px 0', border: 'none', background: 'transparent', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
        const fmtDate = d => d ? new Date(d).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—';
        const fmtAmt = v => `$${Number(v).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
        const sortedExpenses = expSort(expenses, (exp, key) => {
          if (key === 'amount') return Number(exp.amount) || 0;
          if (key === 'date') return exp.date || '';
          return exp[key] || '';
        });
        const categoryTotals = CATEGORIES
          .map(cat => ({ cat, total: expenses.filter(e => e.category === cat).reduce((s, e) => s + Number(e.amount || 0), 0) }))
          .sort((a, b) => b.total - a.total);
        const grandTotal = expenses.reduce((s, e) => s + Number(e.amount || 0), 0);
        return (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 0, flex: 1, minHeight: 0 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '7fr 3fr', gap: 24, flex: 1, minHeight: 0 }}>
            {/* Left: expense list */}
            <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
              {expenses.length === 0 ? <div className="card-empty-center">No expenses</div> : (
                <div className="scrollbar-thin-theme table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
                  <table className="table-sticky-head" style={{ width: '100%', borderCollapse: 'collapse', tableLayout: 'fixed' }}>
                    <colgroup>
                      <col style={{ width: '14%' }} />
                      <col style={{ width: '34%' }} />
                      <col style={{ width: '16%' }} />
                      <col style={{ width: '24%' }} />
                      <col style={{ width: '12%' }} />
                    </colgroup>
                    <thead><tr>
                      <SortTh col="date"        sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle} style={TH}>Date</SortTh>
                      <SortTh col="description" sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle} style={TH}>Description</SortTh>
                      <SortTh col="category"    sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle} style={TH}>Category</SortTh>
                      <SortTh col="notes"       sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle} style={TH}>Notes</SortTh>
                      <SortTh col="amount"      sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle} style={{ ...TH, textAlign: 'right' }}>Amount</SortTh>
                    </tr></thead>
                    <tbody>{sortedExpenses.map(exp => (
                      <tr key={exp.id}>
                        <td style={{ ...TD, fontSize: 12 }}>{fmtDate(exp.date)}</td>
                        <td style={{ ...TD }}>
                          <button type="button" className="dashboard-inline-link" onClick={() => startEditExpense(exp)} style={{ fontSize: 13, fontWeight: 400 }}>
                            {exp.description || '—'}
                          </button>
                        </td>
                        <td style={{ ...TD, fontSize: 12 }}>{exp.category || '—'}</td>
                        <td style={{ ...TD, fontSize: 12 }}>{exp.notes || '—'}</td>
                        <td style={{ ...TD, textAlign: 'right', color: '#ef4444' }}>{fmtAmt(exp.amount)}</td>
                      </tr>
                    ))}</tbody>
                  </table>
                </div>
              )}
            </div>
            {/* Right: category breakdown */}
            <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
              <div style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 5, flexShrink: 0 }}>Category</div>
              <div style={{ fontSize: 30, fontWeight: 400, letterSpacing: -0.5, lineHeight: 1.1, color: '#ef4444', fontVariantNumeric: 'tabular-nums', marginBottom: 14, flexShrink: 0 }}>{fmtAmt(grandTotal)}</div>
              {categoryTotals.length === 0 ? <div className="card-empty-center">No expenses</div> : (
                <div className="scrollbar-thin-theme table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                    {categoryTotals.map(({ cat, total }) => {
                      const pct = grandTotal > 0 ? (total / grandTotal) * 100 : 0;
                      return (
                        <div key={cat}>
                          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 5 }}>
                            <span style={{ fontSize: 12, color: 'var(--text-primary)' }}>{cat}</span>
                            <span style={{ fontSize: 12, color: '#ef4444', fontVariantNumeric: 'tabular-nums' }}>{fmtAmt(total)}</span>
                          </div>
                          <div style={{ height: 4, borderRadius: 2, background: 'var(--border)', overflow: 'hidden' }}>
                            <div style={{ height: '100%', width: `${pct}%`, background: '#ef4444', borderRadius: 2, opacity: 0.7, transition: 'width 400ms ease' }} />
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>
              )}
            </div>
            </div>
          </div>
        );
      })()}

      {financeTab === 'subcontractors' && (() => {
        const CARD = { background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)' };
        const TH = { fontSize: 10, fontWeight: 500, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.6, padding: '0 0 12px 0', border: 'none', background: 'transparent', textAlign: 'left' };
        const TD = { fontSize: 13, color: 'var(--text-primary)', padding: '5px 0', border: 'none', background: 'transparent', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
        const fmtDate = d => d ? new Date(d).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—';
        const fmtAmt = v => `$${Number(v).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
        const subInvoiceStatusColor = { draft: 'not_started', submitted: 'in_progress', paid: 'client_approved' };
        const invTotal = inv => (inv.items || []).reduce((s, i) => s + Number(i.unit_price || 0) * Number(i.quantity || 1), 0);

        const yearFiltered = subInvoices;

        const sortedInvoices = subSort(yearFiltered, (inv, key) => {
          if (key === 'total') return invTotal(inv);
          if (key === 'subcontractor') return inv.profile?.name || '';
          if (key === 'submitted_at') return inv.submitted_at ? new Date(inv.submitted_at).getTime() : 0;
          if (key === 'paid_at') return inv.paid_at ? new Date(inv.paid_at).getTime() : 0;
          return inv[key] || '';
        });

        const bySubcontractor = Object.values(yearFiltered.reduce((acc, inv) => {
          const key = inv.profile?.id || 'unknown';
          if (!acc[key]) acc[key] = { name: inv.profile?.name || 'Unknown', invoices: [] };
          acc[key].invoices.push(inv);
          return acc;
        }, {})).map(g => ({
          ...g,
          total: g.invoices.reduce((s, i) => s + invTotal(i), 0),
          paid: g.invoices.filter(i => i.status === 'paid').reduce((s, i) => s + invTotal(i), 0),
          pending: g.invoices.filter(i => i.status === 'submitted').reduce((s, i) => s + invTotal(i), 0),
        })).sort((a, b) => b.total - a.total);

        const grandTotal = bySubcontractor.reduce((s, g) => s + g.total, 0);

        return (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 0, flex: 1, minHeight: 0 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '7fr 3fr', gap: 24, flex: 1, minHeight: 0 }}>
              {/* Left: invoice list */}
              <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
                {subInvoicesLoading ? (
                  <div style={{ fontSize: 13, color: 'var(--text-muted)' }}>Loading…</div>
                ) : subInvoicesError ? (
                  <div style={{ fontSize: 13, color: 'var(--danger)' }}>{subInvoicesError}</div>
                ) : yearFiltered.length === 0 ? (
                  <div className="card-empty-center">No invoices</div>
                ) : (
                  <div className="scrollbar-thin-theme table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
                    <table className="table-sticky-head" style={{ width: '100%', borderCollapse: 'collapse', tableLayout: 'fixed' }}>
                      <colgroup>
                        <col style={{ width: '14%' }} />
                        <col style={{ width: '26%' }} />
                        <col style={{ width: '16%' }} />
                        <col style={{ width: '16%' }} />
                        <col style={{ width: '14%' }} />
                        <col style={{ width: '14%' }} />
                      </colgroup>
                      <thead><tr>
                        <SortTh col="invoice_number" sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle} style={TH}>Invoice #</SortTh>
                        <SortTh col="subcontractor"  sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle} style={TH}>Subcontractor</SortTh>
                        <SortTh col="submitted_at"   sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle} style={TH}>Submitted</SortTh>
                        <SortTh col="paid_at"        sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle} style={TH}>Paid</SortTh>
                        <SortTh col="status"         sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle} style={TH}>Status</SortTh>
                        <SortTh col="total"          sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle} style={{ ...TH, textAlign: 'right' }}>Amount</SortTh>
                      </tr></thead>
                      <tbody>{sortedInvoices.map(inv => {
                        const total = invTotal(inv);
                        return (
                          <tr key={inv.id}>
                            <td style={{ ...TD }}>
                              <button type="button" className="table-link" onClick={() => navigate(`/sub-invoices/${inv.id}`)}>
                                {inv.invoice_number || '—'}
                              </button>
                            </td>
                            <td style={{ ...TD }}>{inv.profile?.name || '—'}</td>
                            <td style={{ ...TD, fontSize: 12, color: 'var(--text-muted)' }}>{fmtDate(inv.submitted_at)}</td>
                            <td style={{ ...TD, fontSize: 12, color: 'var(--text-muted)' }}>{fmtDate(inv.paid_at)}</td>
                            <td style={{ ...TD }}>
                              <StatusBadge
                                status={subInvoiceStatusColor[inv.status] || 'not_started'}
                                label={inv.status ? inv.status.charAt(0).toUpperCase() + inv.status.slice(1) : '—'}
                              />
                            </td>
                            <td style={{ ...TD, textAlign: 'right', color: inv.status === 'paid' ? '#4ade80' : inv.status === 'submitted' ? '#F5A523' : 'var(--text-primary)' }}>
                              {fmtAmt(total)}
                            </td>
                          </tr>
                        );
                      })}</tbody>
                    </table>
                  </div>
                )}
              </div>
              {/* Right: by subcontractor */}
              <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
                <div style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 5, flexShrink: 0 }}>Subcontractors</div>
                <div style={{ fontSize: 30, fontWeight: 400, letterSpacing: -0.5, lineHeight: 1.1, color: '#F5A523', fontVariantNumeric: 'tabular-nums', marginBottom: 14, flexShrink: 0 }}>{fmtAmt(grandTotal)}</div>
                {bySubcontractor.length === 0 ? <div className="card-empty-center">No data</div> : (
                  <div className="scrollbar-thin-theme table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                      {bySubcontractor.map(g => {
                        const pct = grandTotal > 0 ? (g.total / grandTotal) * 100 : 0;
                        return (
                          <div key={g.name}>
                            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 5 }}>
                              <span style={{ fontSize: 12, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: '65%' }}>{g.name}</span>
                              <span style={{ fontSize: 12, color: '#F5A523', fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>{fmtAmt(g.total)}</span>
                            </div>
                            <div style={{ height: 4, borderRadius: 2, background: 'var(--border)', overflow: 'hidden' }}>
                              <div style={{ height: '100%', width: `${pct}%`, background: '#F5A523', borderRadius: 2, opacity: 0.7, transition: 'width 400ms ease' }} />
                            </div>
                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 3 }}><span style={{ color: g.pending > 0 ? '#F5A523' : 'var(--text-muted)' }}>{fmtAmt(g.pending)} pending</span> · {fmtAmt(g.paid)} paid</div>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        );
      })()}

      {financeTab === 'invoices' && (() => {
        const CARD = { background: 'var(--card-bg)', border: '1px solid var(--border)', borderRadius: 8, padding: '18px 21px', backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)' };
        const TH = { fontSize: 10, fontWeight: 500, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.6, padding: '0 0 12px 0', border: 'none', background: 'transparent', textAlign: 'left' };
        const TD = { fontSize: 13, color: 'var(--text-primary)', padding: '5px 0', border: 'none', background: 'transparent', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
        const fmtDate = d => d ? new Date(d).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—';
        const fmtAmt = v => `$${Number(v).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
        const statusColor = { draft: 'not_started', sent: 'in_progress', paid: 'client_approved' };

        const sorted = invSort(invoices, (inv, key) => {
          if (key === 'total') return Number(inv.total) || 0;
          if (key === 'invoice_date' || key === 'due_date') return new Date(inv[key]).getTime();
          if (key === 'company') return inv.company?.name || '';
          return inv[key] || '';
        });

        const byCompany = Object.values(invoices.reduce((acc, inv) => {
          const name = inv.company?.name || inv.bill_to || 'Unknown';
          if (!acc[name]) acc[name] = { name, total: 0, paid: 0, outstanding: 0 };
          acc[name].total += Number(inv.total) || 0;
          if (inv.status === 'paid') acc[name].paid += Number(inv.total) || 0;
          else if (inv.status === 'sent') acc[name].outstanding += Number(inv.total) || 0;
          return acc;
        }, {})).sort((a, b) => b.total - a.total);

        const grandTotal = byCompany.reduce((s, g) => s + g.total, 0);

        return (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 0, flex: 1, minHeight: 0 }}>
            <div style={{ display: 'grid', gridTemplateColumns: '7fr 3fr', gap: 24, flex: 1, minHeight: 0 }}>
              <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
                {loading ? (
                  <div style={{ fontSize: 13, color: 'var(--text-muted)' }}>Loading…</div>
                ) : invoices.length === 0 ? (
                  <div className="card-empty-center">No invoices</div>
                ) : (
                  <div className="scrollbar-thin-theme table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
                    <table className="table-sticky-head" style={{ width: '100%', borderCollapse: 'collapse', tableLayout: 'fixed' }}>
                      <colgroup>
                        <col style={{ width: '20%' }} />
                        <col style={{ width: '27%' }} />
                        <col style={{ width: '15%' }} />
                        <col style={{ width: '15%' }} />
                        <col style={{ width: '13%' }} />
                        <col style={{ width: '10%' }} />
                      </colgroup>
                      <thead><tr>
                        <SortTh col="invoice_number" sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle} style={TH}>Invoice #</SortTh>
                        <SortTh col="company"        sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle} style={TH}>Company</SortTh>
                        <SortTh col="invoice_date"   sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle} style={TH}>Date</SortTh>
                        <SortTh col="due_date"       sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle} style={TH}>Due</SortTh>
                        <SortTh col="status"         sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle} style={{ ...TH, textAlign: 'center' }}>Status</SortTh>
                        <SortTh col="total"          sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle} style={{ ...TH, textAlign: 'right' }}>Total</SortTh>
                      </tr></thead>
                      <tbody>{sorted.map(inv => (
                        <tr key={inv.id}>
                          <td style={{ ...TD }}>
                            <button type="button" className="dashboard-inline-link" onClick={() => navigate(`/invoices/${inv.id}`)}>{inv.invoice_number}</button>
                          </td>
                          <td style={{ ...TD }}>
                            <button type="button" className="dashboard-inline-link" onClick={() => inv.company?.id && navigate(`/company/${inv.company.id}`)}>{inv.company?.name || inv.bill_to || '—'}</button>
                          </td>
                          <td style={{ ...TD, fontSize: 12 }}>{fmtDate(inv.invoice_date)}</td>
                          <td style={{ ...TD, fontSize: 12, color: inv.status !== 'paid' && new Date(inv.due_date) < new Date() ? 'var(--danger)' : 'var(--text-primary)' }}>{fmtDate(inv.due_date)}</td>
                          <td style={{ ...TD, textAlign: 'center' }}>
                            <StatusBadge
                              status={statusColor[inv.status] || 'not_started'}
                              label={invoiceStatusBadgeLabel(inv.status)}
                            />
                          </td>
                          <td style={{ ...TD, textAlign: 'right', color: inv.status === 'paid' ? '#4ade80' : inv.status === 'sent' ? '#F5A523' : 'var(--text-primary)' }}>
                            {fmtAmt(inv.total)}
                          </td>
                        </tr>
                      ))}</tbody>
                    </table>
                  </div>
                )}
              </div>
              <div style={{ ...CARD, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
                <div style={{ fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 5, flexShrink: 0 }}>Companies</div>
                <div style={{ fontSize: 30, fontWeight: 400, letterSpacing: -0.5, lineHeight: 1.1, color: '#4ade80', fontVariantNumeric: 'tabular-nums', marginBottom: 14, flexShrink: 0 }}>{fmtAmt(grandTotal)}</div>
                {byCompany.length === 0 ? <div className="card-empty-center">No data</div> : (
                  <div className="scrollbar-thin-theme table-scroll-hidden" style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                      {byCompany.map(g => {
                        const pct = grandTotal > 0 ? (g.total / grandTotal) * 100 : 0;
                        return (
                          <div key={g.name}>
                            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 5 }}>
                              <span style={{ fontSize: 12, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: '65%' }}>{g.name}</span>
                              <span style={{ fontSize: 12, color: '#4ade80', fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>{fmtAmt(g.total)}</span>
                            </div>
                            <div style={{ height: 4, borderRadius: 2, background: 'var(--border)', overflow: 'hidden' }}>
                              <div style={{ height: '100%', width: `${pct}%`, background: '#4ade80', borderRadius: 2, opacity: 0.7, transition: 'width 400ms ease' }} />
                            </div>
                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 3 }}><span style={{ color: g.outstanding > 0 ? '#F5A523' : 'var(--text-muted)' }}>{fmtAmt(g.outstanding)} outstanding</span> · {fmtAmt(g.paid)} paid</div>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        );
      })()}

      {financeTab === 'legacy' && <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 0, marginBottom: 16 }}>
        {[
          { id: 'invoices', label: 'INVOICES' },
          { id: 'expenses', label: 'EXPENSES' },
          { id: 'sub-invoices', label: 'SUBCONTRACTOR INVOICES' },
        ].map((t, i, arr) => (
          <span key={t.id} style={{ display: 'flex', alignItems: 'center' }}>
            <button
              type="button"
              onClick={() => setActiveTab(t.id)}
              style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, fontSize: 13, letterSpacing: 0.5, fontWeight: activeTab === t.id ? 600 : 400, color: activeTab === t.id ? 'var(--text-primary)' : 'var(--text-muted)', fontFamily: 'inherit' }}
            >{t.label}</button>
            {i < arr.length - 1 && <span style={{ margin: '0 10px', color: 'var(--border)', userSelect: 'none' }}>|</span>}
          </span>
        ))}
      </div>

      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 16, flexWrap: 'wrap' }}>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          {companyNames.length > 0 && activeTab === 'invoices' && (
            <select className="filter-select" style={{ width: 120 }} value={filterCompany} onChange={e => setFilterCompany(e.target.value)}>
              <option value="">All Companies</option>
              {companyNames.map(name => <option key={name} value={name}>{name}</option>)}
            </select>
          )}
        </div>
        {activeTab === 'invoices' && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <select className="filter-select" style={{ width: 120 }} value={filter} onChange={e => setFilter(e.target.value)}>
              <option value="all">All</option>
              <option value="draft">Draft</option>
              <option value="sent">Sent</option>
              <option value="paid">Paid</option>
            </select>
            <button className="btn btn-primary btn-sm" onClick={() => navigate('/invoices/new')}>+ New Invoice</button>
          </div>
        )}
        {activeTab === 'expenses' && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <select className="filter-select" style={{ width: 120 }} value={expenseFilter} onChange={e => setExpenseFilter(e.target.value)}>
              <option value="all">All</option>
              {CATEGORIES.filter(c => expenses.some(ex => ex.category === c)).map(c => (
                <option key={c} value={c}>{c}</option>
              ))}
            </select>
            <button className="btn btn-primary btn-sm" onClick={() => { setEditingExpenseId(''); setNewExpense(blankExpense()); setExpensesError(''); setShowExpenseForm(true); }}>+ Add Expense</button>
          </div>
        )}
      </div>

      {activeTab === 'invoices' && (
      <div>

        {/* ── Invoices ── */}
        <div>
          {loading ? (
            <p style={{ color: 'var(--text-muted)' }}>Loading...</p>
          ) : filtered.length === 0 ? (
            <p style={{ color: 'var(--text-muted)', fontSize: 13 }}>No invoices.</p>
          ) : (
            <div style={{ background: 'var(--card-bg)', borderRadius: 4, border: '1px solid var(--border)' }}>
              <table>
                <thead>
                  <tr>
                    <SortTh col="invoice_number" sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle}>Invoice #</SortTh>
                    <SortTh col="bill_to" sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle}>Bill To</SortTh>
                    <SortTh col="invoice_date" sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle}>Date</SortTh>
                    <SortTh col="due_date" sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle}>Due</SortTh>
                    <SortTh col="status" sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle}>Status</SortTh>
                    <SortTh col="total" sortKey={invSortKey} sortDir={invSortDir} onSort={invToggle}>Total</SortTh>
                  </tr>
                </thead>
                <tbody>
                  {invSort(filtered, (inv, key) => {
                    if (key === 'total') return Number(inv.total) || 0;
                    if (key === 'invoice_date' || key === 'due_date') return new Date(inv[key]).getTime();
                    return inv[key] || inv.company?.name || '';
                  }).map(inv => (
                    <tr key={inv.id} onClick={() => navigate(`/invoices/${inv.id}`)} style={{ cursor: 'pointer' }}>
                      <td style={{ fontWeight: 400 }}>{inv.invoice_number}</td>
                      <td style={{ fontWeight: 400 }}>{inv.bill_to || inv.company?.name}</td>
                      <td style={{ color: 'var(--text-muted)' }}>{new Date(inv.invoice_date).toLocaleDateString()}</td>
                      <td>
                        <span style={{ color: inv.status !== 'paid' && new Date(inv.due_date) < new Date() ? 'var(--danger)' : 'var(--text-muted)' }}>
                          {new Date(inv.due_date).toLocaleDateString()}
                        </span>
                      </td>
                      <td style={{ textAlign: 'center' }}>
                        <StatusBadge
                          status={statusColor[inv.status] || 'not_started'}
                          label={invoiceStatusBadgeLabel(inv.status)}
                        />
                      </td>
                      <td style={{ fontWeight: 400, color: 'var(--accent)' }}>${Number(inv.total).toFixed(2)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>
      )}

      {activeTab === 'expenses' && (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
        <div>
          <div style={{ marginBottom: 16 }}>

            {expensesLoading ? (
              <p style={{ color: 'var(--text-muted)', fontSize: 13 }}>Loading...</p>
            ) : expensesError ? (
              <p style={{ color: 'var(--danger)', fontSize: 13 }}>{expensesError}</p>
            ) : filteredExpenses.length === 0 ? (
              <p style={{ color: 'var(--text-muted)', fontSize: 13 }}>No expenses yet.</p>
            ) : (
              <div style={{ background: 'var(--card-bg)', borderRadius: 4, border: '1px solid var(--border)' }}>
                <table>
                  <thead>
                    <tr>
                      <SortTh col="date" sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle}>Date</SortTh>
                      <SortTh col="description" sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle}>Description</SortTh>
                      <SortTh col="category" sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle}>Category</SortTh>
                      <SortTh col="notes" sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle}>Notes</SortTh>
                      <SortTh col="amount" sortKey={expSortKey} sortDir={expSortDir} onSort={expToggle} style={{ textAlign: 'right' }}>Amount</SortTh>
                      <th style={{ width: 140, textAlign: 'right' }}>Action</th>
                    </tr>
                  </thead>
                  <tbody>
                    {expSort(filteredExpenses, (exp, key) => {
                      if (key === 'amount') return Number(exp.amount) || 0;
                      if (key === 'date') return exp.date || '';
                      return exp[key] || '';
                    }).map(exp => (
                      <tr key={exp.id} style={{ cursor: 'pointer' }} onClick={() => startEditExpense(exp)}>
                        <td>{new Date(exp.date).toLocaleDateString()}</td>
                        <td style={{ fontWeight: 400 }}>{exp.description}</td>
                        <td>{exp.category}</td>
                        <td style={{ color: 'var(--text-muted)' }}>
                          {exp.notes || exp.receipt_path ? (
                            <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                              <span>{exp.notes || '—'}</span>
                              {exp.receipt_path && (
                                <button
                                  className="btn btn-outline btn-sm"
                                  style={{ width: 'fit-content' }}
                                  onClick={e => { e.stopPropagation(); handleViewReceipt(exp); }}
                                >
                                  View Receipt
                                </button>
                              )}
                            </div>
                          ) : '—'}
                        </td>
                        <td style={{ textAlign: 'right', fontWeight: 400 }}>${Number(exp.amount).toFixed(2)}</td>
                        <td style={{ textAlign: 'right' }}>
                          <button
                            className="btn-icon btn-icon-danger"
                            title="Delete"
                            onClick={e => { e.stopPropagation(); handleDeleteExpense(exp.id); }}
                          >
                            ✕
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>

        </div>

      </div>
      )}

      {activeTab === 'sub-invoices' && (
      <div>
        <div style={{ marginBottom: 16 }}>
          {subInvoicesLoading ? (
            <p style={{ color: 'var(--text-muted)', fontSize: 13 }}>Loading...</p>
          ) : subInvoicesError ? (
            <p style={{ color: 'var(--danger)', fontSize: 13 }}>{subInvoicesError}</p>
          ) : subInvoices.length === 0 ? (
            <p style={{ color: 'var(--text-muted)', fontSize: 13 }}>No sub invoices yet.</p>
          ) : (
            <div style={{ background: 'var(--card-bg)', borderRadius: 4, border: '1px solid var(--border)' }}>
              <table>
                <thead>
                  <tr>
                    <SortTh col="invoice_number" sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle}>Invoice #</SortTh>
                    <SortTh col="subcontractor" sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle}>Subcontractor</SortTh>
                    <SortTh col="submitted_at" sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle}>Submitted</SortTh>
                    <SortTh col="status" sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle}>Status</SortTh>
                    <SortTh col="total" sortKey={subSortKey} sortDir={subSortDir} onSort={subToggle} style={{ textAlign: 'right' }}>Total</SortTh>
                    <th style={{ textAlign: 'right' }}>Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {subSort(subInvoices, (inv, key) => {
                    if (key === 'total') return (inv.items || []).reduce((s, i) => s + Number(i.unit_price || 0) * Number(i.quantity || 1), 0);
                    if (key === 'subcontractor') return inv.profile?.name || '';
                    if (key === 'submitted_at') return inv.submitted_at ? new Date(inv.submitted_at).getTime() : 0;
                    return inv[key] || '';
                  }).map(inv => {
                    const total = (inv.items || []).reduce((s, i) => s + Number(i.unit_price || 0) * Number(i.quantity || 1), 0);
                    const subInvoiceStatusColor = { draft: 'not_started', submitted: 'in_progress', paid: 'client_approved' };
                    return (
                      <tr key={inv.id} style={{ cursor: 'pointer' }} onClick={() => navigate(`/sub-invoices/${inv.id}`)}>
                        <td style={{ fontWeight: 400 }}>{inv.invoice_number}</td>
                        <td>
                          <div style={{ fontWeight: 400 }}>{inv.profile?.name || 'External'}</div>
                          <div style={{ color: 'var(--text-muted)', fontSize: 12 }}>{inv.profile?.email || '—'}</div>
                        </td>
                        <td style={{ color: 'var(--text-muted)' }}>{inv.submitted_at ? new Date(inv.submitted_at).toLocaleDateString() : '—'}</td>
                        <td>
                          <StatusBadge
                            status={subInvoiceStatusColor[inv.status] || 'not_started'}
                            label={inv.status ? inv.status.charAt(0).toUpperCase() + inv.status.slice(1) : '—'}
                          />
                        </td>
                        <td style={{ textAlign: 'right', fontWeight: 400, color: 'var(--accent)' }}>${total.toFixed(2)}</td>
                        <td />
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>
      )}
      </div>}{/* end legacy wrapper */}

      {showExpenseForm && (
        <div style={popupOverlayStyle} onClick={cancelExpenseEdit}>
          <div style={{ ...popupSurfaceStyle, background: 'var(--card-bg)', width: 'min(520px, 96vw)', maxHeight: 'calc(100vh - 48px)', overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 16 }} onClick={e => e.stopPropagation()}>
            <div style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: 0.8, color: 'var(--text-secondary)' }}>{editingExpenseId ? 'Edit Expense' : 'New Expense'}</div>
            <form onSubmit={handleAddExpense} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
                <div>
                  <div style={FIELD_LABEL_STYLE}>Date *</div>
                  <input type="date" required value={newExpense.date} onChange={e => setNewExpense(p => ({ ...p, date: e.target.value }))} style={{ fontSize: 13, color: 'var(--text-primary)', background: 'var(--card-bg-2)', border: '1px solid var(--border)', borderRadius: 6, padding: '6px 10px', width: '100%', fontFamily: 'inherit', boxSizing: 'border-box' }} />
                </div>
                <div>
                  <div style={FIELD_LABEL_STYLE}>Amount (USD) *</div>
                  <input type="number" step="0.01" min="0" required placeholder="0.00" value={newExpense.amount} onChange={e => setNewExpense(p => ({ ...p, amount: e.target.value }))} style={{ fontSize: 13, color: 'var(--text-primary)', background: 'var(--card-bg-2)', border: '1px solid var(--border)', borderRadius: 6, padding: '6px 10px', width: '100%', fontFamily: 'inherit', boxSizing: 'border-box' }} />
                </div>
              </div>
              <div>
                <div style={FIELD_LABEL_STYLE}>Description *</div>
                <input type="text" required placeholder="What was this for?" value={newExpense.description} onChange={e => setNewExpense(p => ({ ...p, description: e.target.value }))} style={{ fontSize: 13, color: 'var(--text-primary)', background: 'var(--card-bg-2)', border: '1px solid var(--border)', borderRadius: 6, padding: '6px 10px', width: '100%', fontFamily: 'inherit', boxSizing: 'border-box' }} />
              </div>
              <div>
                <div style={FIELD_LABEL_STYLE}>Category</div>
                <select value={newExpense.category} onChange={e => setNewExpense(p => ({ ...p, category: e.target.value }))} style={{ fontSize: 13, color: 'var(--text-primary)', background: 'var(--card-bg-2)', border: '1px solid var(--border)', borderRadius: 6, padding: '6px 10px', width: '100%', fontFamily: 'inherit', boxSizing: 'border-box' }}>
                  {CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
                </select>
              </div>
              <div>
                <div style={FIELD_LABEL_STYLE}>Notes</div>
                <input type="text" placeholder="Any extra details" value={newExpense.notes} onChange={e => setNewExpense(p => ({ ...p, notes: e.target.value }))} style={{ fontSize: 13, color: 'var(--text-primary)', background: 'var(--card-bg-2)', border: '1px solid var(--border)', borderRadius: 6, padding: '6px 10px', width: '100%', fontFamily: 'inherit', boxSizing: 'border-box' }} />
              </div>
              <div>
                <div style={FIELD_LABEL_STYLE}>Receipt / Photo</div>
                <input type="file" accept="image/*,.pdf" onChange={e => setNewExpense(p => ({ ...p, receipt: e.target.files?.[0] || null, removeReceipt: false }))} style={{ fontSize: 13, color: 'var(--text-primary)', background: 'var(--card-bg-2)', border: '1px solid var(--border)', borderRadius: 6, padding: '6px 10px', width: '100%', fontFamily: 'inherit', boxSizing: 'border-box' }} />
                {!newExpense.receipt && newExpense.receipt_path && (
                  <div style={{ marginTop: 6, display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>{newExpense.receipt_name || 'Existing receipt attached'}</span>
                    <button type="button" className="btn btn-outline" onClick={() => handleViewReceipt(newExpense)}>View</button>
                    <button type="button" className="btn btn-outline" style={{ color: 'var(--danger)' }} onClick={() => setNewExpense(p => ({ ...p, removeReceipt: true, receipt_path: null, receipt_name: null }))}>Remove</button>
                  </div>
                )}
                {newExpense.receipt && <div style={{ marginTop: 6, fontSize: 12, color: 'var(--text-muted)' }}>{newExpense.receipt.name}</div>}
              </div>
              {expensesError && <div style={{ fontSize: 12, color: 'var(--danger)' }}>{expensesError}</div>}
              <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', paddingTop: 4 }}>
                <button type="submit" className="btn btn-outline" disabled={addingExpense}>{addingExpense ? 'Saving…' : 'Save'}</button>
                <button type="button" className="btn btn-outline" onClick={cancelExpenseEdit}>Cancel</button>
              </div>
            </form>
          </div>
        </div>
      )}

      </div>{/* end flex column wrapper */}
    </Layout>
  );
}
