// ============================
// LELUSA — Finance Pages
// src/pages/finance-pages.jsx
// ============================

// Hardcoded UI enums: keys are the raw stored values, values are i18n keys for display.
const FINANCE_EXPENSE_CATEGORIES = {
  proveedor: 'admin_fin_cat_proveedor',
  material: 'admin_fin_cat_material',
  operativo: 'admin_fin_cat_operativo',
  renta: 'admin_fin_cat_renta',
  nomina: 'admin_fin_cat_nomina',
  marketing: 'admin_fin_cat_marketing',
  postres: 'admin_fin_cat_postres',
  otro: 'admin_fin_cat_otro',
};

const FINANCE_EXPENSE_COLORS = {
  proveedor: '#3A62C8',
  material: '#C8881A',
  operativo: '#9A4AC8',
  renta: '#2A8A50',
  nomina: '#C83A3A',
  marketing: '#C4899A',
  postres: '#C8881A',
  otro: '#9A8070',
};

const FINANCE_DEPARTMENTS = {
  all: 'admin_fin_dept_all',
  decoracion: 'admin_fin_dept_decoracion',
  postres: 'admin_fin_dept_postres',
  finanzas: 'admin_fin_dept_finanzas',
  operaciones: 'admin_fin_dept_operaciones',
  direccion: 'admin_fin_dept_direccion',
};

const FINANCE_DEPARTMENT_COLORS = {
  decoracion: '#C4899A',
  postres: '#C8881A',
  finanzas: '#3A62C8',
  operaciones: '#2A8A50',
  direccion: '#6F4E37',
};

const PAYMENT_METHOD_LABELS = {
  efectivo: 'admin_fin_method_efectivo',
  transferencia: 'admin_fin_method_transferencia',
  tarjeta: 'admin_fin_method_tarjeta',
  otro: 'admin_fin_method_otro',
};

const PAYMENT_SCHEME_TYPES = {
  unico: 'admin_fin_scheme_unico',
  anticipo_final: 'admin_fin_scheme_anticipo_final',
  plan: 'admin_fin_scheme_plan',
};

const FMT_MXN = (n) => `$${Number(n || 0).toLocaleString('es-MX', { minimumFractionDigits: 0, maximumFractionDigits: 0 })}`;
const TODAY = () => new Date().toISOString().slice(0, 10);

const FINANCE_INPUT = {
  width: '100%',
  padding: '10px 12px',
  border: '1px solid var(--border)',
  borderRadius: '10px',
  background: 'var(--bg-soft)',
  color: 'var(--text)',
  fontFamily: "'DM Sans', sans-serif",
  fontSize: '13px',
  outline: 'none',
};

function getPeriodRange(preset, custom) {
  const today = TODAY();
  if (preset === 'semana') {
    const d = new Date();
    const day = d.getDay() || 7;
    const mon = new Date(d);
    mon.setDate(d.getDate() - day + 1);
    const sun = new Date(mon);
    sun.setDate(mon.getDate() + 6);
    return { start: mon.toISOString().slice(0, 10), end: sun.toISOString().slice(0, 10) };
  }
  if (preset === 'mes') return { start: `${today.slice(0, 7)}-01`, end: today };
  if (preset === 'año') return { start: `${today.slice(0, 4)}-01-01`, end: today };
  return custom;
}

function getFinanceSummary(quotes, paymentSchemes, expenses, period, t) {
  const { start, end } = period;
  const inRange = (date) => date && date >= start && date <= end;

  let totalIncome = 0;
  (paymentSchemes || []).forEach((scheme) => {
    (scheme.payments || []).forEach((payment) => {
      if (payment.status === 'pagado' && payment.paidDate && inRange(payment.paidDate)) {
        totalIncome += Number(payment.amount || 0);
      }
    });
  });

  let totalExpenses = 0;
  (expenses || []).forEach((expense) => {
    if (inRange(expense.date)) totalExpenses += Number(expense.amount || 0);
  });

  let pendingReceivables = 0;
  (paymentSchemes || []).forEach((scheme) => {
    (scheme.payments || []).forEach((payment) => {
      if (payment.status !== 'pagado') pendingReceivables += Number(payment.amount || 0);
    });
  });

  const now = new Date();
  const monthlyData = [];
  for (let i = 11; i >= 0; i -= 1) {
    const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
    const monthKey = d.toISOString().slice(0, 7);
    const label = d.toLocaleDateString('es-MX', { month: 'short' });
    let income = 0;
    let expenseTotal = 0;

    (paymentSchemes || []).forEach((scheme) => {
      (scheme.payments || []).forEach((payment) => {
        if (payment.status === 'pagado' && payment.paidDate && payment.paidDate.startsWith(monthKey)) {
          income += Number(payment.amount || 0);
        }
      });
    });
    (expenses || []).forEach((expense) => {
      if (expense.date && expense.date.startsWith(monthKey)) expenseTotal += Number(expense.amount || 0);
    });
    monthlyData.push({ month: label, income, expenses: expenseTotal });
  }

  const expensesByCategory = {};
  Object.keys(FINANCE_EXPENSE_CATEGORIES).forEach((key) => { expensesByCategory[key] = 0; });
  (expenses || []).forEach((expense) => {
    if (inRange(expense.date)) {
      const category = expense.category || 'otro';
      expensesByCategory[category] = (expensesByCategory[category] || 0) + Number(expense.amount || 0);
    }
  });

  const transactions = [];
  (paymentSchemes || []).forEach((scheme) => {
    const quote = (quotes || []).find(q => q.id === scheme.quoteId);
    (scheme.payments || []).forEach((payment) => {
      if (payment.status === 'pagado' && payment.paidDate) {
        transactions.push({
          type: 'ingreso',
          date: payment.paidDate,
          description: `${payment.label || t('admin_fin_payment_default_label_single')} - ${quote ? quote.clientName : scheme.quoteId}`,
          amount: Number(payment.amount || 0),
        });
      }
    });
  });
  (expenses || []).forEach((expense) => {
    transactions.push({
      type: 'egreso',
      date: expense.date,
      description: expense.description,
      amount: Number(expense.amount || 0),
    });
  });
  transactions.sort((a, b) => (b.date || '').localeCompare(a.date || ''));

  return {
    totalIncome,
    totalExpenses,
    netProfit: totalIncome - totalExpenses,
    pendingReceivables,
    monthlyData,
    expensesByCategory,
    recentTransactions: transactions.slice(0, 10),
  };
}

function addDaysToIso(days) {
  const date = new Date();
  date.setDate(date.getDate() + days);
  return date.toISOString().slice(0, 10);
}

function getLinkedEvent(expense, events) {
  return (events || []).find(event => String(event.id) === String(expense.eventId)) || null;
}

function getQuoteDepartment(quote) {
  if (quote?.department) return quote.department;
  if (quote?.dessertRequest?.wanted && !quote?.designId) return 'postres';
  return 'decoracion';
}

function getExpenseDepartment(expense, events) {
  return expense?.department || getLinkedEvent(expense, events)?.department || (expense?.category === 'postres' ? 'postres' : 'operaciones');
}

