/* Módulo admin: Nómina y gastos */

/** Horas por día (Dom–Sáb) para semanas variables; guardado sin abrir el modal completo. */
const PayrollCoachWeekCard = ({ theme, profile, highlight, onEdit, onPay, onReload }) => {
  const initialRange = typeof defaultPayrollWeekRange === 'function'
    ? defaultPayrollWeekRange()
    : { weekStart: '', weekEnd: '' };
  const startFromProfile = profile.schedule_week_start || initialRange.weekStart;

  const [schedule, setSchedule] = React.useState(() => (
    typeof parseWeeklyHours === 'function' ? parseWeeklyHours(profile) : []
  ));
  const [weekStart, setWeekStart] = React.useState(startFromProfile);
  const [weekEnd, setWeekEnd] = React.useState(
    typeof addPayrollDays === 'function' ? addPayrollDays(startFromProfile, 6) : initialRange.weekEnd,
  );
  const [busy, setBusy] = React.useState(false);
  const [open, setOpen] = React.useState(true);

  React.useEffect(() => {
    if (typeof parseWeeklyHours === 'function') setSchedule(parseWeeklyHours(profile));
    const start = profile.schedule_week_start || (typeof mondayOfWeek === 'function' ? mondayOfWeek() : '');
    setWeekStart(start);
    setWeekEnd(typeof addPayrollDays === 'function' ? addPayrollDays(start, 6) : start);
  }, [profile.id, profile.weekly_hours, profile.schedule_week_start, profile.updated_at]);

  const syncWeekFromStart = (startIso) => {
    setWeekStart(startIso);
    if (typeof addPayrollDays === 'function') setWeekEnd(addPayrollDays(startIso, 6));
  };

  const syncWeekFromEnd = (endIso) => {
    setWeekEnd(endIso);
    if (typeof addPayrollDays === 'function' && endIso) setWeekStart(addPayrollDays(endIso, -6));
  };

  const weekRangeLabel = typeof formatPayrollWeekRange === 'function'
    ? formatPayrollWeekRange(weekStart, weekEnd)
    : `${weekStart} — ${weekEnd}`;

  const preview = typeof computePayrollWeekPreview === 'function'
    ? computePayrollWeekPreview(profile, schedule)
    : { amount: Number(profile.rate_amount) || 0, label: '', totalHours: 0, daysWorked: 0 };

  const dayLabels = typeof WEEKDAY_LABELS !== 'undefined'
    ? WEEKDAY_LABELS
    : ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'];

  const setDayHours = (weekday, hours) => {
    setSchedule((prev) => prev.map((e) => (
      e.weekday === weekday ? { ...e, hours: hours === '' ? '' : hours } : e
    )));
  };

  const saveWeek = async () => {
    if (typeof savePayrollWeeklySchedule !== 'function') {
      alert('Ejecuta la migración 063_payroll_weekly_hours.sql en Supabase.');
      return;
    }
    setBusy(true);
    try {
      await savePayrollWeeklySchedule(profile.id, schedule, weekStart);
      onReload?.();
    } catch (e) { alert(e.message); }
    setBusy(false);
  };

  return (
    <div className="tecos-nomina-coach" style={{
      borderColor: highlight ? theme.warning : theme.border,
      background: highlight ? `${theme.warning}14` : theme.bgInput,
    }}>
      <div className="tecos-nomina-coach__head">
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 700, color: theme.text, fontFamily: 'Inter, sans-serif' }}>{profile.display_name}</div>
          <div style={{ fontSize: 12, color: theme.textDim, marginTop: 4, fontFamily: 'Inter, sans-serif' }}>
            {(PAY_TYPE_LABELS && PAY_TYPE_LABELS[profile.pay_type]) || profile.pay_type}
            {' · $'}{Number(profile.rate_amount).toLocaleString('es-MX')}
            {profile.next_pay_date ? ` · Próximo: ${profile.next_pay_date}` : ''}
          </div>
          {preview.label && (
            <div style={{ fontSize: 11, color: theme.primary, marginTop: 6, fontFamily: 'Inter, sans-serif' }}>
              Esta semana: {preview.label} → <strong>${preview.amount.toLocaleString('es-MX')}</strong>
            </div>
          )}
        </div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
          <Btn theme={theme} kind="soft" onClick={() => onPay({
            profile_id: profile.id,
            name: profile.display_name,
            amount: preview.amount,
            suggestedAmount: preview.amount,
          })}>Registrar pago</Btn>
          <Btn theme={theme} kind="ghost" onClick={() => onEdit(profile)}>Tarifa y tipo</Btn>
          <button type="button" onClick={() => setOpen((v) => !v)} style={{
            padding: '6px 10px', borderRadius: 6, border: `1px solid ${theme.border}`,
            background: theme.bgCard, color: theme.textDim, cursor: 'pointer', fontSize: 12,
          }}>{open ? 'Ocultar' : 'Horas'}</button>
        </div>
      </div>
      {open && (
        <>
          <div className="tecos-nomina-week-range" style={{
            padding: '0 16px 12px', borderBottom: `1px solid ${theme.border}`,
          }}>
            <div className="tecos-nomina-week-range__title" style={{ color: theme.text, fontFamily: 'Inter, sans-serif' }}>
              Semana: <strong>{weekRangeLabel}</strong>
            </div>
            <div className="tecos-nomina-week-range__inputs" style={{ color: theme.textDim }}>
              <label>
                Del
                <input type="date" value={weekStart} onChange={(e) => syncWeekFromStart(e.target.value)} style={{
                  padding: '6px 8px', borderRadius: 6, border: `1px solid ${theme.border}`,
                  background: theme.bgInput, color: theme.text,
                }} />
              </label>
              <span className="tecos-nomina-week-range__sep">al</span>
              <label>
                <input type="date" value={weekEnd} min={weekStart} onChange={(e) => syncWeekFromEnd(e.target.value)} style={{
                  padding: '6px 8px', borderRadius: 6, border: `1px solid ${theme.border}`,
                  background: theme.bgInput, color: theme.text,
                }} />
              </label>
              <button type="button" onClick={() => {
                const r = typeof defaultPayrollWeekRange === 'function' ? defaultPayrollWeekRange() : null;
                if (r) { setWeekStart(r.weekStart); setWeekEnd(r.weekEnd); }
              }} style={{
                padding: '6px 10px', borderRadius: 6, border: `1px solid ${theme.border}`,
                background: theme.bgCard, color: theme.textDim, cursor: 'pointer', fontSize: 11,
              }}>Semana actual</button>
            </div>
            <div className="tecos-nomina-week-range__total" style={{ color: theme.textDim }}>
              Total sugerido ({(PAY_TYPE_LABELS && PAY_TYPE_LABELS[profile.pay_type]) || profile.pay_type}):
              {' '}<strong style={{ color: preview.amount > 0 ? theme.text : theme.warning, fontSize: 18 }}>
                ${preview.amount.toLocaleString('es-MX')}
              </strong>
              {preview.label && <span style={{ marginLeft: 8 }}>· {preview.label}</span>}
            </div>
            {preview.hint && (
              <p style={{ fontSize: 11, color: theme.warning, margin: '8px 0 0', fontFamily: 'Inter, sans-serif' }}>
                {preview.hint}
              </p>
            )}
          </div>
          <div className="tecos-nomina-week">
            {schedule.map((entry) => (
              <div key={entry.weekday} className="tecos-nomina-day" style={{
                borderColor: theme.border, background: theme.bgCard,
              }}>
                <label style={{ color: theme.textMute }}>{dayLabels[entry.weekday]}</label>
                <input
                  type="number"
                  min="0"
                  step="0.5"
                  placeholder="0"
                  value={entry.hours}
                  onChange={(e) => setDayHours(entry.weekday, e.target.value)}
                  style={{ borderColor: theme.border, background: theme.bgInput, color: theme.text }}
                />
              </div>
            ))}
          </div>
          <div style={{
            padding: '8px 16px 16px', display: 'flex', justifyContent: 'space-between',
            alignItems: 'center', flexWrap: 'wrap', gap: 10,
          }}>
            <span style={{ fontSize: 12, color: theme.textDim, fontFamily: 'Inter, sans-serif' }}>
              {preview.totalHours} h en {preview.daysWorked} día(s)
            </span>
            <Btn theme={theme} onClick={saveWeek} disabled={busy}>
              {busy ? 'Guardando…' : 'Guardar semana'}
            </Btn>
          </div>
        </>
      )}
    </div>
  );
};

