// Workspace — Payments view (F1).
//
// Per-project list of payment milestones with totals at the top. The "late"
// status is derived in the backend (D1 decision); the UI just shows a
// red badge for items where effectiveStatus === 'late'.
//
// Currency lives on the project record. We show its symbol everywhere.

const _CURRENCY_SYMBOL = { MXN: '$', USD: 'US$', EUR: '€' };
const _PAYMENT_STATUS_META = {
  pending:   { label: 'Pendiente',   color: 'var(--text-1)',   bg: 'var(--bg-2)',                  dot: 'var(--text-3)' },
  late:      { label: 'Atrasado',    color: 'var(--danger)',   bg: 'rgba(239,68,68,.12)',          dot: 'var(--danger)' },
  received:  { label: 'Recibido',    color: 'var(--success)',  bg: 'rgba(16,185,129,.14)',         dot: 'var(--success)' },
  cancelled: { label: 'Cancelado',   color: 'var(--text-3)',   bg: 'var(--bg-2)',                  dot: 'var(--text-3)' },
};

function fmtMoney(amount, symbol) {
  return `${symbol}${(amount ?? 0).toLocaleString('es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}

function PaymentsView() {
  window.useData();
  const project = window.getCurrentProject?.();
  const symbol = _CURRENCY_SYMBOL[project?.currency || 'MXN'] || '$';

  const [payments, setPayments] = React.useState([]);
  const [summary, setSummary] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [showNew, setShowNew] = React.useState(false);
  const [editing, setEditing] = React.useState(null);

  const refresh = React.useCallback(async () => {
    setLoading(true);
    try {
      const [list, sum] = await Promise.all([
        window.api('GET', '/api/payments'),
        window.api('GET', '/api/payments/summary'),
      ]);
      setPayments(list);
      setSummary(sum);
    } catch (e) { console.error(e); }
    finally { setLoading(false); }
  }, []);
  React.useEffect(() => { refresh(); }, [refresh, project?.id]);
  // Subscribe to WS events for live updates.
  React.useEffect(() => {
    return window.onRealtime((msg) => {
      if (msg.type === 'payment.changed' && msg.projectId === window.CURRENT_PROJECT_ID) {
        refresh();
      }
    });
  }, [refresh]);

  if (!project) {
    return <div style={{ padding: 40, color: 'var(--text-2)' }}>Seleccioná un proyecto para ver sus pagos.</div>;
  }

  return (
    <div style={{ flex: 1, overflowY: 'auto', padding: '32px 40px 80px' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto' }}>
        <SectionHead
          level="h1"
          title="Pagos"
          sub={`${project.name} · moneda ${project.currency}`}
          right={
            <div style={{ display: 'flex', gap: 8 }}>
              <CurrencySelector project={project} />
              <Button variant="primary" size="md" icon="plus" onClick={() => setShowNew(true)}>Nuevo pago</Button>
            </div>
          }
        />

        {/* Summary */}
        {summary && (
          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 12,
            marginBottom: 24,
          }}>
            <SummaryCard label="Cotizado" value={fmtMoney(summary.totalQuoted, symbol)} sub={`${summary.counts.total} hito${summary.counts.total === 1 ? '' : 's'}`} />
            <SummaryCard label="Recibido" value={fmtMoney(summary.totalReceived, symbol)} accent="var(--success)" sub={`${summary.counts.received} pago${summary.counts.received === 1 ? '' : 's'}`} />
            <SummaryCard label="Pendiente" value={fmtMoney(summary.totalPending, symbol)} sub={`${summary.counts.pending} pago${summary.counts.pending === 1 ? '' : 's'}`} />
            <SummaryCard label="Atrasado" value={fmtMoney(summary.totalLate, symbol)} accent="var(--danger)" sub={summary.counts.late === 0 ? 'al día' : `${summary.counts.late} atrasado${summary.counts.late === 1 ? '' : 's'}`} />
            <SummaryCard label="Próximo"
              value={summary.nextExpected ? fmtMoney(summary.nextExpected.amount, symbol) : '—'}
              sub={summary.nextExpected ? new Date(summary.nextExpected.expectedDate + 'T00:00:00').toLocaleDateString('es', { day: 'numeric', month: 'short' }) : 'sin agenda'} />
          </div>
        )}

        {/* Table */}
        <div style={{ background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)', overflow: 'hidden' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '40px 120px 110px 110px 110px 1fr 90px 60px', alignItems: 'center', gap: 0, padding: '10px 16px', borderBottom: '1px solid var(--border)', fontSize: 11, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.5 }}>
            <div>#</div><div>Monto</div><div>Esperado</div><div>Recibido</div><div>Status</div><div>Habilita</div><div>Notas</div><div></div>
          </div>
          {loading && <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)' }}>Cargando…</div>}
          {!loading && payments.length === 0 && (
            <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)' }}>
              No hay pagos cargados todavía. <button className="btn-reset" onClick={() => setShowNew(true)} style={{ color: 'var(--accent)' }}>Crear el primero</button>
            </div>
          )}
          {!loading && payments.map((p, i) => (
            <PaymentRow key={p.id} index={i + 1} payment={p} symbol={symbol} onEdit={() => setEditing(p)} onQuickReceive={async () => {
              const today = new Date().toISOString().slice(0, 10);
              try { await window.api('PATCH', `/api/payments/${p.id}`, { receivedDate: today }); }
              catch (e) { alert(e.message || 'No se pudo actualizar'); }
            }} />
          ))}
        </div>
      </div>

      {showNew && <PaymentModal onClose={() => setShowNew(false)} />}
      {editing && <PaymentModal payment={editing} onClose={() => setEditing(null)} />}
    </div>
  );
}

function CurrencySelector({ project }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);
  const setCurrency = async (currency) => {
    setOpen(false);
    if (currency === project.currency) return;
    try {
      await window.api('PATCH', `/api/projects/${project.id}`, { currency });
      await window.loadProjects();
    } catch (e) { alert(e.message || 'No se pudo cambiar la moneda'); }
  };
  return (
    <span ref={ref} style={{ position: 'relative' }}>
      <Button variant="secondary" size="md" icon="dollar-sign" onClick={() => setOpen((v) => !v)}>{project.currency}</Button>
      {open && (
        <div style={{
          position: 'absolute', top: 36, right: 0, zIndex: 30,
          background: 'var(--bg-1)', border: '1px solid var(--border-strong)',
          borderRadius: 6, padding: 4, minWidth: 100,
          boxShadow: '0 8px 22px rgba(0,0,0,.45)',
        }}>
          {['MXN', 'USD', 'EUR'].map((c) => (
            <button key={c} className="btn-reset" onClick={() => setCurrency(c)}
              style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%', padding: '6px 10px', borderRadius: 4, fontSize: 12.5, color: c === project.currency ? 'var(--accent)' : 'var(--text-1)' }}
              onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-2)'}
              onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
              <span>{_CURRENCY_SYMBOL[c]}</span><span>{c}</span>
            </button>
          ))}
        </div>
      )}
    </span>
  );
}

function SummaryCard({ label, value, sub, accent }) {
  return (
    <div style={{ background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)', padding: 16 }}>
      <div style={{ fontSize: 10.5, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.6, marginBottom: 8 }}>{label}</div>
      <div className="mono" style={{ fontSize: 18, fontWeight: 600, color: accent || 'var(--text-0)', letterSpacing: -0.3 }}>{value}</div>
      {sub && <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 4 }}>{sub}</div>}
    </div>
  );
}

function PaymentRow({ index, payment, symbol, onEdit, onQuickReceive }) {
  const meta = _PAYMENT_STATUS_META[payment.effectiveStatus] || _PAYMENT_STATUS_META.pending;
  const fmtDate = (d) => d ? new Date(d + 'T00:00:00').toLocaleDateString('es', { day: 'numeric', month: 'short', year: '2-digit' }) : '—';
  const isCancelled = payment.status === 'cancelled';
  return (
    <div onClick={onEdit} style={{
      display: 'grid', gridTemplateColumns: '40px 120px 110px 110px 110px 1fr 90px 60px',
      alignItems: 'center', gap: 0, padding: '12px 16px',
      borderBottom: '1px solid var(--border)',
      fontSize: 12.5, cursor: 'pointer',
      opacity: isCancelled ? 0.55 : 1,
    }}
      onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-2)'}
      onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
      <div className="mono" style={{ color: 'var(--text-3)' }}>{String(index).padStart(2, '0')}</div>
      <div className="mono" style={{ fontWeight: 600, color: 'var(--text-0)' }}>{symbol}{payment.amount.toLocaleString('es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</div>
      <div style={{ color: 'var(--text-1)' }}>{fmtDate(payment.expectedDate)}</div>
      <div style={{ color: payment.receivedDate ? 'var(--text-1)' : 'var(--text-3)' }}>{fmtDate(payment.receivedDate)}</div>
      <div>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 5,
          padding: '2px 8px', borderRadius: 10,
          background: meta.bg, color: meta.color, fontSize: 11, fontWeight: 500,
        }}>
          <span style={{ width: 6, height: 6, borderRadius: 3, background: meta.dot }} />
          {meta.label}
        </span>
      </div>
      <div style={{ color: 'var(--text-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{payment.unlocks || <span style={{ color: 'var(--text-3)', fontStyle: 'italic' }}>—</span>}</div>
      <div style={{ color: 'var(--text-3)', fontSize: 11 }}>{payment.notes ? `${payment.notes.length} ch` : ''}</div>
      <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
        {payment.status === 'pending' && (
          <button className="btn-reset" title="Marcar recibido (hoy)"
            onClick={(e) => { e.stopPropagation(); onQuickReceive(); }}
            style={{ width: 26, height: 26, display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: 5, color: 'var(--text-2)' }}
            onMouseEnter={(e) => { e.currentTarget.style.background = 'var(--bg-2)'; e.currentTarget.style.color = 'var(--success)'; }}
            onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--text-2)'; }}>
            <Icon name="check-circle-2" size={14} />
          </button>
        )}
      </div>
    </div>
  );
}

function PaymentModal({ payment, onClose }) {
  const isEdit = !!payment;
  const [amount, setAmount] = React.useState(payment ? String(payment.amount) : '');
  const [expectedDate, setExpectedDate] = React.useState(payment?.expectedDate || '');
  const [receivedDate, setReceivedDate] = React.useState(payment?.receivedDate || '');
  const [status, setStatus] = React.useState(payment?.status || 'pending');
  const [unlocks, setUnlocks] = React.useState(payment?.unlocks || '');
  const [notes, setNotes] = React.useState(payment?.notes || '');
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState(null);

  const submit = async () => {
    const n = Number(amount);
    if (!Number.isFinite(n) || n < 0) { setError('Monto inválido'); return; }
    setSubmitting(true);
    setError(null);
    const body = {
      amount: n,
      expectedDate: expectedDate || null,
      receivedDate: receivedDate || null,
      status,
      unlocks: unlocks.trim(),
      notes,
    };
    try {
      if (isEdit) await window.api('PATCH', `/api/payments/${payment.id}`, body);
      else await window.api('POST', '/api/payments', body);
      onClose();
    } catch (e) {
      setError(e.message || 'Error');
      setSubmitting(false);
    }
  };

  const onDelete = async () => {
    if (!confirm('¿Borrar este pago?')) return;
    try {
      await window.api('DELETE', `/api/payments/${payment.id}`);
      onClose();
    } catch (e) { alert(e.message || 'No se pudo borrar'); }
  };

  return (
    <Modal title={isEdit ? `Editar pago` : 'Nuevo pago'} onClose={onClose} width={500}
      footer={<>
        {isEdit && <Button variant="ghost" onClick={onDelete} style={{ marginRight: 'auto', color: 'var(--danger)' }}>Borrar</Button>}
        <Button variant="ghost" onClick={onClose}>Cancelar</Button>
        <Button variant="primary" onClick={submit} disabled={submitting || !amount}>
          {submitting ? 'Guardando…' : (isEdit ? 'Guardar' : 'Crear')}
        </Button>
      </>}>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <FormRow label="Monto">
          <input type="number" step="0.01" min="0" autoFocus
            value={amount} onChange={(e) => setAmount(e.target.value)}
            placeholder="5000.00"
            style={{
              width: '100%', height: 36, padding: '0 12px',
              background: 'var(--bg-0)', border: '1px solid var(--border)',
              borderRadius: 6, color: 'var(--text-0)', fontSize: 14,
              fontFamily: 'var(--font-mono)', outline: 'none',
            }} />
        </FormRow>
        <FormRow label="Status">
          <select value={status} onChange={(e) => setStatus(e.target.value)}
            style={{
              width: '100%', height: 36, padding: '0 10px',
              background: 'var(--bg-0)', border: '1px solid var(--border)',
              borderRadius: 6, color: 'var(--text-0)', fontSize: 13, outline: 'none',
            }}>
            <option value="pending">Pendiente</option>
            <option value="received">Recibido</option>
            <option value="cancelled">Cancelado</option>
          </select>
        </FormRow>
        <FormRow label="Fecha esperada">
          <input type="date" value={expectedDate} onChange={(e) => setExpectedDate(e.target.value)}
            style={{
              width: '100%', height: 32, padding: '0 10px',
              background: 'var(--bg-0)', border: '1px solid var(--border)',
              borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, outline: 'none',
            }} />
        </FormRow>
        <FormRow label="Fecha recibida">
          <input type="date" value={receivedDate} onChange={(e) => setReceivedDate(e.target.value)}
            style={{
              width: '100%', height: 32, padding: '0 10px',
              background: 'var(--bg-0)', border: '1px solid var(--border)',
              borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, outline: 'none',
            }} />
        </FormRow>
      </div>
      <FormRow label="Habilita" hint="¿Qué desbloquea este pago? Ej: 'noche del cambio', 'G2 cierre'">
        <input value={unlocks} onChange={(e) => setUnlocks(e.target.value)} maxLength={200}
          style={{
            width: '100%', height: 32, padding: '0 10px',
            background: 'var(--bg-0)', border: '1px solid var(--border)',
            borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, outline: 'none',
          }} />
      </FormRow>
      <FormRow label="Notas (Markdown)">
        <textarea rows={4} value={notes} onChange={(e) => setNotes(e.target.value)}
          style={{
            width: '100%', padding: '8px 12px', resize: 'vertical',
            background: 'var(--bg-0)', border: '1px solid var(--border)',
            borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5,
            fontFamily: 'var(--font-mono)', outline: 'none',
          }} />
      </FormRow>
      {error && <div style={{ color: 'var(--danger)', fontSize: 12.5, marginTop: 6 }}>{error}</div>}
    </Modal>
  );
}

Object.assign(window, { PaymentsView, PaymentModal });