function getFinanceIntelligence(quotes, paymentSchemes, expenses, events, period, department = 'all', t = (k) => k) {
  const { start, end } = period;
  const today = TODAY();
  const inRange = (date) => date && date >= start && date <= end;
  const departmentMatches = (dept) => department === 'all' || dept === department;

  const quoteById = new Map((quotes || []).map(quote => [quote.id, quote]));
  const eventBudgets = (events || [])
    .filter(event => ['confirmado', 'en preparacion', 'en montaje', 'completado', 'reservado'].includes(event.status))
    .filter(event => event.budget != null && departmentMatches(event.department || 'decoracion'));

  let collected = 0;
  let receivable = 0;
  let overdue = 0;
  const projection = { d30: 0, d60: 0, d90: 0 };

  (paymentSchemes || []).forEach((scheme) => {
    const quote = quoteById.get(scheme.quoteId);
    const quoteDepartment = getQuoteDepartment(quote);
    if (!departmentMatches(quoteDepartment)) return;
    (scheme.payments || []).forEach((payment) => {
      const amount = Number(payment.amount || 0);
      if (payment.status === 'pagado' && payment.paidDate && inRange(payment.paidDate)) collected += amount;
      if (payment.status !== 'pagado') {
        receivable += amount;
        if (payment.dueDate && payment.dueDate < today) overdue += amount;
        if (payment.dueDate && payment.dueDate >= today && payment.dueDate <= addDaysToIso(30)) projection.d30 += amount;
        if (payment.dueDate && payment.dueDate >= today && payment.dueDate <= addDaysToIso(60)) projection.d60 += amount;
        if (payment.dueDate && payment.dueDate >= today && payment.dueDate <= addDaysToIso(90)) projection.d90 += amount;
      }
    });
  });

  let approvedWithoutScheme = 0;
  (quotes || []).forEach((quote) => {
    if (!['aprobada', 'completada'].includes(quote.status)) return;
    if (!departmentMatches(getQuoteDepartment(quote))) return;
    if ((paymentSchemes || []).some(scheme => scheme.quoteId === quote.id)) return;
    approvedWithoutScheme += Number(quote.total || 0);
    if (quote.eventDate && quote.eventDate >= today && quote.eventDate <= addDaysToIso(90)) projection.d90 += Number(quote.total || 0);
  });

  eventBudgets.forEach((event) => {
    if (event.date && event.date >= today && event.date <= addDaysToIso(90)) projection.d90 += Number(event.budget || 0);
  });

  const filteredExpenses = (expenses || []).filter(expense => departmentMatches(getExpenseDepartment(expense, events)));
  const paidExpenses = filteredExpenses.filter(expense => expense.status !== 'pendiente' && inRange(expense.date));
  const pendingExpenses = filteredExpenses.filter(expense => expense.status === 'pendiente');
  const expenseTotal = paidExpenses.reduce((sum, expense) => sum + Number(expense.amount || 0), 0);
  const pendingExpenseTotal = pendingExpenses.reduce((sum, expense) => sum + Number(expense.amount || 0), 0);

  const departmentRows = ['decoracion', 'postres', 'finanzas', 'operaciones', 'direccion'].map((dept) => {
    let deptIncome = 0;
    let deptReceivable = 0;
    (paymentSchemes || []).forEach((scheme) => {
      const quote = quoteById.get(scheme.quoteId);
      if (getQuoteDepartment(quote) !== dept) return;
      (scheme.payments || []).forEach((payment) => {
        const amount = Number(payment.amount || 0);
        if (payment.status === 'pagado' && payment.paidDate && inRange(payment.paidDate)) deptIncome += amount;
        if (payment.status !== 'pagado') deptReceivable += amount;
      });
    });
    const deptExpenses = (expenses || [])
      .filter(expense => getExpenseDepartment(expense, events) === dept && inRange(expense.date))
      .reduce((sum, expense) => sum + Number(expense.amount || 0), 0);
    const deptEvents = (events || []).filter(event => (event.department || 'decoracion') === dept && event.date && event.date >= today).length;
    return {
      department: dept,
      label: FINANCE_DEPARTMENTS[dept],
      income: deptIncome,
      receivable: deptReceivable,
      expenses: deptExpenses,
      profit: deptIncome - deptExpenses,
      events: deptEvents,
    };
  });

  const recentReports = [
    ...(quotes || []).filter(quote => ['aprobada', 'completada'].includes(quote.status)).map(quote => ({
      type: 'Ingreso',
      department: getQuoteDepartment(quote),
      name: `${quote.clientName} · ${quote.designName || t('admin_fin_quote_fallback')}`,
      date: quote.eventDate,
      amount: Number(quote.total || 0),
      status: quote.status,
    })),
    ...filteredExpenses.map(expense => ({
      type: 'Egreso',
      department: getExpenseDepartment(expense, events),
      name: expense.description,
      date: expense.date,
      amount: Number(expense.amount || 0),
      status: expense.status,
    })),
  ].sort((a, b) => (b.date || '').localeCompare(a.date || '')).slice(0, 12);

  return {
    collected,
    receivable: receivable + approvedWithoutScheme,
    overdue,
    expenseTotal,
    pendingExpenseTotal,
    profit: collected - expenseTotal,
    margin: collected > 0 ? ((collected - expenseTotal) / collected) * 100 : 0,
    projection,
    departmentRows,
    recentReports,
  };
}

function FinanceKpi({ icon, label, value, sub, color }) {
  return (
    <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', padding: '18px', display: 'flex', gap: '14px', minHeight: '122px', boxShadow: '0 10px 30px rgba(58,42,32,0.05)' }}>
      <div style={{ width: '42px', height: '42px', borderRadius: '14px', background: `${color}18`, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
        <Icon name={icon} size={20} color={color} />
      </div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: '12px', color: 'var(--muted)', fontFamily: "'DM Sans', sans-serif", marginBottom: '6px' }}>{label}</div>
        <div style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: '30px', fontWeight: 700, color: 'var(--text)', lineHeight: 1 }}>{value}</div>
        {sub && <div style={{ fontSize: '12px', color: 'var(--muted)', marginTop: '6px' }}>{sub}</div>}
      </div>
    </div>
  );
}

function FinancePanel({ title, children, action }) {
  return (
    <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', padding: '18px', boxShadow: '0 10px 30px rgba(58,42,32,0.05)', minWidth: 0 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'center', marginBottom: 14 }}>
        <h3 style={{ margin: 0, fontSize: '14px', fontWeight: 800, color: 'var(--text)' }}>{title}</h3>
        {action}
      </div>
      {children}
    </div>
  );
}

function ProjectionBars({ projection }) {
  const { t } = window.ReactI18next.useTranslation();
  const rows = [
    { id: 'd30', label: 'admin_fin_projection_30', value: projection.d30 },
    { id: 'd60', label: 'admin_fin_projection_60', value: projection.d60 },
    { id: 'd90', label: 'admin_fin_projection_90', value: projection.d90 },
  ];
  const max = Math.max(...rows.map(row => Number(row.value || 0)), 1);
  return (
    <div style={{ display: 'grid', gap: 12 }}>
      {rows.map(row => (
        <div key={row.id}>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, marginBottom: 6, fontSize: 12, color: 'var(--muted)', fontWeight: 800 }}>
            <span>{t(row.label)}</span>
            <span style={{ color: 'var(--text)' }}>{FMT_MXN(row.value)}</span>
          </div>
          <div style={{ height: 10, borderRadius: 999, background: 'var(--bg-soft)', overflow: 'hidden' }}>
            <div style={{ width: `${Math.max(4, (Number(row.value || 0) / max) * 100)}%`, height: '100%', borderRadius: 999, background: 'linear-gradient(90deg, #2A8A50, #C8A87A)' }} />
          </div>
        </div>
      ))}
    </div>
  );
}

