// Simulador de financiamento (2026-10-07) — SAC e Price, com as faixas do Minha Casa Minha Vida.
// Usado na aba Crédito da ficha (clientes-editar.jsx → salva em form.simulacao) e solto pelo card
// "Simulador de financiamento" em Integrações (window.horosOpenSimulator()).
// Valores de referência: taxas e tetos mudam — a tela sempre diz que é estimativa e aponta o simulador da CAIXA.
// CSS: .fsim-* no fim de styles.css.

const FSIM_MODES = [
  // renda até (familiar bruta), taxa de referência a.a. (topo da faixa, conservadora), teto do imóvel, subsídio possível
  { id:'f1',   label:'MCMV Faixa 1', rendaMax: 2850,  taxa: 4.25,  teto: 264000, subsidio: true,  hint:'Renda até R$ 2.850' },
  { id:'f2',   label:'MCMV Faixa 2', rendaMax: 4700,  taxa: 7.00,  teto: 264000, subsidio: true,  hint:'Renda até R$ 4.700' },
  { id:'f3',   label:'MCMV Faixa 3', rendaMax: 8600,  taxa: 8.16,  teto: 350000, subsidio: false, hint:'Renda até R$ 8.600' },
  { id:'f4',   label:'MCMV Faixa 4', rendaMax: 12000, taxa: 10.00, teto: 500000, subsidio: false, hint:'Renda até R$ 12.000' },
  { id:'sbpe', label:'SBPE (mercado)', rendaMax: null, taxa: 11.49, teto: null, subsidio: false, hint:'Sem limite de renda' },
];
const FSIM_COTA = 80;           // % do imóvel que o banco costuma financiar
const FSIM_COMPROMETIMENTO = 30; // % da renda bruta que a parcela pode ocupar

