/* portal-shared.jsx — Portal sidebar, topbar, banner, IBAN dialog, small bits */

const PORTAL_NAV = [
  { k: 'home',    label: 'Início',         icon: 'dashboard' },
  { k: 'cycle',   label: 'Próximo ciclo',  icon: 'cycle',     alert: 'D-7' },
  { k: 'history', label: 'Histórico',      icon: 'contracts', count: 2 },
  { k: 'billing', label: 'Faturas',        icon: 'billing',   count: 2 },
  { k: 'catalog', label: 'Catálogo',       icon: 'products' },
  { k: 'account', label: 'Conta',          icon: 'customers' },
];

function PortalSidebar({ route, onNav, suspended, renewal, ended }) {
  const c = PORTAL_CUSTOMER;
  const sidebarCls = ['sidebar'];
  if (suspended) sidebarCls.push('suspended');
  if (renewal)   sidebarCls.push('renewal');
  if (ended)     sidebarCls.push('ended');

  const cardCls = ['sb-customer'];
  if (suspended) cardCls.push('alert');
  if (renewal)   cardCls.push('renewal');
  if (ended)     cardCls.push('ended');

  return (
    <div className={sidebarCls.join(' ')}>
      <div className="sb-brand">
        <div>
          <div className="logo">RVDE</div>
          <div className="role" style={{ marginTop: 2 }}>portal do cliente</div>
        </div>
        <button className="btn ghost sm" style={{ padding: '0 6px', position: 'relative' }} title="Notificações">
          <Icon k="bell" size={14} />
          {(suspended || renewal) && <span className={'bell-dot' + (renewal ? ' clay' : '')}/>}
        </button>
      </div>

      <div className={cardCls.join(' ')}>
        <div className="name">{c.name}</div>
        <div className="meta">{c.kind} · {c.loc}</div>
        <div className="row between items-c mt-2">
          <span className="id">{c.id}</span>
          {suspended && <span className="badge failed"><span className="dot"/>Suspenso</span>}
          {renewal   && <span className="badge pending"><span className="dot"/>Renovar</span>}
          {ended     && <span className="badge ended"><span className="dot"/>Terminado</span>}
        </div>
      </div>

      <div className="sb-section">
        <div className="label">Contrato</div>
      </div>
      {PORTAL_NAV.map(it => {
        let alert = it.alert;
        let count = it.count;
        let disabled = false;
        if (suspended) {
          if (it.k === 'cycle')   { alert = null; count = null; }
          if (it.k === 'billing') { alert = '!'; count = null; }
        }
        if (renewal) {
          if (it.k === 'cycle')   { alert = null; count = null; }
        }
        if (ended) {
          if (it.k === 'cycle')   { alert = null; count = null; disabled = true; }
        }
        return (
          <div key={it.k}
            className={'sb-item' + (route === it.k ? ' active' : '') + (disabled ? ' disabled' : '')}
            onClick={() => !disabled && onNav(it.k)}>
            <Icon k={it.icon} size={15} />
            <span className="grow truncate">{it.label}</span>
            {alert && <span className={'pill-alert' + (alert === '!' ? ' fail' : '')}>{alert}</span>}
            {count != null && !alert && <span className="count">{count}</span>}
          </div>
        );
      })}

      {renewal && (
        <div
          className={'sb-item renewal-item' + (route === 'renewal' ? ' active' : '')}
          onClick={() => onNav('renewal')}>
          <Icon k="pen" size={15} />
          <span className="grow truncate">Renovação</span>
          <span className="pill-alert">D-60</span>
        </div>
      )}

      <div className="sb-profile">
        <div className="avatar">M</div>
        <div className="grow truncate">
          <div style={{ fontSize: 13, lineHeight: 1.2, fontWeight: 600 }}>Maria Antunes</div>
          <div className="ink-3" style={{ fontSize: 11 }}>Hotel Sereno · receção</div>
        </div>
      </div>
    </div>
  );
}