function DepartmentReport({ rows }) {
  const { t } = window.ReactI18next.useTranslation();
  const max = Math.max(...(rows || []).map(row => Math.max(row.income, row.expenses, row.receivable)), 1);
  return (
    <div style={{ display: 'grid', gap: 10 }}>
      {(rows || []).map(row => (
        <div key={row.department} style={{ border: '1px solid var(--border)', borderRadius: 14, padding: 12, background: 'var(--bg)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, alignItems: 'center', marginBottom: 9 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
              <span style={{ width: 10, height: 10, borderRadius: 999, background: FINANCE_DEPARTMENT_COLORS[row.department] || 'var(--primary)' }} />
              <strong style={{ fontSize: 13, color: 'var(--text)' }}>{t(row.label)}</strong>
            </div>
            <strong style={{ fontSize: 13, color: row.profit >= 0 ? '#2A8A50' : '#C83A3A' }}>{FMT_MXN(row.profit)}</strong>
          </div>
          <div style={{ display: 'grid', gap: 6 }}>
            {[
              { id: 'income', label: 'admin_fin_dept_income', value: row.income, color: '#2A8A50' },
              { id: 'expenses', label: 'admin_fin_dept_expenses', value: row.expenses, color: '#C83A3A' },
              { id: 'receivable', label: 'admin_fin_dept_receivable', value: row.receivable, color: '#C8881A' },
            ].map(({ id, label, value, color }) => (
              <div key={id} style={{ display: 'grid', gridTemplateColumns: '72px 1fr 82px', gap: 8, alignItems: 'center', fontSize: 11, color: 'var(--muted)' }}>
                <span>{t(label)}</span>
                <div style={{ height: 7, background: 'var(--bg-soft)', borderRadius: 99, overflow: 'hidden' }}>
                  <div style={{ width: `${Math.max(3, (Number(value || 0) / max) * 100)}%`, height: '100%', background: color, borderRadius: 99 }} />
                </div>
                <strong style={{ textAlign: 'right', color: 'var(--text)' }}>{FMT_MXN(value)}</strong>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function FinanceReportRows({ rows }) {
  const { t } = window.ReactI18next.useTranslation();
  if (!rows.length) return <div style={{ padding: 24, textAlign: 'center', color: 'var(--muted)', fontSize: 13 }}>{t('admin_fin_report_no_data')}</div>;
  return (
    <div style={{ display: 'grid', gap: 8 }}>
      {rows.map((row, index) => (
        <div key={`${row.type}-${row.date}-${index}`} style={{ display: 'grid', gridTemplateColumns: '86px 1fr 98px', gap: 10, alignItems: 'center', padding: '11px 0', borderBottom: index < rows.length - 1 ? '1px solid var(--border)' : 'none' }} className="form-row">
          <div>
            <div style={{ fontSize: 11, fontWeight: 900, color: row.type === 'Ingreso' ? '#2A8A50' : '#C83A3A' }}>{row.type === 'Ingreso' ? t('admin_fin_type_income') : t('admin_fin_type_expense')}</div>
            <div style={{ fontSize: 10.5, color: 'var(--muted)' }}>{FINANCE_DEPARTMENTS[row.department] ? t(FINANCE_DEPARTMENTS[row.department]) : row.department}</div>
          </div>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 12.5, fontWeight: 800, color: 'var(--text)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{row.name}</div>
            <div style={{ fontSize: 11, color: 'var(--muted)', marginTop: 2 }}>{row.date || t('admin_fin_no_date')} · {window.LelusaStatusLabel(row.status)}</div>
          </div>
          <strong style={{ textAlign: 'right', color: row.type === 'Ingreso' ? '#2A8A50' : '#C83A3A', fontSize: 13 }}>{row.type === 'Ingreso' ? '+' : '-'}{FMT_MXN(row.amount)}</strong>
        </div>
      ))}
    </div>
  );
}

function BarChart({ monthlyData }) {
  const { t } = window.ReactI18next.useTranslation();
  const W = 700;
  const H = 250;
  const padL = 58;
  const padB = 36;
  const padR = 18;
  const padT = 18;
  const chartW = W - padL - padR;
  const chartH = H - padT - padB;
  const maxVal = Math.max(...monthlyData.map(d => Math.max(d.income, d.expenses)), 1);
  const barW = chartW / monthlyData.length;
  const bw = Math.max(Math.floor(barW * 0.28), 4);

  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
      {[0, 0.25, 0.5, 0.75, 1].map((f) => {
        const y = padT + chartH - f * chartH;
        return (
          <g key={f}>
            <line x1={padL} y1={y} x2={W - padR} y2={y} stroke="#E8D8CC" strokeWidth="1" />
            <text x={padL - 8} y={y + 4} textAnchor="end" fontSize="10" fill="#8B7068">{FMT_MXN(f * maxVal)}</text>
          </g>
        );
      })}
      {monthlyData.map((d, i) => {
        const x = padL + i * barW + barW / 2;
        const incH = (d.income / maxVal) * chartH;
        const expH = (d.expenses / maxVal) * chartH;
        return (
          <g key={`${d.month}-${i}`}>
            <rect x={x - bw - 2} y={padT + chartH - incH} width={bw} height={incH} rx="2" fill="#2A8A50">
              <title>{t('admin_fin_chart_income_month', { month: d.month, amount: FMT_MXN(d.income) })}</title>
            </rect>
            <rect x={x + 2} y={padT + chartH - expH} width={bw} height={expH} rx="2" fill="#C83A3A">
              <title>{t('admin_fin_chart_expenses_month', { month: d.month, amount: FMT_MXN(d.expenses) })}</title>
            </rect>
            <text x={x} y={H - 10} textAnchor="middle" fontSize="10" fill="#8B7068">{d.month}</text>
          </g>
        );
      })}
      <line x1={padL} y1={padT + chartH} x2={W - padR} y2={padT + chartH} stroke="#8B7068" strokeWidth="1" />
      <rect x={padL} y="4" width="10" height="10" fill="#2A8A50" rx="2" />
      <text x={padL + 14} y="13" fontSize="10" fill="#8B7068">{t('admin_fin_chart_income')}</text>
      <rect x={padL + 78} y="4" width="10" height="10" fill="#C83A3A" rx="2" />
      <text x={padL + 92} y="13" fontSize="10" fill="#8B7068">{t('admin_fin_chart_expenses')}</text>
    </svg>
  );
}

function DonutChart({ data }) {
  const { t } = window.ReactI18next.useTranslation();
  const entries = Object.entries(data || {}).filter(([, value]) => Number(value) > 0);
  const total = entries.reduce((sum, [, value]) => sum + Number(value), 0);
  if (!total) {
    return (
      <div style={{ height: '230px', display: 'grid', placeItems: 'center', color: 'var(--muted)', fontSize: '13px' }}>
        {t('admin_fin_no_data')}
      </div>
    );
  }

  let offset = 0;
  const radius = 62;
  const circumference = 2 * Math.PI * radius;

  return (
    <div style={{ display: 'grid', gridTemplateColumns: '170px 1fr', gap: '18px', alignItems: 'center' }} className="dash-grid">
      <svg viewBox="0 0 160 160" style={{ width: '100%', height: 'auto' }}>
        <circle cx="80" cy="80" r={radius} fill="none" stroke="#E8D8CC" strokeWidth="22" />
        {entries.map(([category, value]) => {
          const dash = (Number(value) / total) * circumference;
          const strokeDasharray = `${dash} ${circumference - dash}`;
          const strokeDashoffset = -offset;
          offset += dash;
          return (
            <circle key={category} cx="80" cy="80" r={radius} fill="none" stroke={FINANCE_EXPENSE_COLORS[category] || '#9A8070'} strokeWidth="22" strokeDasharray={strokeDasharray} strokeDashoffset={strokeDashoffset} transform="rotate(-90 80 80)">
              <title>{`${t(FINANCE_EXPENSE_CATEGORIES[category])}: ${FMT_MXN(value)}`}</title>
            </circle>
          );
        })}
        <text x="80" y="75" textAnchor="middle" fontFamily="'DM Sans', sans-serif" fontSize="11" fill="#8B7068">{t('admin_fin_chart_total')}</text>
        <text x="80" y="94" textAnchor="middle" fontFamily="'Cormorant Garamond', serif" fontSize="20" fontWeight="700" fill="#3A2A20">{FMT_MXN(total)}</text>
      </svg>
      <div>
        {entries.map(([category, value]) => (
          <div key={category} style={{ display: 'flex', justifyContent: 'space-between', gap: '10px', alignItems: 'center', marginBottom: '9px' }}>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: '7px', fontSize: '12px', color: 'var(--text)' }}>
              <span style={{ width: '9px', height: '9px', borderRadius: '50%', background: FINANCE_EXPENSE_COLORS[category] || '#9A8070' }} />
              {FINANCE_EXPENSE_CATEGORIES[category] ? t(FINANCE_EXPENSE_CATEGORIES[category]) : category}
            </span>
            <strong style={{ fontSize: '12px', color: 'var(--text)' }}>{FMT_MXN(value)}</strong>
          </div>
        ))}
      </div>
    </div>
  );
}

function FinanceDashboard({ quotes, paymentSchemes, expenses, events }) {
  const { t } = window.ReactI18next.useTranslation();
  const [preset, setPreset] = React.useState('mes');
  const [custom, setCustom] = React.useState({ start: `${TODAY().slice(0, 7)}-01`, end: TODAY() });
  const [department, setDepartment] = React.useState('all');
  const period = getPeriodRange(preset, custom);
  const summary = getFinanceSummary(quotes, paymentSchemes, expenses, period, t);
  const intelligence = getFinanceIntelligence(quotes, paymentSchemes, expenses, events, period, department, t);

  return (
    <div>
      <div style={{ display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap', marginBottom: '18px' }}>
        {[
          ['semana', 'admin_fin_period_week'],
          ['mes', 'admin_fin_period_month'],
          ['año', 'admin_fin_period_year'],
          ['custom', 'admin_fin_period_range'],
        ].map(([key, label]) => (
          <button key={key} onClick={() => setPreset(key)}
            style={{ padding: '8px 14px', borderRadius: '999px', border: preset === key ? '1px solid var(--primary)' : '1px solid var(--border)', background: preset === key ? 'var(--primary-light)' : 'var(--card)', color: preset === key ? 'var(--primary-dark)' : 'var(--muted)', cursor: 'pointer', fontFamily: "'DM Sans', sans-serif", fontSize: '13px', fontWeight: 700 }}>
            {t(label)}
          </button>
        ))}
        {preset === 'custom' && (
          <>
            <input type="date" value={custom.start} onChange={e => setCustom({ ...custom, start: e.target.value })} style={{ ...FINANCE_INPUT, width: '150px' }} />
            <input type="date" value={custom.end} onChange={e => setCustom({ ...custom, end: e.target.value })} style={{ ...FINANCE_INPUT, width: '150px' }} />
          </>
        )}
        <select value={department} onChange={event => setDepartment(event.target.value)} style={{ ...FINANCE_INPUT, width: '190px', marginLeft: 'auto' }}>
          {Object.entries(FINANCE_DEPARTMENTS).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
        </select>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(190px, 1fr))', gap: '16px', marginBottom: '20px' }}>
        <FinanceKpi icon="trendingUp" label={t('admin_fin_kpi_income_collected')} value={FMT_MXN(intelligence.collected)} sub={t('admin_fin_kpi_period_sub', { start: period.start, end: period.end })} color="#2A8A50" />
        <FinanceKpi icon="trendingDown" label={t('admin_fin_kpi_expenses_paid')} value={FMT_MXN(intelligence.expenseTotal)} sub={t('admin_fin_kpi_pending_sub', { amount: FMT_MXN(intelligence.pendingExpenseTotal) })} color="#C83A3A" />
        <FinanceKpi icon="barChart" label={t('admin_fin_kpi_net_profit')} value={FMT_MXN(intelligence.profit)} sub={t('admin_fin_kpi_margin_sub', { margin: Math.round(intelligence.margin) })} color={intelligence.profit >= 0 ? '#2A8A50' : '#C83A3A'} />
        <FinanceKpi icon="clock" label={t('admin_fin_kpi_receivable')} value={FMT_MXN(intelligence.receivable)} sub={t('admin_fin_kpi_overdue_sub', { amount: FMT_MXN(intelligence.overdue) })} color="#C8881A" />
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.35fr) minmax(280px, 0.65fr)', gap: '18px', alignItems: 'start' }} className="dash-grid">
        <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', padding: '18px', boxShadow: '0 10px 30px rgba(58,42,32,0.05)' }}>
          <h3 style={{ margin: '0 0 12px', fontSize: '14px', fontWeight: 800, color: 'var(--text)' }}>{t('admin_fin_chart_income_vs_expenses')}</h3>
          <BarChart monthlyData={summary.monthlyData} />
        </div>
        <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', padding: '18px', boxShadow: '0 10px 30px rgba(58,42,32,0.05)' }}>
          <h3 style={{ margin: '0 0 12px', fontSize: '14px', fontWeight: 800, color: 'var(--text)' }}>{t('admin_fin_chart_expenses_by_category')}</h3>
          <DonutChart data={summary.expensesByCategory} />
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(280px, 0.75fr)', gap: '18px', alignItems: 'start', marginTop: 18 }} className="dash-grid">
        <FinancePanel title={t('admin_fin_panel_dept_result')}>
          <DepartmentReport rows={department === 'all' ? intelligence.departmentRows : intelligence.departmentRows.filter(row => row.department === department)} />
        </FinancePanel>
        <FinancePanel title={t('admin_fin_panel_income_projection')}>
          <ProjectionBars projection={intelligence.projection} />
          <div style={{ marginTop: 14, padding: 12, borderRadius: 14, background: 'var(--bg-soft)', color: 'var(--muted)', fontSize: 12, lineHeight: 1.5 }}>
            {t('admin_fin_projection_note')}
          </div>
        </FinancePanel>
      </div>

      <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', marginTop: '18px', overflow: 'hidden', boxShadow: '0 10px 30px rgba(58,42,32,0.05)' }}>
        <div style={{ padding: '16px 18px', borderBottom: '1px solid var(--border)', fontSize: '14px', fontWeight: 800, color: 'var(--text)' }}>{t('admin_fin_recent_movements')}</div>
        {summary.recentTransactions.length === 0 ? (
          <div style={{ padding: '28px', textAlign: 'center', color: 'var(--muted)', fontSize: '13px' }}>{t('admin_fin_no_movements')}</div>
        ) : summary.recentTransactions.map((item, index) => (
          <div key={`${item.type}-${item.date}-${index}`} style={{ display: 'grid', gridTemplateColumns: '100px 1fr 120px', gap: '12px', padding: '13px 18px', alignItems: 'center', borderBottom: index < summary.recentTransactions.length - 1 ? '1px solid var(--border)' : 'none' }} className="form-row">
            <span style={{ fontSize: '12px', color: 'var(--muted)' }}>{item.date}</span>
            <span style={{ fontSize: '13px', color: 'var(--text)', fontWeight: 600 }}>{item.description}</span>
            <span style={{ textAlign: 'right', color: item.type === 'ingreso' ? '#2A8A50' : '#C83A3A', fontWeight: 800 }}>{item.type === 'ingreso' ? '+' : '-'}{FMT_MXN(item.amount)}</span>
          </div>
        ))}
      </div>

      <FinancePanel title={t('admin_fin_panel_operative_report')} action={<span style={{ fontSize: 11, color: 'var(--muted)', fontWeight: 800 }}>{t(FINANCE_DEPARTMENTS[department])}</span>}>
        <FinanceReportRows rows={intelligence.recentReports} />
      </FinancePanel>
    </div>
  );
}

function createPaymentsForQuote(quote, type, current = []) {
  const total = Number(quote.total || quote.basePrice || 0);
  const date = quote.eventDate || TODAY();
  if (current.length) return current;
  if (type === 'anticipo_final') {
    return [
      { id: Date.now(), label: 'Anticipo', amount: Math.round(total * 0.5), dueDate: TODAY(), status: 'pendiente', method: 'transferencia', paidDate: '' },
      { id: Date.now() + 1, label: 'Pago final', amount: total - Math.round(total * 0.5), dueDate: date, status: 'pendiente', method: 'transferencia', paidDate: '' },
    ];
  }
  if (type === 'plan') {
    const first = Math.round(total / 3);
    const second = Math.round(total / 3);
    return [
      { id: Date.now(), label: 'Pago 1', amount: first, dueDate: TODAY(), status: 'pendiente', method: 'transferencia', paidDate: '' },
      { id: Date.now() + 1, label: 'Pago 2', amount: second, dueDate: TODAY(), status: 'pendiente', method: 'transferencia', paidDate: '' },
      { id: Date.now() + 2, label: 'Pago 3', amount: total - first - second, dueDate: date, status: 'pendiente', method: 'transferencia', paidDate: '' },
    ];
  }
  return [{ id: Date.now(), label: 'Pago unico', amount: total, dueDate: date, status: 'pendiente', method: 'transferencia', paidDate: '' }];
}

function PaymentSchemeModal({ quote, scheme, open, onClose, onSave }) {
  const { t } = window.ReactI18next.useTranslation();
  const [type, setType] = React.useState(scheme?.type || 'anticipo_final');
  const [payments, setPayments] = React.useState(() => createPaymentsForQuote(quote || {}, scheme?.type || 'anticipo_final', scheme?.payments || []));

  React.useEffect(() => {
    if (!open || !quote) return;
    setType(scheme?.type || 'anticipo_final');
    setPayments(createPaymentsForQuote(quote, scheme?.type || 'anticipo_final', scheme?.payments || []));
  }, [open, quote?.id, scheme?.id]);

  const total = Number(quote?.total || 0);
  const sum = payments.reduce((acc, payment) => acc + Number(payment.amount || 0), 0);
  const valid = Math.abs(sum - total) < 1;

  const changeType = (nextType) => {
    setType(nextType);
    setPayments(createPaymentsForQuote(quote, nextType, []));
  };

  const updatePayment = (id, patch) => {
    setPayments(current => current.map(payment => payment.id === id ? { ...payment, ...patch } : payment));
  };

  const addRow = () => {
    setPayments(current => [...current, { id: Date.now(), label: `Pago ${current.length + 1}`, amount: 0, dueDate: quote?.eventDate || TODAY(), status: 'pendiente', method: 'transferencia', paidDate: '' }]);
  };

  return (
    <AdminModal
      open={open}
      title={t('admin_fin_scheme_modal_title')}
      subtitle={quote ? t('admin_fin_scheme_modal_subtitle', { id: quote.id, client: quote.clientName, total: FMT_MXN(total) }) : ''}
      onClose={onClose}
      width="900px"
      footer={(
        <>
          <Btn variant="ghost" onClick={onClose}>{t('admin_fin_cancel')}</Btn>
          <Btn disabled={!valid} onClick={() => onSave({ quoteId: quote.id, type, payments })}>{t('admin_fin_save_scheme')}</Btn>
        </>
      )}
    >
      <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
        <AdminField label={t('admin_fin_scheme_type')}>
          <select value={type} onChange={event => changeType(event.target.value)} style={FINANCE_INPUT}>
            {Object.entries(PAYMENT_SCHEME_TYPES).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
          </select>
        </AdminField>

        <div style={{ display: 'flex', justifyContent: 'space-between', gap: '12px', alignItems: 'center', padding: '12px 14px', borderRadius: '12px', background: valid ? '#DCF5E6' : '#FFF3DC', color: valid ? '#2A8A50' : '#C8881A', fontSize: '13px', fontWeight: 800 }}>
          <span>{t('admin_fin_total_scheduled', { amount: FMT_MXN(sum) })}</span>
          <span>{t('admin_fin_total_quote', { amount: FMT_MXN(total) })}</span>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
          {payments.map((payment, index) => (
            <div key={payment.id} style={{ display: 'grid', gridTemplateColumns: '1.1fr 120px 150px 130px 36px', gap: '10px', alignItems: 'center' }} className="form-row">
              <input value={payment.label} onChange={event => updatePayment(payment.id, { label: event.target.value })} placeholder={t('admin_fin_payment_label_ph')} style={FINANCE_INPUT} />
              <input type="number" min="0" value={payment.amount} onChange={event => updatePayment(payment.id, { amount: Number(event.target.value || 0) })} style={FINANCE_INPUT} />
              <input type="date" value={payment.dueDate || ''} onChange={event => updatePayment(payment.id, { dueDate: event.target.value })} style={FINANCE_INPUT} />
              <select value={payment.status || 'pendiente'} onChange={event => updatePayment(payment.id, { status: event.target.value, paidDate: event.target.value === 'pagado' ? (payment.paidDate || TODAY()) : '' })} style={FINANCE_INPUT}>
                <option value="pendiente">{t('admin_fin_status_pendiente')}</option>
                <option value="pagado">{t('admin_fin_status_pagado')}</option>
              </select>
              <button onClick={() => setPayments(current => current.filter((_, i) => i !== index))} title={t('admin_fin_delete_payment')} style={{ width: '34px', height: '34px', border: '1px solid var(--border)', borderRadius: '10px', background: 'var(--card)', cursor: 'pointer' }}>
                <Icon name="trash" size={14} color="#C83A3A" />
              </button>
            </div>
          ))}
        </div>
        <Btn variant="ghost" size="sm" onClick={addRow} style={{ alignSelf: 'flex-start' }}>
          <Icon name="plus" size={14} /> {t('admin_fin_add_payment')}
        </Btn>
      </div>
    </AdminModal>
  );
}

function RegisterPaymentModal({ quote, scheme, payment, open, onClose, onSave }) {
  const { t } = window.ReactI18next.useTranslation();
  const [form, setForm] = React.useState({ paidDate: TODAY(), method: 'transferencia', notes: '' });

  React.useEffect(() => {
    if (!open) return;
    setForm({
      paidDate: payment?.paidDate || TODAY(),
      method: payment?.method || 'transferencia',
      notes: payment?.notes || '',
    });
  }, [open, payment?.id]);

  return (
    <AdminModal
      open={open}
      title={t('admin_fin_register_payment')}
      subtitle={payment ? t('admin_fin_register_subtitle', { label: payment.label, amount: FMT_MXN(payment.amount), client: quote?.clientName || scheme?.quoteId }) : ''}
      onClose={onClose}
      width="520px"
      footer={(
        <>
          <Btn variant="ghost" onClick={onClose}>{t('admin_fin_cancel')}</Btn>
          <Btn onClick={() => onSave({ ...payment, ...form, status: 'pagado' })}>{t('admin_fin_confirm_payment')}</Btn>
        </>
      )}
    >
      <div style={{ display: 'grid', gap: '14px' }}>
        <AdminField label={t('admin_fin_payment_date')}>
          <input type="date" value={form.paidDate} onChange={event => setForm({ ...form, paidDate: event.target.value })} style={FINANCE_INPUT} />
        </AdminField>
        <AdminField label={t('admin_fin_method')}>
          <select value={form.method} onChange={event => setForm({ ...form, method: event.target.value })} style={FINANCE_INPUT}>
            {Object.entries(PAYMENT_METHOD_LABELS).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
          </select>
        </AdminField>
        <AdminField label={t('admin_fin_notes')}>
          <textarea value={form.notes} onChange={event => setForm({ ...form, notes: event.target.value })} rows={3} style={{ ...FINANCE_INPUT, resize: 'vertical' }} />
        </AdminField>
      </div>
    </AdminModal>
  );
}

function FinancePayments({ quotes, paymentSchemes, onSchemeChange, onPaymentReceived }) {
  const { t } = window.ReactI18next.useTranslation();
  const [editingQuote, setEditingQuote] = React.useState(null);
  const [receiving, setReceiving] = React.useState(null);
  const billableQuotes = (quotes || []).filter(quote => ['aprobada', 'completada'].includes(quote.status));

  const findScheme = (quoteId) => (paymentSchemes || []).find(scheme => scheme.quoteId === quoteId);

  return (
    <div>
      {billableQuotes.length === 0 ? (
        <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', padding: '34px', textAlign: 'center', color: 'var(--muted)' }}>
          {t('admin_fin_no_billable_quotes')}
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(310px, 1fr))', gap: '16px' }}>
          {billableQuotes.map((quote) => {
            const scheme = findScheme(quote.id);
            const payments = scheme?.payments || [];
            const paid = payments.reduce((sum, payment) => sum + (payment.status === 'pagado' ? Number(payment.amount || 0) : 0), 0);
            return (
              <div key={quote.id} style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', padding: '18px', boxShadow: '0 10px 30px rgba(58,42,32,0.05)' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: '12px', marginBottom: '12px' }}>
                  <div>
                    <div style={{ fontSize: '12px', color: 'var(--muted)', marginBottom: '4px' }}>{quote.id}</div>
                    <h3 style={{ margin: 0, fontFamily: "'Cormorant Garamond', serif", fontSize: '22px', color: 'var(--text)' }}>{quote.clientName}</h3>
                    <div style={{ fontSize: '12px', color: 'var(--muted)', marginTop: '3px' }}>{quote.eventDate || t('admin_fin_no_date')} - {quote.designName}</div>
                  </div>
                  <div style={{ textAlign: 'right' }}>
                    <div style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: '24px', fontWeight: 700, color: 'var(--primary)' }}>{FMT_MXN(quote.total)}</div>
                    <div style={{ fontSize: '12px', color: '#2A8A50', fontWeight: 700 }}>{t('admin_fin_collected_label', { amount: FMT_MXN(paid) })}</div>
                  </div>
                </div>

                {payments.length > 0 ? (
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', marginBottom: '14px' }}>
                    {payments.map(payment => (
                      <button key={payment.id} onClick={() => payment.status === 'pagado' ? null : setReceiving({ quote, scheme, payment })}
                        style={{ border: `1px solid ${payment.status === 'pagado' ? '#2A8A50' : '#C8881A'}40`, background: payment.status === 'pagado' ? '#DCF5E6' : '#FFF3DC', color: payment.status === 'pagado' ? '#2A8A50' : '#C8881A', borderRadius: '999px', padding: '6px 10px', cursor: payment.status === 'pagado' ? 'default' : 'pointer', fontSize: '12px', fontWeight: 800 }}>
                        {payment.label}: {FMT_MXN(payment.amount)}
                      </button>
                    ))}
                  </div>
                ) : (
                  <p style={{ margin: '0 0 14px', color: 'var(--muted)', fontSize: '13px' }}>{t('admin_fin_no_scheme')}</p>
                )}

                <Btn variant="ghost" size="sm" onClick={() => setEditingQuote(quote)}>
                  <Icon name="settings" size={14} />
                  {t('admin_fin_configure_payments')}
                </Btn>
              </div>
            );
          })}
        </div>
      )}

      <PaymentSchemeModal
        open={!!editingQuote}
        quote={editingQuote}
        scheme={editingQuote ? findScheme(editingQuote.id) : null}
        onClose={() => setEditingQuote(null)}
        onSave={(schemeData) => { onSchemeChange(editingQuote.id, schemeData); setEditingQuote(null); }}
      />

      <RegisterPaymentModal
        open={!!receiving}
        quote={receiving?.quote}
        scheme={receiving?.scheme}
        payment={receiving?.payment}
        onClose={() => setReceiving(null)}
        onSave={(paymentData) => { onPaymentReceived(receiving.scheme.id, receiving.payment.id, paymentData); setReceiving(null); }}
      />
    </div>
  );
}

function ExpenseModal({ open, expense, quotes, events, onSave, onClose, onDelete }) {
  const { t } = window.ReactI18next.useTranslation();
  const isNew = !expense;
  const [confirmDelete, setConfirmDelete] = React.useState(false);
  const [form, setForm] = React.useState({
    date: TODAY(),
    amount: '',
    category: 'proveedor',
    department: 'operaciones',
    description: '',
    vendor: '',
    invoiceRef: '',
    invoiceFile: '',
    eventId: '',
    quoteId: '',
    paymentMethod: 'transferencia',
    status: 'pagado',
    notes: '',
  });

  React.useEffect(() => {
    if (!open) return;
    setConfirmDelete(false);
    setForm({
      date: expense?.date || TODAY(),
      amount: expense?.amount ?? '',
      category: expense?.category || 'proveedor',
      department: expense?.department || 'operaciones',
      description: expense?.description || '',
      vendor: expense?.vendor || '',
      invoiceRef: expense?.invoiceRef || '',
      invoiceFile: expense?.invoiceFile || '',
      eventId: expense?.eventId || '',
      quoteId: expense?.quoteId || '',
      paymentMethod: expense?.paymentMethod || 'transferencia',
      status: expense?.status || 'pagado',
      notes: expense?.notes || '',
    });
  }, [open, expense?.id]);

  const set = (key, value) => setForm(current => ({ ...current, [key]: value }));
  const valid = form.description.trim() && Number(form.amount) > 0;

  const save = () => {
    if (!valid) return;
    onSave({
      ...form,
      amount: Number(form.amount || 0),
      eventId: form.eventId ? Number(form.eventId) : null,
      quoteId: form.quoteId || null,
    });
  };

  return (
    <AdminModal
      open={open}
      title={isNew ? t('admin_fin_expense_new_title') : t('admin_fin_expense_edit_title')}
      subtitle={t('admin_fin_expense_modal_subtitle')}
      onClose={onClose}
      width="820px"
      footer={(
        <div style={{ display: 'flex', justifyContent: 'space-between', width: '100%', gap: '10px', flexWrap: 'wrap' }}>
          <div>
            {!isNew && !confirmDelete && <Btn variant="danger" onClick={() => setConfirmDelete(true)}>{t('admin_fin_delete')}</Btn>}
            {!isNew && confirmDelete && (
              <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
                <span style={{ color: '#C83A3A', fontSize: '13px', fontWeight: 700 }}>{t('admin_fin_confirm')}</span>
                <Btn variant="danger" onClick={() => onDelete(expense.id)}>{t('admin_fin_yes_delete')}</Btn>
                <Btn variant="ghost" onClick={() => setConfirmDelete(false)}>{t('admin_fin_cancel')}</Btn>
              </div>
            )}
          </div>
          <div style={{ display: 'flex', gap: '10px' }}>
            <Btn variant="ghost" onClick={onClose}>{t('admin_fin_cancel')}</Btn>
            <Btn disabled={!valid} onClick={save}>{isNew ? t('admin_fin_save_expense') : t('admin_fin_save_changes')}</Btn>
          </div>
        </div>
      )}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '14px' }} className="form-row">
        <AdminField label={t('admin_fin_field_description')} full>
          <input value={form.description} onChange={event => set('description', event.target.value)} placeholder={t('admin_fin_field_description_ph')} style={FINANCE_INPUT} />
        </AdminField>
        <AdminField label={t('admin_fin_field_date')}>
          <input type="date" value={form.date} onChange={event => set('date', event.target.value)} style={FINANCE_INPUT} />
        </AdminField>
        <AdminField label={t('admin_fin_field_amount')}>
          <input type="number" min="0" value={form.amount} onChange={event => set('amount', event.target.value)} style={FINANCE_INPUT} />
        </AdminField>
        <AdminField label={t('admin_fin_field_category')}>
          <select value={form.category} onChange={event => set('category', event.target.value)} style={FINANCE_INPUT}>
            {Object.entries(FINANCE_EXPENSE_CATEGORIES).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
          </select>
        </AdminField>
        <AdminField label={t('admin_fin_field_department')}>
          <select value={form.department} onChange={event => set('department', event.target.value)} style={FINANCE_INPUT}>
            {Object.entries(FINANCE_DEPARTMENTS).filter(([key]) => key !== 'all').map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
          </select>
        </AdminField>
        <AdminField label={t('admin_fin_field_status')}>
          <select value={form.status} onChange={event => set('status', event.target.value)} style={FINANCE_INPUT}>
            <option value="pagado">{t('admin_fin_status_pagado')}</option>
            <option value="pendiente">{t('admin_fin_status_pendiente')}</option>
          </select>
        </AdminField>
        <AdminField label={t('admin_fin_field_vendor')}>
          <input value={form.vendor} onChange={event => set('vendor', event.target.value)} style={FINANCE_INPUT} />
        </AdminField>
        <AdminField label={t('admin_fin_field_payment_method')}>
          <select value={form.paymentMethod} onChange={event => set('paymentMethod', event.target.value)} style={FINANCE_INPUT}>
            {Object.entries(PAYMENT_METHOD_LABELS).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
          </select>
        </AdminField>
        <AdminField label={t('admin_fin_field_invoice_ref')}>
          <input value={form.invoiceRef} onChange={event => set('invoiceRef', event.target.value)} style={FINANCE_INPUT} />
        </AdminField>
        <AdminField label={t('admin_fin_field_invoice_file')}>
          <input value={form.invoiceFile} onChange={event => set('invoiceFile', event.target.value)} placeholder="/uploads/facturas/archivo.pdf" style={FINANCE_INPUT} />
        </AdminField>
        <AdminField label={t('admin_fin_field_linked_quote')}>
          <select value={form.quoteId || ''} onChange={event => set('quoteId', event.target.value)} style={FINANCE_INPUT}>
            <option value="">{t('admin_fin_no_quote')}</option>
            {(quotes || []).map(quote => <option key={quote.id} value={quote.id}>{quote.id} - {quote.clientName}</option>)}
          </select>
        </AdminField>
        <AdminField label={t('admin_fin_field_linked_event')}>
          <select value={form.eventId || ''} onChange={event => set('eventId', event.target.value)} style={FINANCE_INPUT}>
            <option value="">{t('admin_fin_no_event')}</option>
            {(events || []).map(event => <option key={event.id} value={event.id}>{event.name} - {event.date}</option>)}
          </select>
        </AdminField>
        <AdminField label={t('admin_fin_field_notes')} full>
          <textarea value={form.notes} onChange={event => set('notes', event.target.value)} rows={3} style={{ ...FINANCE_INPUT, resize: 'vertical' }} />
        </AdminField>
      </div>
    </AdminModal>
  );
}

function FinanceExpenses({ expenses, quotes, events, onAdd, onEdit, onDelete }) {
  const { t } = window.ReactI18next.useTranslation();
  const [search, setSearch] = React.useState('');
  const [catFilter, setCatFilter] = React.useState('todas');
  const [deptFilter, setDeptFilter] = React.useState('all');
  const [statusFilter, setStatusFilter] = React.useState('todas');
  const [periodFilter, setPeriodFilter] = React.useState('todo');
  const [modal, setModal] = React.useState(null);
  const today = TODAY();

  const periodStart = periodFilter === 'mes' ? `${today.slice(0, 7)}-01` : periodFilter === 'año' ? `${today.slice(0, 4)}-01-01` : null;
  const filtered = (expenses || []).filter((expense) => {
    const q = search.toLowerCase();
    if (q && !`${expense.description || ''} ${expense.vendor || ''}`.toLowerCase().includes(q)) return false;
    if (catFilter !== 'todas' && expense.category !== catFilter) return false;
    if (deptFilter !== 'all' && getExpenseDepartment(expense, events) !== deptFilter) return false;
    if (statusFilter !== 'todas' && expense.status !== statusFilter) return false;
    if (periodStart && expense.date < periodStart) return false;
    return true;
  });
  const totalFiltered = filtered.reduce((sum, expense) => sum + Number(expense.amount || 0), 0);
  const byCategory = {};
  Object.keys(FINANCE_EXPENSE_CATEGORIES).forEach((key) => { byCategory[key] = 0; });
  filtered.forEach((expense) => { byCategory[expense.category || 'otro'] += Number(expense.amount || 0); });

  const findLink = (expense) => {
    if (expense.quoteId) return expense.quoteId;
    const event = (events || []).find(item => item.id === expense.eventId);
    return event ? event.name : '';
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '10px', marginBottom: '18px', flexWrap: 'wrap', alignItems: 'center' }}>
        <input value={search} onChange={event => setSearch(event.target.value)} placeholder={t('admin_fin_search_ph')} style={{ ...FINANCE_INPUT, flex: '1 1 220px' }} />
        <select value={catFilter} onChange={event => setCatFilter(event.target.value)} style={{ ...FINANCE_INPUT, width: '190px' }}>
          <option value="todas">{t('admin_fin_filter_all_categories')}</option>
          {Object.entries(FINANCE_EXPENSE_CATEGORIES).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
        </select>
        <select value={deptFilter} onChange={event => setDeptFilter(event.target.value)} style={{ ...FINANCE_INPUT, width: '170px' }}>
          {Object.entries(FINANCE_DEPARTMENTS).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
        </select>
        <select value={statusFilter} onChange={event => setStatusFilter(event.target.value)} style={{ ...FINANCE_INPUT, width: '150px' }}>
          <option value="todas">{t('admin_fin_filter_all_statuses')}</option>
          <option value="pagado">{t('admin_fin_status_pagado')}</option>
          <option value="pendiente">{t('admin_fin_status_pendiente')}</option>
        </select>
        <select value={periodFilter} onChange={event => setPeriodFilter(event.target.value)} style={{ ...FINANCE_INPUT, width: '150px' }}>
          <option value="todo">{t('admin_fin_filter_period_all')}</option>
          <option value="mes">{t('admin_fin_filter_period_month')}</option>
          <option value="año">{t('admin_fin_filter_period_year')}</option>
        </select>
        <Btn onClick={() => setModal('new')}><Icon name="plus" size={14} />{t('admin_fin_expense_btn')}</Btn>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) 260px', gap: '16px', alignItems: 'start' }} className="dash-grid">
        <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', overflow: 'hidden', boxShadow: '0 10px 30px rgba(58,42,32,0.05)' }}>
          {filtered.length === 0 ? (
            <div style={{ padding: '36px', textAlign: 'center', color: 'var(--muted)', fontSize: '13px' }}>{t('admin_fin_expenses_empty')}</div>
          ) : filtered.map((expense, index) => (
            <div key={expense.id} style={{ display: 'grid', gridTemplateColumns: '92px 1fr 140px 110px 90px', gap: '12px', alignItems: 'center', padding: '14px 16px', borderBottom: index < filtered.length - 1 ? '1px solid var(--border)' : 'none' }} className="form-row">
              <div style={{ fontSize: '12px', color: 'var(--muted)' }}>{expense.date}</div>
              <div>
                <div style={{ fontSize: '13px', color: 'var(--text)', fontWeight: 800 }}>{expense.description}</div>
                <div style={{ fontSize: '11px', color: 'var(--muted)', marginTop: '3px' }}>{[FINANCE_DEPARTMENTS[getExpenseDepartment(expense, events)] ? t(FINANCE_DEPARTMENTS[getExpenseDepartment(expense, events)]) : null, expense.vendor, findLink(expense)].filter(Boolean).join(' - ')}</div>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: '7px', fontSize: '12px', color: 'var(--text)' }}>
                <span style={{ width: '9px', height: '9px', borderRadius: '50%', background: FINANCE_EXPENSE_COLORS[expense.category] || '#9A8070' }} />
                {FINANCE_EXPENSE_CATEGORIES[expense.category] ? t(FINANCE_EXPENSE_CATEGORIES[expense.category]) : expense.category}
              </div>
              <div style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: '18px', fontWeight: 700, textAlign: 'right' }}>{FMT_MXN(expense.amount)}</div>
              <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '6px', alignItems: 'center' }}>
                <span style={{ fontSize: '11px', color: expense.status === 'pagado' ? '#2A8A50' : '#C8881A', fontWeight: 800 }}>{expense.status === 'pagado' ? t('admin_fin_status_pagado') : t('admin_fin_status_pendiente')}</span>
                <button onClick={() => setModal(expense)} title={t('admin_fin_edit')} style={{ border: 'none', background: 'transparent', cursor: 'pointer', padding: '4px' }}>
                  <Icon name="edit" size={15} color="var(--primary)" />
                </button>
              </div>
            </div>
          ))}
        </div>

        <div style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: '18px', padding: '18px', boxShadow: '0 10px 30px rgba(58,42,32,0.05)' }}>
          <div style={{ fontSize: '12px', fontWeight: 800, color: 'var(--muted)', textTransform: 'uppercase', marginBottom: '12px' }}>{t('admin_fin_by_category')}</div>
          {Object.entries(byCategory).filter(([, value]) => value > 0).map(([category, value]) => (
            <div key={category} style={{ display: 'flex', justifyContent: 'space-between', gap: '10px', marginBottom: '9px', fontSize: '12px' }}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: '7px' }}>
                <span style={{ width: '8px', height: '8px', borderRadius: '50%', background: FINANCE_EXPENSE_COLORS[category] }} />
                {t(FINANCE_EXPENSE_CATEGORIES[category])}
              </span>
              <strong>{FMT_MXN(value)}</strong>
            </div>
          ))}
          {Object.values(byCategory).every(value => value === 0) && <div style={{ color: 'var(--muted)', fontSize: '12px' }}>{t('admin_fin_no_results')}</div>}
          <div style={{ marginTop: '12px', paddingTop: '12px', borderTop: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <strong style={{ fontSize: '13px' }}>{t('admin_fin_total')}</strong>
            <strong style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: '20px' }}>{FMT_MXN(totalFiltered)}</strong>
          </div>
        </div>
      </div>

      <ExpenseModal
        open={!!modal}
        expense={modal === 'new' ? null : modal}
        quotes={quotes}
        events={events}
        onClose={() => setModal(null)}
        onSave={(data) => { modal === 'new' ? onAdd(data) : onEdit(modal.id, data); setModal(null); }}
        onDelete={(id) => { onDelete(id); setModal(null); }}
      />
    </div>
  );
}