const DEFAULT_PAYROLL_FORM = {
  id: null,
  coach_id: null,
  display_name: '',
  pay_type: 'week',
  rate_amount: '',
  pay_weekdays: [],
  pay_days_of_month: [],
  next_pay_date: '',
  notes: '',
  active: true,
};

const NominaGastosAdminModule = ({ theme }) => {
  const [tab, setTab] = React.useState('nomina');
  const [profiles, setProfiles] = React.useState([]);
  const [categories, setCategories] = React.useState([]);
  const [expenses, setExpenses] = React.useState([]);
  const [payrollPayments, setPayrollPayments] = React.useState([]);
  const [withdrawals, setWithdrawals] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr] = React.useState('');
  const [payrollModal, setPayrollModal] = React.useState(null);
  const [expenseModal, setExpenseModal] = React.useState(null);
  const [payModal, setPayModal] = React.useState(null);
  const [withdrawModal, setWithdrawModal] = React.useState(false);
  const [syncBusy, setSyncBusy] = React.useState(false);
  const [exportBusy, setExportBusy] = React.useState('');

  const load = React.useCallback(async () => {
    setLoading(true);
    setErr('');
    try {
      const [p, c, e, pp, w] = await Promise.all([
        fetchPayrollProfilesAdmin(),
        fetchExpenseCategoriesAdmin(),
        fetchExpensesAdmin({ limit: 200 }),
        fetchPayrollPaymentsAdmin({ limit: 200 }),
        fetchFinanceWithdrawalsAdmin({ limit: 100 }),
      ]);
      setProfiles(p);
      setCategories(c);
      setExpenses(e);
      setPayrollPayments(pp);
      setWithdrawals(w);
    } catch (e) {
      setErr(e.message || 'Error al cargar');
    }
    setLoading(false);
  }, []);

  React.useEffect(() => {
    load();
    const on = () => load();
    window.addEventListener('tecos:academy-data-sync', on);
    window.addEventListener('tecos:finance-changed', on);
    return () => {
      window.removeEventListener('tecos:academy-data-sync', on);
      window.removeEventListener('tecos:finance-changed', on);
    };
  }, [load]);

  const dueTomorrow = typeof payrollProfilesDueTomorrow === 'function'
    ? payrollProfilesDueTomorrow(profiles)
    : [];

  const syncCoaches = async () => {
    setSyncBusy(true);
    try {
      const n = await syncCoachesToPayroll();
      alert(n > 0 ? `Se agregaron ${n} entrenador(es) a nómina.` : 'Todos los entrenadores activos ya están en nómina.');
      load();
    } catch (e) { alert(e.message); }
    setSyncBusy(false);
  };

  const tabs = [
    { id: 'nomina', l: 'Nómina' },
    { id: 'gastos', l: 'Gastos operativos' },
    { id: 'retiros', l: 'Retiros' },
    { id: 'movimientos', l: 'Movimientos' },
  ];

  return (
    <div className="tecos-page-shell" style={{ padding: 32, display: 'grid', gap: 18 }}>
      {dueTomorrow.length > 0 && (
        <div style={{
          padding: 14, borderRadius: 10,
          background: `linear-gradient(135deg, ${theme.warning}33, ${theme.warning}08)`,
          border: `2px solid ${theme.warning}`,
          animation: 'tecos-pulse 1.5s ease-in-out infinite',
          fontFamily: 'Inter, sans-serif', fontSize: 13,
        }}>
          <strong style={{ color: theme.warning }}>Pago de nómina mañana:</strong>{' '}
          {dueTomorrow.map((p) => p.display_name).join(', ')}
        </div>
      )}

      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          {tabs.map((t) => (
            <button key={t.id} type="button" onClick={() => setTab(t.id)} style={{
              padding: '8px 16px', borderRadius: 8, cursor: 'pointer', fontFamily: 'Inter, sans-serif', fontSize: 13, fontWeight: 600,
              border: `1px solid ${tab === t.id ? theme.primary : theme.border}`,
              background: tab === t.id ? `${theme.primary}22` : theme.bgInput,
              color: tab === t.id ? theme.primary : theme.textDim,
            }}>{t.l}</button>
          ))}
        </div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <Btn theme={theme} kind="soft" icon="users" onClick={syncCoaches} disabled={syncBusy}>
            {syncBusy ? 'Sincronizando…' : 'Importar entrenadores'}
          </Btn>
          {tab === 'nomina' && (
            <Btn theme={theme} icon="plus" onClick={() => setPayrollModal({ ...DEFAULT_PAYROLL_FORM })}>Nuevo perfil</Btn>
          )}
          {tab === 'gastos' && (
            <Btn theme={theme} icon="plus" onClick={() => setExpenseModal({ name: '', amount: '', category_id: categories[0]?.id || '', is_variable: true, expense_at: new Date().toISOString().slice(0, 16) })}>Nuevo gasto</Btn>
          )}
          {tab === 'retiros' && (
            <Btn theme={theme} icon="money" onClick={() => setWithdrawModal(true)}>Registrar retiro</Btn>
          )}
          <Btn theme={theme} kind="soft" icon="download" disabled={!!exportBusy} onClick={async () => {
            setExportBusy('pdf');
            try {
              const st = await fetchAdminDashboardStats(new Date().getFullYear());
              await exportDashboardFinancePdf(st, { mode: 'rango', rangeFrom: 1, rangeTo: 12 }, st.year, theme, DEFAULT_DASHBOARD_CHART_SERIES);
            } catch (e) { alert(e.message); }
            setExportBusy('');
          }}>PDF finanzas</Btn>
          <Btn theme={theme} kind="soft" icon="download" disabled={!!exportBusy} onClick={async () => {
            setExportBusy('xlsx');
            try {
              const st = await fetchAdminDashboardStats(new Date().getFullYear());
              await exportDashboardFinanceExcel(st, { mode: 'rango', rangeFrom: 1, rangeTo: 12 }, st.year, DEFAULT_DASHBOARD_CHART_SERIES);
            } catch (e) { alert(e.message); }
            setExportBusy('');
          }}>Excel finanzas</Btn>
        </div>
      </div>

      {err && <div style={{ color: theme.danger, fontSize: 13 }}>{err}</div>}
      {loading ? <LoadingBlock theme={theme} label="Cargando finanzas…" /> : (
        <>
          {tab === 'nomina' && (
            <Card theme={theme}>
              <p style={{ fontSize: 12, color: theme.textDim, margin: '0 0 14px', fontFamily: 'Inter, sans-serif', lineHeight: 1.5 }}>
                Cada entrenador puede tener horas distintas por semana. Captura Dom–Sáb, guarda la semana y registra el pago con el monto sugerido (por hora, día, semana o fijo).
              </p>
              <div style={{ display: 'grid', gap: 0 }}>
                {profiles.map((p) => (
                  <PayrollCoachWeekCard
                    key={p.id}
                    theme={theme}
                    profile={p}
                    highlight={dueTomorrow.some((d) => d.id === p.id)}
                    onEdit={(prof) => setPayrollModal({
                      ...prof,
                      pay_weekdays: prof.pay_weekdays || [],
                      pay_days_of_month: prof.pay_days_of_month || [],
                    })}
                    onPay={(data) => setPayModal(data)}
                    onReload={load}
                  />
                ))}
                {!profiles.length && <p style={{ color: theme.textMute, fontSize: 13 }}>Sin perfiles. Usa «Importar entrenadores» o «Nuevo perfil».</p>}
              </div>
            </Card>
          )}

          {tab === 'gastos' && (
            <Card theme={theme}>
              <p style={{ fontSize: 12, color: theme.textDim, margin: '0 0 14px', fontFamily: 'Inter, sans-serif' }}>
                Lista editable de gastos (luz, agua, servicios…). Marca «variable» si el monto cambia cada mes.
              </p>
              <div style={{ display: 'grid', gap: 8 }}>
                {expenses.map((e) => (
                  <div key={e.id} style={{
                    padding: 12, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput,
                    display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 8,
                  }}>
                    <div>
                      <strong style={{ color: theme.text }}>{e.name}</strong>
                      <span style={{ fontSize: 12, color: theme.textDim, marginLeft: 8 }}>
                        {e.expense_categories?.name || 'Sin categoría'}
                        {e.is_variable ? ' · Variable' : ''}
                      </span>
                      <div style={{ fontSize: 11, color: theme.textMute, marginTop: 4 }}>{formatFinanceDateTime(e.expense_at)}</div>
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                      <span style={{ fontFamily: 'Bebas Neue, sans-serif', fontSize: 22, color: theme.danger }}>-${Number(e.amount).toLocaleString('es-MX')}</span>
                      <Btn theme={theme} kind="soft" onClick={() => setExpenseModal({ ...e, expense_at: e.expense_at?.slice(0, 16) })}>Editar</Btn>
                    </div>
                  </div>
                ))}
              </div>
            </Card>
          )}

          {tab === 'retiros' && (
            <Card theme={theme}>
              <p style={{ fontSize: 12, color: theme.textDim, margin: '0 0 14px' }}>Retiros de caja con fecha y hora exacta.</p>
              {withdrawals.map((w) => (
                <div key={w.id} style={{ padding: 12, borderBottom: `1px solid ${theme.border}`, fontSize: 13 }}>
                  <strong>{w.concept}</strong> · -${Number(w.amount).toLocaleString('es-MX')}
                  <div style={{ fontSize: 11, color: theme.textMute }}>{formatFinanceDateTime(w.withdrawn_at)}</div>
                </div>
              ))}
            </Card>
          )}

          {tab === 'movimientos' && (
            <Card theme={theme}>
              <h4 style={{ margin: '0 0 12px', fontFamily: 'Bebas Neue, sans-serif', fontSize: 20, color: theme.text }}>Últimos egresos</h4>
              {[...payrollPayments.map((p) => ({ ...p, kind: 'nomina', at: p.paid_at, label: p.payroll_profiles?.display_name || 'Nómina' })),
                ...expenses.map((e) => ({ ...e, kind: 'gasto', at: e.expense_at, label: e.name })),
                ...withdrawals.map((w) => ({ ...w, kind: 'retiro', at: w.withdrawn_at, label: w.concept })),
              ].sort((a, b) => new Date(b.at) - new Date(a.at)).slice(0, 40).map((row) => (
                <div key={`${row.kind}-${row.id}`} style={{ padding: 10, borderBottom: `1px solid ${theme.border}`, fontSize: 12 }}>
                  <span style={{ textTransform: 'capitalize', color: theme.textMute }}>{row.kind}</span> · {row.label} · -${Number(row.amount).toLocaleString('es-MX')}
                  <div style={{ color: theme.textMute, fontSize: 11 }}>{formatFinanceDateTime(row.at)}</div>
                </div>
              ))}
            </Card>
          )}
        </>
      )}

      {payrollModal && (
        <PayrollProfileModal theme={theme} form={payrollModal} onClose={() => setPayrollModal(null)} onSaved={() => { setPayrollModal(null); load(); }} />
      )}
      {expenseModal && (
        <ExpenseModal theme={theme} form={expenseModal} categories={categories} onClose={() => setExpenseModal(null)} onSaved={() => { setExpenseModal(null); load(); }} />
      )}
      {payModal && (
        <RecordPayrollPaymentModal theme={theme} data={payModal} onClose={() => setPayModal(null)} onSaved={() => { setPayModal(null); load(); }} />
      )}
      {withdrawModal && (
        <WithdrawalModal theme={theme} onClose={() => setWithdrawModal(false)} onSaved={() => { setWithdrawModal(false); load(); }} />
      )}
    </div>
  );
};