function PortalTopBar({ crumbs, suspended, renewal, ended }) {
  return (
    <div className="topbar">
      <div className="crumb">
        {crumbs.map((c, i) => (
          <React.Fragment key={i}>
            {i > 0 && <span className="sep">/</span>}
            <span style={{
              color: i === crumbs.length - 1 ? 'var(--ink)' : 'var(--ink-3)',
              fontWeight: i === crumbs.length - 1 ? 500 : 400,
            }}>{c}</span>
          </React.Fragment>
        ))}
      </div>
      <div style={{ flex: 1 }} />
      {!suspended && !renewal && !ended && (
        <div className="row gap-3" style={{ fontSize: 12, color: 'var(--ink-3)' }}>
          <span className="mono">{PORTAL_TODAY}</span>
          <span style={{ opacity: 0.5 }}>·</span>
          <span>D-7 a <span className="mono" style={{color:'var(--clay)'}}>{PORTAL_D7_DATE}</span></span>
        </div>
      )}
      {suspended && (
        <div className="row gap-3" style={{ fontSize: 12, color: 'var(--clay-deep)' }}>
          <span className="mono">{PORTAL_SUSPENDED.today}</span>
          <span style={{ opacity: 0.5 }}>·</span>
          <span>resolve até <span className="mono" style={{color:'var(--clay-deep)', fontWeight: 600}}>{PORTAL_SUSPENDED.deadline}</span></span>
        </div>
      )}
      {renewal && (
        <div className="row gap-3" style={{ fontSize: 12, color: 'var(--clay)' }}>
          <span className="mono">{PORTAL_RENEWAL.today}</span>
          <span style={{ opacity: 0.5 }}>·</span>
          <span>decisão até <span className="mono" style={{color:'var(--clay)', fontWeight: 600}}>{PORTAL_RENEWAL.noticeBy}</span></span>
        </div>
      )}
      {ended && (
        <div className="row gap-3" style={{ fontSize: 12, color: 'var(--ink-3)' }}>
          <span className="mono">{PORTAL_ENDED.today}</span>
          <span style={{ opacity: 0.5 }}>·</span>
          <span>arquivo até <span className="mono">{PORTAL_ENDED.archiveUntil}</span></span>
        </div>
      )}
      <button className="btn outline sm">
        <Icon k="download" size={13} /> Contrato (PDF)
      </button>
    </div>
  );
}

/* Renewal banner — runs across the top of every screen in renewal mode */
function RenewalBanner({ onOpenRenewal }) {
  const r = PORTAL_RENEWAL;
  return (
    <div className="renew-banner">
      <div className="renew-icon">
        <Icon k="pen" size={16} color="var(--bone)"/>
      </div>
      <div className="grow">
        <div className="renew-title">
          O contrato renova-se em {r.daysToDecide} dias · 14 SET 2026
        </div>
        <div className="renew-sub">
          Por defeito renova tal-qual por mais 24 meses. Decide até <strong>{r.noticeBy}</strong> se queres renegociar ou denunciar.
        </div>
      </div>
      <button className="btn clay" onClick={onOpenRenewal}>
        Ver opções →
      </button>
    </div>
  );
}

/* ── Suspended banner — runs across the top of every screen ──────── */
function SuspendedBanner({ onOpenIban, onNav }) {
  const s = PORTAL_SUSPENDED;
  return (
    <div className="susp-banner">
      <div className="susp-icon">
        <Icon k="bell" size={16} color="#fff"/>
      </div>
      <div className="grow">
        <div className="susp-title">
          Cobrança SEPA bloqueada · ciclo Q3 em pausa
        </div>
        <div className="susp-sub">
          Tentámos {s.retries.length} débitos de <strong>{CRM_FMT_EUR(s.amount)}</strong> desde {s.failedOn} —
          devolvidos com <span className="mono">{s.reasonCode} · {s.reasonLabel.toLowerCase()}</span>.
          Resolve até <strong>{s.deadline}</strong> para a encomenda partir.
        </div>
      </div>
      <div className="row gap-2 susp-actions">
        <button className="btn outline sm" style={{
          borderColor: 'rgba(255,255,255,0.4)', color: '#fff',
        }} onClick={() => onNav && onNav('billing')}>
          Pagar por transferência
        </button>
        <button className="btn sm susp-cta" onClick={onOpenIban}>
          <Icon k="sepa" size={13}/> Atualizar IBAN
        </button>
      </div>
    </div>
  );
}