function FinanceReports({ quotes, paymentSchemes, expenses, events }) {
  const { t } = window.ReactI18next.useTranslation();
  const [department, setDepartment] = React.useState('all');
  const period = getPeriodRange('año', { start: `${TODAY().slice(0, 4)}-01-01`, end: TODAY() });
  const intelligence = getFinanceIntelligence(quotes, paymentSchemes, expenses, events, period, department, t);
  const reportRows = department === 'all'
    ? intelligence.departmentRows
    : intelligence.departmentRows.filter(row => row.department === department);

  return (
    <div style={{ display: 'grid', gap: 18 }}>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
        <select value={department} onChange={event => setDepartment(event.target.value)} style={{ ...FINANCE_INPUT, width: '210px' }}>
          {Object.entries(FINANCE_DEPARTMENTS).map(([key, label]) => <option key={key} value={key}>{t(label)}</option>)}
        </select>
        <span style={{ fontSize: 12, color: 'var(--muted)', fontWeight: 800 }}>{t('admin_fin_annual_report', { year: TODAY().slice(0, 4) })}</span>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 14 }}>
        <FinanceKpi icon="trendingUp" label={t('admin_fin_kpi_collected')} value={FMT_MXN(intelligence.collected)} sub={t('admin_fin_kpi_collected_sub')} color="#2A8A50" />
        <FinanceKpi icon="clock" label={t('admin_fin_kpi_receivable')} value={FMT_MXN(intelligence.receivable)} sub={t('admin_fin_kpi_receivable_sub')} color="#C8881A" />
        <FinanceKpi icon="trendingDown" label={t('admin_fin_kpi_expenses')} value={FMT_MXN(intelligence.expenseTotal)} sub={t('admin_fin_kpi_expenses_sub')} color="#C83A3A" />
        <FinanceKpi icon="barChart" label={t('admin_fin_kpi_profit')} value={FMT_MXN(intelligence.profit)} sub={t('admin_fin_kpi_margin_sub', { margin: Math.round(intelligence.margin) })} color={intelligence.profit >= 0 ? '#2A8A50' : '#C83A3A'} />
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(280px, 0.8fr)', gap: 18 }} className="dash-grid">
        <FinancePanel title={t('admin_fin_panel_dept_table')}>
          <DepartmentReport rows={reportRows} />
        </FinancePanel>
        <FinancePanel title={t('admin_fin_panel_projected_flow')}>
          <ProjectionBars projection={intelligence.projection} />
        </FinancePanel>
      </div>

      <FinancePanel title={t('admin_fin_panel_business_report')}>
        <FinanceReportRows rows={intelligence.recentReports} />
      </FinancePanel>
    </div>
  );
}