const PayrollProfileModal = ({ theme, form, onClose, onSaved }) => {
  const [f, setF] = React.useState(form);
  const [busy, setBusy] = React.useState(false);
  const rateLabel = (PAY_TYPE_RATE_LABELS && PAY_TYPE_RATE_LABELS[f.pay_type])
    || 'Monto (MXN)';
  const typeHint = (PAY_TYPE_HINTS && PAY_TYPE_HINTS[f.pay_type]) || '';
  const previewProfile = typeof computePayrollWeekPreview === 'function'
    ? computePayrollWeekPreview(f, typeof parseWeeklyHours === 'function' ? parseWeeklyHours(f) : [])
    : null;

  const toggleWeekday = (d) => {
    const w = [...(f.pay_weekdays || [])];
    const i = w.indexOf(d);
    if (i >= 0) w.splice(i, 1); else w.push(d);
    setF({ ...f, pay_weekdays: w.sort((a, b) => a - b) });
  };
  const save = async () => {
    if (!String(f.display_name || '').trim()) { alert('Nombre requerido'); return; }
    if (!(Number(f.rate_amount) > 0)) {
      alert('Indica un monto mayor a 0 para la tarifa o pago fijo.');
      return;
    }
    setBusy(true);
    try {
      await upsertPayrollProfile(f);
      onSaved();
    } catch (e) { alert(e.message); }
    setBusy(false);
  };
  return (
    <Modal open onClose={onClose} theme={theme} width={540}>
      <div style={{ padding: 24, display: 'grid', gap: 12 }}>
        <h3 style={{ fontFamily: 'Bebas Neue, sans-serif', fontSize: 24, margin: 0 }}>Tarifa y tipo de pago</h3>
        <p style={{ fontSize: 12, color: theme.textDim, margin: 0, fontFamily: 'Inter, sans-serif', lineHeight: 1.5 }}>
          Define cómo se calcula el pago: por hora, por día, por semana o monto fijo. Las horas de cada semana se capturan en la tarjeta del entrenador.
        </p>
        <Input theme={theme} label="Nombre" value={f.display_name} onChange={(e) => setF({ ...f, display_name: e.target.value })} />
        <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, fontFamily: 'Inter, sans-serif' }}>¿Cómo se le paga?</label>
        <select value={f.pay_type} onChange={(e) => setF({ ...f, pay_type: e.target.value })} style={{ padding: 10, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text, fontFamily: 'Inter, sans-serif' }}>
          {Object.entries(PAY_TYPE_LABELS || {}).map(([k, l]) => <option key={k} value={k}>{l}</option>)}
        </select>
        {typeHint && (
          <p style={{ fontSize: 11, color: theme.textDim, margin: 0, padding: 10, borderRadius: 8, background: theme.bgInput, fontFamily: 'Inter, sans-serif', lineHeight: 1.45 }}>
            {typeHint}
          </p>
        )}
        <Input theme={theme} label={rateLabel} type="number" min="0" step="0.01" value={f.rate_amount}
          onChange={(e) => setF({ ...f, rate_amount: e.target.value })} />
        {previewProfile && (
          <div style={{
            padding: 12, borderRadius: 8, border: `1px solid ${theme.primary}44`,
            background: `${theme.primary}10`, fontSize: 12, fontFamily: 'Inter, sans-serif',
          }}>
            Vista previa (sin horas esta semana):{' '}
            <strong style={{ color: theme.text }}>${previewProfile.amount.toLocaleString('es-MX')}</strong>
            {previewProfile.label && <span style={{ color: theme.textDim }}> · {previewProfile.label}</span>}
          </div>
        )}
        <Input theme={theme} label="Próxima fecha de pago" type="date" value={f.next_pay_date || ''} onChange={(e) => setF({ ...f, next_pay_date: e.target.value })} />
        <div>
          <div style={{ fontSize: 11, color: theme.textMute, marginBottom: 6, fontWeight: 700 }}>Días de la semana (si aplica)</div>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {WEEKDAY_LABELS.map((lbl, i) => (
              <button key={i} type="button" onClick={() => toggleWeekday(i)} style={{
                padding: '6px 10px', borderRadius: 6, border: `1px solid ${(f.pay_weekdays || []).includes(i) ? theme.primary : theme.border}`,
                background: (f.pay_weekdays || []).includes(i) ? `${theme.primary}22` : theme.bgInput, cursor: 'pointer', fontSize: 12,
              }}>{lbl}</button>
            ))}
          </div>
        </div>
        <Input theme={theme} label="Días del mes (separados por coma, ej. 1,15)" value={(f.pay_days_of_month || []).join(',')}
          onChange={(e) => setF({ ...f, pay_days_of_month: e.target.value.split(',').map((x) => parseInt(x.trim(), 10)).filter((n) => n >= 1 && n <= 31) })} />
        <Input theme={theme} label="Notas" value={f.notes || ''} onChange={(e) => setF({ ...f, notes: e.target.value })} />
        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
          <Btn theme={theme} kind="soft" onClick={onClose}>Cancelar</Btn>
          <Btn theme={theme} onClick={save} disabled={busy}>{busy ? 'Guardando…' : 'Guardar'}</Btn>
        </div>
      </div>
    </Modal>
  );
};