function fsimNum(v) {
  if (v == null || v === '') return 0;
  if (typeof v === 'number') return Number.isFinite(v) ? v : 0;
  const s = String(v).replace(/[R$\s]/g, '');
  const n = parseFloat(s.replace(/\./g, '').replace(',', '.'));
  return Number.isFinite(n) ? n : 0;
}
function fsimBRL(v, dec = 2) {
  return (Number(v) || 0).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: dec, maximumFractionDigits: dec });
}
const fsimPct = (v, d = 1) => (Number(v) || 0).toFixed(d).replace('.', ',');
function fsimMask(v) {
  const d = String(v || '').replace(/\D/g, '');
  if (!d) return '';
  return (parseInt(d, 10) / 100).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
function fsimModeFor(renda) {
  if (!renda) return 'sbpe';
  const m = FSIM_MODES.find(x => x.rendaMax && renda <= x.rendaMax);
  return m ? m.id : 'sbpe';
}

// Cálculo puro (exportado em window para teste)
function fsimCalc({ valor, entrada, fgts, subsidio, taxaAA, prazo, sistema, extras, renda }) {
  const P = Math.max(0, valor - entrada - fgts - subsidio);
  const n = Math.max(1, Math.round(prazo));
  const i = Math.pow(1 + taxaAA / 100, 1 / 12) - 1;   // taxa efetiva anual → mensal equivalente
  let primeira, ultima, total, juros, saldoAno = [];
  if (P <= 0) return { P: 0, n, i, primeira: 0, ultima: 0, total: 0, juros: 0, saldoAno: [], maxPorRenda: 0 };
  if (sistema === 'price') {
    const pmt = i === 0 ? P / n : P * i / (1 - Math.pow(1 + i, -n));
    primeira = ultima = pmt;
    total = pmt * n;
    juros = total - P;
    for (let y = 1; y * 12 <= n; y++) {
      const k = y * 12;
      const saldo = i === 0 ? P - pmt * k : P * Math.pow(1 + i, k) - pmt * (Math.pow(1 + i, k) - 1) / i;
      saldoAno.push({ ano: y, parcela: pmt, saldo: Math.max(0, saldo) });
    }
  } else {
    const a = P / n;
    primeira = a + P * i;
    ultima = a + a * i;
    juros = i * a * n * (n + 1) / 2;
    total = P + juros;
    for (let y = 1; y * 12 <= n; y++) {
      const k = y * 12;            // parcela do mês k (último do ano) e saldo depois dele
      saldoAno.push({ ano: y, parcela: a + (P - a * (k - 1)) * i, saldo: Math.max(0, P - a * k) });
    }
  }
  // Quanto a renda permite financiar (parcela ≤ 30% da renda, já tirando seguros/taxas)
  const parcelaMax = renda * FSIM_COMPROMETIMENTO / 100 - extras;
  let maxPorRenda = 0;
  if (parcelaMax > 0) {
    maxPorRenda = sistema === 'price'
      ? (i === 0 ? parcelaMax * n : parcelaMax * (1 - Math.pow(1 + i, -n)) / i)
      : parcelaMax / (1 / n + i);
  }
  return { P, n, i, primeira: primeira + extras, ultima: ultima + extras, total: total + extras * n, juros, saldoAno, maxPorRenda, parcelaMax };
}

function FsimMoney({ label, value, onChange, hint }) {
  return (
    <label className="fsim-field">
      <span>{label}</span>
      <div className="fsim-money"><em>R$</em><input inputMode="numeric" value={value} placeholder="0,00" onChange={e => onChange(fsimMask(e.target.value))} /></div>
      {hint && <small>{hint}</small>}
    </label>
  );
}

function HorosFinSimulator({ initial = {}, onSave, saveLabel = 'Salvar na ficha', compact }) {
  const init = initial || {};
  const prev = init.simulacao || {};
  const rendaIni = fsimNum(prev.renda ?? init.renda);
  const [f, setF] = React.useState(() => ({
    renda: fsimMask(Math.round(rendaIni * 100)),
    valor: fsimMask(Math.round(fsimNum(prev.valorImovel ?? init.valor) * 100)),
    entrada: fsimMask(Math.round(fsimNum(prev.entrada ?? init.entrada) * 100)),
    fgts: fsimMask(Math.round(fsimNum(prev.fgts ?? init.fgts) * 100)),
    subsidio: fsimMask(Math.round(fsimNum(prev.subsidio) * 100)),
    extras: fsimMask(Math.round(fsimNum(prev.extras) * 100)),
    mode: prev.modalidade || fsimModeFor(rendaIni),
    taxa: String(prev.taxa ?? (FSIM_MODES.find(m => m.id === (prev.modalidade || fsimModeFor(rendaIni))) || FSIM_MODES[4]).taxa).replace('.', ','),
    prazo: String(prev.prazo || init.prazo || 420),
    sistema: prev.sistema || 'sac',
  }));
  const [savedAt, setSavedAt] = React.useState(prev.em || null);
  const set = (k, v) => setF(x => ({ ...x, [k]: v }));
  const mode = FSIM_MODES.find(m => m.id === f.mode) || FSIM_MODES[4];
  const pickMode = (id) => {
    const m = FSIM_MODES.find(x => x.id === id);
    setF(x => ({ ...x, mode: id, taxa: String(m.taxa).replace('.', ','), subsidio: m.subsidio ? x.subsidio : '' }));
  };

  const v = {
    renda: fsimNum(f.renda), valor: fsimNum(f.valor), entrada: fsimNum(f.entrada), fgts: fsimNum(f.fgts),
    subsidio: mode.subsidio ? fsimNum(f.subsidio) : 0, extras: fsimNum(f.extras),
    taxaAA: fsimNum(f.taxa), prazo: Math.min(420, Math.max(12, parseInt(f.prazo, 10) || 0)),
  };
  const r = fsimCalc({ ...v, sistema: f.sistema });
  const sugerida = fsimModeFor(v.renda);
  const cotaPct = v.valor ? r.P / v.valor * 100 : 0;
  const compPct = v.renda ? r.primeira / v.renda * 100 : 0;

  const alerts = [];
  if (v.valor && r.P <= 0) alerts.push({ k:'ok', t:'Entrada, FGTS e subsídio cobrem o imóvel: não precisa financiar.' });
  if (mode.rendaMax && v.renda > mode.rendaMax) alerts.push({ k:'bad', t:`A renda informada passa do limite da ${mode.label} (${fsimBRL(mode.rendaMax, 0)}). Pela renda, a modalidade seria ${FSIM_MODES.find(m => m.id === sugerida).label}.` });
  if (mode.teto && v.valor > mode.teto) alerts.push({ k:'bad', t:`O imóvel passa do teto de referência da ${mode.label} (${fsimBRL(mode.teto, 0)}; o teto exato depende da cidade).` });
  if (r.P > 0 && cotaPct > FSIM_COTA) alerts.push({ k:'warn', t:`O financiamento é ${fsimPct(cotaPct, 0)}% do imóvel. Os bancos costumam financiar até ${FSIM_COTA}%: falta ${fsimBRL(r.P - v.valor * FSIM_COTA / 100, 0)} de entrada.` });
  if (r.P > 0 && v.renda && compPct > FSIM_COMPROMETIMENTO) alerts.push({ k:'bad', t:`A 1ª parcela ocupa ${fsimPct(compPct)}% da renda (o limite costuma ser ${FSIM_COMPROMETIMENTO}%). Com essa renda, dá para financiar até ${fsimBRL(r.maxPorRenda, 0)}.` });
  if (r.P > 0 && v.renda && compPct <= FSIM_COMPROMETIMENTO && cotaPct <= FSIM_COTA) alerts.push({ k:'ok', t:`Parcela dentro de ${FSIM_COMPROMETIMENTO}% da renda (${fsimPct(compPct)}%) e financiamento de ${fsimPct(cotaPct, 0)}% do imóvel.` });

  const marks = r.saldoAno.filter(s => [1, 5, 10, 15, 20, 25, 30, 35].includes(s.ano));

  const save = () => {
    const sim = {
      modalidade: mode.id, modalidadeLabel: mode.label, sistema: f.sistema,
      renda: v.renda, valorImovel: v.valor, entrada: v.entrada, fgts: v.fgts, subsidio: v.subsidio, extras: v.extras,
      taxa: v.taxaAA, prazo: v.prazo, financiado: Math.round(r.P * 100) / 100,
      primeiraParcela: Math.round(r.primeira * 100) / 100, ultimaParcela: Math.round(r.ultima * 100) / 100,
      totalPago: Math.round(r.total * 100) / 100, juros: Math.round(r.juros * 100) / 100,
      comprometimento: Math.round(compPct * 10) / 10, maxPorRenda: Math.round(r.maxPorRenda),
      em: new Date().toISOString(),
    };
    onSave && onSave(sim);
    setSavedAt(sim.em);
  };

  const text = () => [
    `Simulação de financiamento — ${mode.label} · ${f.sistema === 'sac' ? 'SAC' : 'Price'}`,
    `Imóvel: ${fsimBRL(v.valor)}`,
    `Entrada: ${fsimBRL(v.entrada)}${v.fgts ? ` · FGTS: ${fsimBRL(v.fgts)}` : ''}${v.subsidio ? ` · Subsídio: ${fsimBRL(v.subsidio)}` : ''}`,
    `Financiado: ${fsimBRL(r.P)} em ${v.prazo} meses · juros de ${f.taxa}% a.a.`,
    f.sistema === 'sac' ? `1ª parcela: ${fsimBRL(r.primeira)} · última: ${fsimBRL(r.ultima)}` : `Parcela: ${fsimBRL(r.primeira)}`,
    `*Estimativa sem valor de proposta. Taxas, subsídio e aprovação dependem da análise do banco.*`,
  ].join('\n');
  const [copied, setCopied] = React.useState(false);

  return (
    <div className={'fsim' + (compact ? ' fsim--compact' : '')}>
      <div className="fsim-modes" role="tablist">
        {FSIM_MODES.map(m => (
          <button key={m.id} type="button" className={'fsim-mode' + (f.mode === m.id ? ' on' : '')} onClick={() => pickMode(m.id)} title={m.hint}>
            <b>{m.label}</b><span>{m.hint}</span>
            {sugerida === m.id && v.renda > 0 && <i>pela renda</i>}
          </button>
        ))}
      </div>

      <div className="fsim-body">
        <div className="fsim-form">
          <FsimMoney label="Renda familiar bruta" value={f.renda} onChange={x => set('renda', x)} />
          <FsimMoney label="Valor do imóvel" value={f.valor} onChange={x => set('valor', x)} />
          <FsimMoney label="Entrada" value={f.entrada} onChange={x => set('entrada', x)} />
          <FsimMoney label="FGTS" value={f.fgts} onChange={x => set('fgts', x)} />
          {mode.subsidio && <FsimMoney label="Subsídio" value={f.subsidio} onChange={x => set('subsidio', x)} hint="Até R$ 55 mil nas Faixas 1 e 2; o valor exato depende da cidade e da renda" />}
          <label className="fsim-field">
            <span>Juros ao ano</span>
            <div className="fsim-money"><input inputMode="decimal" value={f.taxa} onChange={e => set('taxa', e.target.value.replace(/[^\d,]/g, ''))} /><em>% a.a.</em></div>
          </label>
          <label className="fsim-field">
            <span>Prazo</span>
            <div className="fsim-money"><input inputMode="numeric" value={f.prazo} onChange={e => set('prazo', e.target.value.replace(/\D/g, '').slice(0, 3))} /><em>meses</em></div>
            <small>Até 420 meses (35 anos)</small>
          </label>
          <FsimMoney label="Seguros e taxas por mês" value={f.extras} onChange={x => set('extras', x)} hint="Opcional: seguros MIP/DFI e taxa de administração" />
          <div className="fsim-field">
            <span>Sistema de amortização</span>
            <div className="fsim-seg">
              <button type="button" className={f.sistema === 'sac' ? 'on' : ''} onClick={() => set('sistema', 'sac')}>SAC</button>
              <button type="button" className={f.sistema === 'price' ? 'on' : ''} onClick={() => set('sistema', 'price')}>Price</button>
            </div>
            <small>{f.sistema === 'sac' ? 'Parcela começa maior e diminui todo mês' : 'Parcela igual do começo ao fim'}</small>
          </div>
        </div>

        <div className="fsim-out">
          <div className="fsim-kpis">
            <div className="fsim-kpi"><span>Valor financiado</span><b>{fsimBRL(r.P, 0)}</b><small>{v.valor ? `${fsimPct(cotaPct, 0)}% do imóvel` : '—'}</small></div>
            <div className="fsim-kpi"><span>{f.sistema === 'sac' ? '1ª parcela' : 'Parcela'}</span><b>{fsimBRL(r.primeira)}</b><small>{v.renda ? `${fsimPct(compPct)}% da renda` : 'informe a renda'}</small></div>
            {f.sistema === 'sac' && <div className="fsim-kpi"><span>Última parcela</span><b>{fsimBRL(r.ultima)}</b><small>{r.n} meses</small></div>}
            <div className="fsim-kpi"><span>Total pago</span><b>{fsimBRL(r.total, 0)}</b><small>{fsimBRL(r.juros, 0)} de juros</small></div>
            <div className="fsim-kpi"><span>Financia pela renda</span><b>{v.renda ? fsimBRL(r.maxPorRenda, 0) : '—'}</b><small>parcela até {FSIM_COMPROMETIMENTO}% da renda</small></div>
          </div>

          {alerts.map((a, k) => <div key={k} className={'fsim-alert fsim-alert--' + a.k}>{a.t}</div>)}

          {marks.length > 0 && (
            <table className="fsim-table">
              <thead><tr><th>Ano</th><th>Parcela no fim do ano</th><th>Saldo devedor</th></tr></thead>
              <tbody>{marks.map(s => <tr key={s.ano}><td>{s.ano}º</td><td>{fsimBRL(s.parcela + v.extras)}</td><td>{fsimBRL(s.saldo, 0)}</td></tr>)}</tbody>
            </table>
          )}

          <div className="fsim-note">
            Estimativa com juros efetivos convertidos para o mês, sem TR. Taxas e tetos são de referência e mudam; a aprovação, o subsídio e as condições finais dependem da análise do banco.{' '}
            <a href="https://www8.caixa.gov.br/siopiinternet-web/simulaOperacaoInternet.do?method=inicializarCasoUso" target="_blank" rel="noopener noreferrer">Simulador da CAIXA</a>
          </div>

          <div className="fsim-actions">
            <button type="button" className="fsim-btn" onClick={() => { navigator.clipboard?.writeText(text()); setCopied(true); setTimeout(() => setCopied(false), 1500); }}>
              <Icon name={copied ? 'check' : 'copy'} size={15} /> {copied ? 'Copiado' : 'Copiar para enviar ao cliente'}
            </button>
            {onSave && (
              <button type="button" className="fsim-btn fsim-btn--primary" onClick={save} disabled={!r.P}>
                <Icon name="check" size={15} /> {saveLabel}
              </button>
            )}
            {savedAt && onSave && <span className="fsim-saved">Simulação de {new Date(savedAt).toLocaleDateString('pt-BR')} na ficha</span>}
          </div>
        </div>
      </div>
    </div>
  );
}

// Janela solta (card de Integrações, Horos 360…)
function HorosFinSimulatorModal({ initial, onSave, onClose }) {
  React.useEffect(() => {
    const k = e => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', k);
    return () => window.removeEventListener('keydown', k);
  }, []);
  return ReactDOM.createPortal(
    <div className="fsim-ov" onClick={onClose}>
      <div className="fsim-modal" role="dialog" aria-label="Simulador de financiamento" onClick={e => e.stopPropagation()}>
        <div className="fsim-modal-head">
          <div>
            <div className="fsim-modal-title">Simulador de financiamento</div>
            <div className="fsim-modal-sub">SAC, Price e faixas do Minha Casa Minha Vida</div>
          </div>
          <button type="button" className="fsim-x" onClick={onClose} title="Fechar (Esc)"><Icon name="close" size={18} /></button>
        </div>
        <div className="fsim-modal-body"><HorosFinSimulator initial={initial} onSave={onSave} /></div>
      </div>
    </div>,
    document.body
  );
}

function horosOpenSimulator(opts = {}) {
  let host = document.getElementById('fsim-host');
  if (!host) { host = document.createElement('div'); host.id = 'fsim-host'; document.body.appendChild(host); }
  const root = host._root || (host._root = ReactDOM.createRoot(host));
  const close = () => root.render(null);
  root.render(<HorosFinSimulatorModal initial={opts.initial} onSave={opts.onSave} onClose={close} />);
}

Object.assign(window, { HorosFinSimulator, HorosFinSimulatorModal, horosOpenSimulator, fsimCalc });