function FinancePage() {
  const { t } = window.ReactI18next.useTranslation();
  const { quotes, events, paymentSchemes, expenses } = window.LelusaStore.useBusinessData();
  const [tab, setTab] = React.useState('dashboard');

  const handleSchemeChange = (quoteId, schemeData) => {
    const existing = (paymentSchemes || []).find(scheme => scheme.quoteId === quoteId);
    if (existing) {
      window.LelusaStore.updatePaymentScheme(existing.id, schemeData);
    } else {
      window.LelusaStore.addPaymentScheme(schemeData);
    }
  };

  const handlePaymentReceived = (schemeId, paymentId, paymentData) => {
    const scheme = (paymentSchemes || []).find(item => item.id === schemeId);
    if (!scheme) return;
    const updatedPayments = (scheme.payments || []).map(payment => (
      payment.id === paymentId ? { ...payment, ...paymentData } : payment
    ));
    window.LelusaStore.updatePaymentScheme(schemeId, { payments: updatedPayments });
  };

  const tabs = [
    { key: 'dashboard', label: t('admin_fin_tab_dashboard'), icon: 'barChart' },
    { key: 'payments', label: t('admin_fin_tab_payments'), icon: 'trendingUp' },
    { key: 'expenses', label: t('admin_fin_tab_expenses'), icon: 'trendingDown' },
    { key: 'reports', label: t('admin_fin_tab_reports'), icon: 'fileText' },
  ];

  return (
    <AdminLayout title={t('admin_fin_title')} subtitle={t('admin_fin_subtitle')}>
      <div className="lel-admin-scroll-tabs" style={{ display: 'flex', gap: '6px', marginBottom: '24px', borderBottom: '1px solid var(--border)', overflowX: 'auto', maxWidth: '100%' }}>
        {tabs.map(item => (
          <button key={item.key} onClick={() => setTab(item.key)}
            style={{ display: 'flex', alignItems: 'center', gap: '7px', padding: '10px 18px', borderRadius: '10px 10px 0 0', border: 'none', borderBottom: tab === item.key ? '2px solid var(--primary)' : '2px solid transparent', background: tab === item.key ? 'var(--primary-light)' : 'transparent', color: tab === item.key ? 'var(--primary-dark)' : 'var(--muted)', cursor: 'pointer', fontSize: '14px', fontFamily: "'DM Sans', sans-serif", fontWeight: tab === item.key ? 800 : 500, whiteSpace: 'nowrap' }}>
            <Icon name={item.icon} size={16} color={tab === item.key ? 'var(--primary-dark)' : 'var(--muted)'} />
            {item.label}
          </button>
        ))}
      </div>

      {tab === 'dashboard' && <FinanceDashboard quotes={quotes} paymentSchemes={paymentSchemes} expenses={expenses} events={events} />}
      {tab === 'payments' && (
        <FinancePayments
          quotes={quotes}
          paymentSchemes={paymentSchemes}
          onSchemeChange={handleSchemeChange}
          onPaymentReceived={handlePaymentReceived}
        />
      )}
      {tab === 'expenses' && (
        <FinanceExpenses
          expenses={expenses}
          quotes={quotes}
          events={events}
          onAdd={data => window.LelusaStore.addExpense(data)}
          onEdit={(id, data) => window.LelusaStore.updateExpense(id, data)}
          onDelete={id => window.LelusaStore.deleteExpense(id)}
        />
      )}
      {tab === 'reports' && <FinanceReports quotes={quotes} paymentSchemes={paymentSchemes} expenses={expenses} events={events} />}
    </AdminLayout>
  );
}

window.FinancePage = FinancePage;