const ExpenseModal = ({ theme, form, categories, onClose, onSaved }) => {
  const [f, setF] = React.useState(form);
  const [busy, setBusy] = React.useState(false);
  const save = async () => {
    setBusy(true);
    try {
      const at = f.expense_at?.length === 16 ? `${f.expense_at}:00` : f.expense_at;
      await upsertExpense({ ...f, expense_at: at ? new Date(at).toISOString() : new Date().toISOString() });
      onSaved();
    } catch (e) { alert(e.message); }
    setBusy(false);
  };
  return (
    <Modal open onClose={onClose} theme={theme} width={480}>
      <div style={{ padding: 24, display: 'grid', gap: 12 }}>
        <h3 style={{ fontFamily: 'Bebas Neue, sans-serif', fontSize: 24, margin: 0 }}>{f.id ? 'Editar gasto' : 'Nuevo gasto'}</h3>
        <Input theme={theme} label="Concepto" value={f.name} onChange={(e) => setF({ ...f, name: e.target.value })} />
        <Input theme={theme} label="Monto" type="number" value={f.amount} onChange={(e) => setF({ ...f, amount: e.target.value })} />
        <label style={{ fontSize: 11, color: theme.textMute }}>Categoría</label>
        <select value={f.category_id || ''} onChange={(e) => setF({ ...f, category_id: e.target.value })} style={{ padding: 10, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text }}>
          <option value="">—</option>
          {categories.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
        </select>
        <Input theme={theme} label="Fecha y hora" type="datetime-local" value={f.expense_at || ''} onChange={(e) => setF({ ...f, expense_at: e.target.value })} />
        <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: theme.textDim }}>
          <input type="checkbox" checked={!!f.is_variable} onChange={(e) => setF({ ...f, is_variable: e.target.checked })} />
          Monto variable cada mes
        </label>
        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
          <Btn theme={theme} kind="soft" onClick={onClose}>Cancelar</Btn>
          <Btn theme={theme} onClick={save} disabled={busy}>Guardar</Btn>
        </div>
      </div>
    </Modal>
  );
};