/* ── IBAN update dialog ──────────────────────────────────────────── */
function IbanDialog({ open, onClose }) {
  const [iban, setIban] = React.useState('');
  const [bank, setBank] = React.useState('');
  const [holder, setHolder] = React.useState(PORTAL_CUSTOMER.name + ' Lda.');
  const [accepted, setAccepted] = React.useState(false);
  const [phase, setPhase] = React.useState('form'); // 'form' | 'success'

  if (!open) return null;

  const valid = iban.replace(/\s/g,'').length >= 21 && bank && accepted;
  const submit = () => {
    if (valid) setPhase('success');
  };
  const close = () => {
    setIban(''); setBank(''); setAccepted(false); setPhase('form');
    onClose();
  };

  return (
    <div className="modal-backdrop" onClick={close}>
      <div className="modal-card" onClick={e => e.stopPropagation()}>
        {phase === 'form' && (
          <>
            <div className="modal-head">
              <div>
                <div className="smallcaps">Resolver cobrança · ciclo Q3</div>
                <h2 className="section-title mt-1" style={{ fontSize: 24 }}>Atualizar IBAN</h2>
              </div>
              <button className="btn ghost sm icon-only" onClick={close} title="Fechar">
                <Icon k="x" size={13}/>
              </button>
            </div>

            <div className="modal-body stack gap-4">
              <div className="card surface-2 flat" style={{ padding: '12px 14px' }}>
                <div className="row gap-3" style={{ alignItems: 'flex-start' }}>
                  <div style={{
                    width: 22, height: 22, borderRadius: '50%',
                    background: 'var(--clay-deep)', color: 'var(--bone)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontFamily: 'var(--mono)', fontSize: 11, fontWeight: 700,
                    flexShrink: 0,
                  }}>!</div>
                  <div style={{ fontSize: 12.5, lineHeight: 1.55, color:'var(--ink-2)' }}>
                    O IBAN atual <span className="mono" style={{fontSize:11.5}}>{PORTAL_MANDATE.iban}</span> foi
                    devolvido com motivo <span className="mono">AC04</span>. Indica um novo IBAN e
                    voltamos a tentar o débito <strong>3 dias depois</strong>.
                  </div>
                </div>
              </div>

              <div className="field">
                <span className="lbl">Novo IBAN</span>
                <input
                  className="input mono"
                  placeholder="PT50 0000 0000 0000 0000 0 00"
                  value={iban}
                  onChange={e => setIban(e.target.value)}
                  autoFocus
                />
                <span className="ink-3" style={{ fontSize: 11.5, marginTop: 2 }}>
                  25 caracteres · começa por PT50
                </span>
              </div>

              <div className="grid gap-3" style={{ gridTemplateColumns: '1fr 1fr' }}>
                <div className="field">
                  <span className="lbl">Banco</span>
                  <input className="input" placeholder="ex: Millennium BCP" value={bank} onChange={e => setBank(e.target.value)}/>
                </div>
                <div className="field">
                  <span className="lbl">Titular da conta</span>
                  <input className="input" value={holder} onChange={e => setHolder(e.target.value)}/>
                </div>
              </div>

              <div className="row gap-2" style={{ alignItems:'flex-start' }}>
                <div className={'iban-check ' + (accepted ? 'on' : '')}
                  onClick={() => setAccepted(!accepted)}/>
                <span style={{ fontSize: 12.5, lineHeight: 1.55, color: 'var(--ink-2)' }}>
                  Confirmo que sou titular ou autorizado da conta indicada, e autorizo o débito da
                  fatura <span className="mono">{PORTAL_SUSPENDED.invoice}</span> ({CRM_FMT_EUR(PORTAL_SUSPENDED.amount)})
                  e cobranças futuras conforme o mandato SEPA B2B já assinado.
                </span>
              </div>
            </div>

            <div className="modal-foot">
              <button className="btn ghost" onClick={close}>Cancelar</button>
              <div style={{ flex: 1 }}/>
              <button className="btn outline">
                Preferir transferência
              </button>
              <button className="btn clay" disabled={!valid} onClick={submit}>
                <Icon k="check" size={13}/> Atualizar e retentar
              </button>
            </div>
          </>
        )}

        {phase === 'success' && (
          <>
            <div className="modal-head">
              <div>
                <div className="smallcaps">IBAN atualizado</div>
                <h2 className="section-title mt-1" style={{ fontSize: 24 }}>Vamos voltar a tentar.</h2>
              </div>
              <button className="btn ghost sm icon-only" onClick={close} title="Fechar">
                <Icon k="x" size={13}/>
              </button>
            </div>

            <div className="modal-body stack gap-4">
              <div style={{
                display: 'flex', justifyContent: 'center', padding: '8px 0 4px',
              }}>
                <div style={{
                  width: 64, height: 64, borderRadius:'50%',
                  background:'var(--clay)', color:'var(--bone)',
                  display:'flex', alignItems:'center', justifyContent:'center',
                }}>
                  <Icon k="check" size={30} color="var(--bone)"/>
                </div>
              </div>

              <div className="italic-serif" style={{ textAlign:'center', fontSize: 16, lineHeight: 1.5, color:'var(--ink-2)' }}>
                Recebemos o novo IBAN <span className="mono" style={{ color: 'var(--ink)', fontSize: 13 }}>{iban || 'PT50…'}</span>.
                Volta a tentar-se o débito a <strong style={{color:'var(--clay)'}}>25 SET 2025</strong>.
              </div>

              <div className="grid gap-2" style={{ gridTemplateColumns: 'repeat(3, 1fr)' }}>
                {[
                  ['Próxima tentativa', '25 SET 2025'],
                  ['Valor a debitar',    CRM_FMT_EUR(PORTAL_SUSPENDED.amount)],
                  ['Se OK · expedição', '~28 SET 2025'],
                ].map(([k,v]) => (
                  <div key={k} className="card surface-2 flat" style={{ padding:'12px 14px' }}>
                    <div className="smallcaps">{k}</div>
                    <div className="mono mt-1" style={{ fontSize: 13 }}>{v}</div>
                  </div>
                ))}
              </div>

              <div className="ink-3" style={{ fontSize: 11.5, textAlign:'center', fontStyle:'italic' }}>
                Avisamos-te por email quando o débito for aceite — e Jorge fica também a saber.
              </div>
            </div>

            <div className="modal-foot">
              <div style={{ flex: 1 }}/>
              <button className="btn clay" onClick={close}>Voltar ao portal</button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

/* Small reusable: term row */
function Term({ label, value, mono, clay }) {
  return (
    <div>
      <div className="smallcaps">{label}</div>
      <div className={'mt-1 ' + (mono ? 'mono tab ' : '') + (clay ? 'clay ' : '')} style={{ fontSize: 13.5 }}>{value}</div>
    </div>
  );
}

/* Product art placeholder — striped slot with code overlay */
function ProductArt({ code, kind }) {
  const letter = (code || '?').split('-')[0] || '?';
  return (
    <div className="product-art">
      <div className="ref">{code}</div>
      <div className="display" style={{
        fontSize: 38, color: 'var(--clay)',
        fontStyle: 'italic', letterSpacing: '-0.04em',
        opacity: 0.45,
      }}>
        {letter.slice(0,3).toLowerCase()}
      </div>
    </div>
  );
}

Object.assign(window, {
  PortalSidebar, PortalTopBar, SuspendedBanner, RenewalBanner, IbanDialog,
  Term, ProductArt, PORTAL_NAV,
});