const RecordPayrollPaymentModal = ({ theme, data, onClose, onSaved }) => {
  const initialAmount = data.suggestedAmount != null ? data.suggestedAmount : (data.amount || '');
  const [amount, setAmount] = React.useState(initialAmount === '' ? '' : String(initialAmount));
  const [at, setAt] = React.useState(new Date().toISOString().slice(0, 16));
  const [busy, setBusy] = React.useState(false);

  React.useEffect(() => {
    const next = data.suggestedAmount != null ? data.suggestedAmount : (data.amount || '');
    setAmount(next === '' ? '' : String(next));
  }, [data.profile_id, data.suggestedAmount, data.amount]);
  const save = async () => {
    setBusy(true);
    try {
      await recordPayrollPayment({
        profile_id: data.profile_id,
        amount,
        paid_at: new Date(at).toISOString(),
        concept: `Nómina ${data.name}`,
      });
      onSaved();
    } catch (e) { alert(e.message); }
    setBusy(false);
  };
  return (
    <Modal open onClose={onClose} theme={theme} width={420}>
      <div style={{ padding: 24, display: 'grid', gap: 12 }}>
        <h3 style={{ fontFamily: 'Bebas Neue, sans-serif', fontSize: 22, margin: 0 }}>Pago — {data.name}</h3>
        {data.suggestedAmount != null && (
          <p style={{ fontSize: 12, color: theme.textDim, margin: 0, fontFamily: 'Inter, sans-serif' }}>
            Monto sugerido según horas de la semana guardada. Puedes ajustarlo si pagaste distinto.
          </p>
        )}
        <Input theme={theme} label="Monto" type="number" value={amount} onChange={(e) => setAmount(e.target.value)} />
        <Input theme={theme} label="Fecha y hora" type="datetime-local" value={at} onChange={(e) => setAt(e.target.value)} />
        <Btn theme={theme} onClick={save} disabled={busy}>Registrar egreso</Btn>
      </div>
    </Modal>
  );
};

const WithdrawalModal = ({ theme, onClose, onSaved }) => {
  const [amount, setAmount] = React.useState('');
  const [concept, setConcept] = React.useState('');
  const [at, setAt] = React.useState(new Date().toISOString().slice(0, 16));
  const [busy, setBusy] = React.useState(false);
  const save = async () => {
    setBusy(true);
    try {
      await recordFinanceWithdrawal({ amount, concept, withdrawn_at: new Date(at).toISOString() });
      onSaved();
    } catch (e) { alert(e.message); }
    setBusy(false);
  };
  return (
    <Modal open onClose={onClose} theme={theme} width={420}>
      <div style={{ padding: 24, display: 'grid', gap: 12 }}>
        <h3 style={{ fontFamily: 'Bebas Neue, sans-serif', fontSize: 22, margin: 0 }}>Registrar retiro</h3>
        <Input theme={theme} label="Concepto" value={concept} onChange={(e) => setConcept(e.target.value)} />
        <Input theme={theme} label="Monto" type="number" value={amount} onChange={(e) => setAmount(e.target.value)} />
        <Input theme={theme} label="Fecha y hora" type="datetime-local" value={at} onChange={(e) => setAt(e.target.value)} />
        <Btn theme={theme} onClick={save} disabled={busy}>Guardar</Btn>
      </div>
    </Modal>
  );
};

Object.assign(window, { NominaGastosAdminModule });
