// Institutional CRM — Brokered deals: files ExpressFund shops to outside lenders.
// Tracks the broker pipeline (New File → Submitted → Offers In → Contracts Out → Funded / Dead)
// and every lender submission — offers, declines, stipulations — in one place.
const { fmt: bfmt, fmtK: bfmtK } = window.ICRM;

const BR_TONE = { 'New File': 'blue', 'Submitted': '', 'Offers In': 'amber', 'Contracts Out': 'navy', 'Funded': 'green', 'Dead': 'red' };
const SUB_TONE = { 'Offer Received': 'green', 'Submitted': 'blue', 'Declined': 'red' };
const BR_STAGES = ['New File', 'Submitted', 'Offers In', 'Contracts Out', 'Funded', 'Dead'];

function StipChip({ children }) {
  return <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 11, fontWeight: 600, color: 'var(--inst-ink-2)', border: '1px solid var(--inst-rule)', borderRadius: 20, padding: '3px 10px', whiteSpace: 'nowrap' }}><span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--inst-ink-3)' }}></span>{children}</span>;
}

function FactRow({ k, v }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, padding: '6px 0', borderBottom: '1px solid var(--inst-rule-soft)', fontSize: 13 }}>
      <span style={{ color: 'var(--inst-ink-3)' }}>{k}</span>
      <span style={{ fontWeight: 700, color: 'var(--inst-ink)', textAlign: 'right' }}>{v}</span>
    </div>
  );
}

function SubmissionCard({ s, top }) {
  return (
    <div className="inst-card" style={{ marginBottom: 10 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 14px', borderBottom: '1px solid var(--inst-rule-soft)', flexWrap: 'wrap' }}>
        <span style={{ fontSize: 14, fontWeight: 800, color: 'var(--inst-ink)' }}>{s.lender}</span>
        <Chip tone={SUB_TONE[s.status]}>{s.status}</Chip>
        {top ? <span style={{ fontSize: 10, fontWeight: 800, letterSpacing: '.6px', color: 'var(--inst-blue)', display: 'inline-flex', alignItems: 'center', gap: 4 }}><span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--inst-blue)' }}></span>TOP OFFER</span> : null}
        <span style={{ flex: 1 }}></span>
        <span style={{ fontSize: 12, color: 'var(--inst-ink-3)' }}>{s.when}</span>
      </div>
      {s.status === 'Offer Received' ? (
        <div style={{ padding: '12px 14px 4px' }}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(110px, 1fr))', gap: 10, background: 'var(--inst-canvas)', border: '1px solid var(--inst-rule-soft)', borderRadius: 4, padding: '10px 12px' }}>
            {[['Amount', bfmt(s.amount)], ['Factor', s.factor.toFixed(2)], ['Term', s.termDays + ' d · Daily'], ['Payment', bfmt(s.payment) + ' /d'], ['Upsell', s.upsell + ' pts']].map(([k, v]) => (
              <div key={k}>
                <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '.6px', textTransform: 'uppercase', color: 'var(--inst-ink-3)' }}>{k}</div>
                <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--inst-ink)', fontVariantNumeric: 'tabular-nums', marginTop: 2 }}>{v}</div>
              </div>
            ))}
          </div>
        </div>
      ) : null}
      {s.status === 'Declined' ? (
        <div style={{ padding: '12px 14px 4px' }}>
          <div style={{ background: 'var(--inst-canvas)', border: '1px solid var(--inst-rule-soft)', borderRadius: 4, padding: '10px 12px', fontSize: 13, color: 'var(--inst-ink-3)' }}>No offer extended — see decline reasons below.</div>
        </div>
      ) : null}
      {s.status === 'Submitted' ? (
        <div style={{ padding: '12px 14px 4px' }}>
          <div style={{ background: 'var(--inst-canvas)', border: '1px solid var(--inst-rule-soft)', borderRadius: 4, padding: '10px 12px', fontSize: 13, color: 'var(--inst-ink-3)' }}>In underwriting — awaiting lender response.</div>
        </div>
      ) : null}
      {(s.stips && s.stips.length) || (s.reasons && s.reasons.length) ? (
        <div style={{ padding: '10px 14px 14px' }}>
          <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '.6px', textTransform: 'uppercase', color: 'var(--inst-ink-3)', margin: '2px 0 8px' }}>{s.reasons ? 'Decline reasons' : 'Required stipulations'}</div>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {(s.reasons || s.stips).map(x => <StipChip key={x}>{x}</StipChip>)}
          </div>
        </div>
      ) : <div style={{ height: 10 }}></div>}
    </div>
  );
}

function BrokeredDetail({ d, onAddSubmission }) {
  const offers = d.submissions.filter(s => s.status === 'Offer Received').sort((a, b) => b.amount - a.amount);
  const best = offers[0] || null;
  const declines = d.submissions.filter(s => s.status === 'Declined');
  const sorted = d.submissions.slice().sort((a, b) => (b.amount || 0) - (a.amount || 0));
  return (
    <React.Fragment>
      {d.repaid != null && renewalTier(d.repaid) ? (
        <div className="inst-notice" style={{ marginBottom: 12 }}>
          <span className="bulb"><IC d={ICONS.zap} size={16} /></span>
          <span><b>Renewal eligible</b> — outside advance {Math.round(d.repaid)}% complete{d.fundedBy ? ' with ' + d.fundedBy : ''}, crossed the {renewalTier(d.repaid)}% milestone. Re-shop the file.</span>
          <span style={{ flex: 1 }}></span>
          <button className="inst-btn outline sm" onClick={onAddSubmission}>Log renewal submission</button>
        </div>
      ) : null}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 12, marginBottom: 12 }}>
        <div className="inst-card">
          <div className="inst-card-head">Contact</div>
          <div className="inst-card-body" style={{ padding: '4px 16px 10px' }}>
            <FactRow k="Owner" v={d.owner} />
            <FactRow k="Phone" v={d.phone} />
            <FactRow k="Email" v={d.email} />
            <FactRow k="App score" v={d.appScore} />
            <FactRow k="FICO" v={d.fico} />
          </div>
        </div>
        <div className="inst-card">
          <div className="inst-card-head">Business</div>
          <div className="inst-card-body" style={{ padding: '4px 16px 10px' }}>
            <FactRow k="Industry" v={d.industry} />
            <FactRow k="Requested" v={bfmt(d.requested)} />
            <FactRow k="File opened" v={d.created} />
            <FactRow k="File ID" v={d.id} />
          </div>
        </div>
        <div className="inst-card">
          <div className="inst-card-head">Team & economics</div>
          <div className="inst-card-body" style={{ padding: '4px 16px 10px' }}>
            <FactRow k="Submitter" v={d.submitter} />
            <FactRow k="Rep" v={d.rep} />
            <FactRow k="Broker fee" v={d.feePts + ' pts'} />
            {d.fee != null ? <FactRow k="Fee earned" v={bfmt(d.fee)} /> : best ? <FactRow k="Est. fee on top offer" v={bfmt(best.amount * d.feePts / 100)} /> : null}
          </div>
        </div>
      </div>

      {best ? (
        <div style={{ background: 'var(--inst-navy)', borderRadius: 6, padding: '16px 18px', color: '#fff', display: 'flex', gap: 18, alignItems: 'center', flexWrap: 'wrap', marginBottom: 12 }}>
          <div style={{ flex: 1, minWidth: 220 }}>
            <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '.8px', opacity: .75 }}>MAX OFFER</div>
            <div style={{ fontSize: 30, fontWeight: 800, fontVariantNumeric: 'tabular-nums', lineHeight: 1.15 }}>{bfmt(best.amount)}</div>
            <div style={{ fontSize: 12, opacity: .8, marginTop: 2 }}>from <b>{best.lender}</b> · {best.when}</div>
          </div>
          <div style={{ fontSize: 12, display: 'grid', gap: 3, textAlign: 'right', fontVariantNumeric: 'tabular-nums' }}>
            <span><span style={{ opacity: .7 }}>Factor · </span><b>{best.factor.toFixed(2)}</b></span>
            <span><span style={{ opacity: .7 }}>Term · </span><b>{best.termDays} d</b></span>
            <span><span style={{ opacity: .7 }}>Payment · </span><b>{bfmt(best.payment)} / day</b></span>
            <span><span style={{ opacity: .7 }}>Upsell · </span><b>{best.upsell} pts</b></span>
          </div>
        </div>
      ) : (
        <div className="inst-notice" style={{ marginBottom: 12 }}><span className="bulb"><IC d={ICONS.bulb} size={16} /></span>No offers on the table yet{d.submissions.length ? ' — ' + d.submissions.length + ' lender' + (d.submissions.length > 1 ? 's' : '') + ' shopping the file' : ' — file has not been submitted'}.</div>
      )}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: 12, marginBottom: 12 }}>
        <div className="inst-card inst-stat"><div className="lbl">Total submissions</div><div className="val">{d.submissions.length}</div><div className="sub">Across {d.submissions.length} lenders</div></div>
        <div className="inst-card inst-stat"><div className="lbl">Offers received</div><div className="val" style={{ color: 'var(--inst-pos)' }}>{offers.length}</div><div className="sub">{d.submissions.length ? Math.round(offers.length / d.submissions.length * 100) : 0}% conversion</div></div>
        <div className="inst-card inst-stat"><div className="lbl">Declines</div><div className="val" style={{ color: declines.length ? 'var(--inst-neg)' : 'var(--inst-ink)' }}>{declines.length}</div><div className="sub">{d.submissions.length ? Math.round(declines.length / d.submissions.length * 100) : 0}% of file</div></div>
      </div>

      <div style={{ display: 'flex', alignItems: 'center', gap: 10, margin: '4px 0 10px' }}>
        <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.6px', textTransform: 'uppercase', color: 'var(--inst-ink-3)' }}>Lender submissions · sorted by amount</div>
        <span style={{ flex: 1 }}></span>
        <button className="inst-btn primary sm" onClick={onAddSubmission}>+ Add submission</button>
      </div>
      {sorted.length ? sorted.map((s, i) => <SubmissionCard key={s.lender + i} s={s} top={best && s === best} />) : <div style={{ fontSize: 13, color: 'var(--inst-ink-3)', padding: '4px 0 12px' }}>No submissions yet — add the first lender above.</div>}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: 12, marginTop: 4 }}>
        <div className="inst-card">
          <div className="inst-card-head">Activity log</div>
          <div className="inst-card-body" style={{ padding: '2px 16px 10px' }}><ActivityFeed items={d.activity} /></div>
        </div>
        <div className="inst-card">
          <div className="inst-card-head">Notes</div>
          <div className="inst-card-body" style={{ padding: '12px 16px 14px' }}><NotesCard subject={d} /></div>
        </div>
      </div>
    </React.Fragment>
  );
}

function AddSubmissionModal({ file, onClose, toast }) {
  const [f, setF] = React.useState({ lender: '', status: 'Submitted', amount: '', factor: '1.30', termDays: '200', upsell: '6' });
  const save = () => {
    const sub = { lender: f.lender || 'Unnamed Lender', status: f.status, when: 'Just now' };
    if (f.status === 'Offer Received') {
      sub.amount = parseFloat(f.amount) || 0;
      sub.factor = parseFloat(f.factor) || 1.3;
      sub.termDays = parseInt(f.termDays) || 200;
      sub.payment = sub.amount * sub.factor / sub.termDays;
      sub.upsell = parseInt(f.upsell) || 0;
      sub.stips = [];
    }
    if (f.status === 'Declined') sub.reasons = [];
    file.submissions = [sub].concat(file.submissions);
    file.activity = [{ when: 'Just now', who: 'You', kind: f.status === 'Offer Received' ? 'offer' : f.status === 'Declined' ? 'status' : 'doc', text: (f.status === 'Offer Received' ? 'Offer received · ' : f.status === 'Declined' ? 'Declined · ' : 'File submitted to ') + sub.lender, amount: sub.amount }].concat(file.activity);
    toast('Submission logged · ' + sub.lender);
    onClose();
  };
  return (
    <Modal title={'Add submission · ' + file.biz} onClose={onClose}
      footer={<React.Fragment>
        <button className="inst-btn outline" onClick={onClose}>Cancel</button>
        <button className="inst-btn primary" onClick={save} disabled={!f.lender.trim()}>Log submission</button>
      </React.Fragment>}>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
        <Field label="Lender"><input className="inst-input" value={f.lender} onChange={e => setF({ ...f, lender: e.target.value })} /></Field>
        <Field label="Status">
          <select className="inst-input" value={f.status} onChange={e => setF({ ...f, status: e.target.value })}>
            <option>Submitted</option>
            <option>Offer Received</option>
            <option>Declined</option>
          </select>
        </Field>
        {f.status === 'Offer Received' ? <React.Fragment>
          <Field label="Offer amount"><input className="inst-input" type="text" inputMode="numeric" value={f.amount ? Number(f.amount).toLocaleString('en-US') : ''} onChange={e => setF({ ...f, amount: e.target.value.replace(/[^0-9]/g, '') })} /></Field>
          <Field label="Factor rate"><input className="inst-input" value={f.factor} onChange={e => setF({ ...f, factor: e.target.value })} /></Field>
          <Field label="Term (days)"><input className="inst-input" inputMode="numeric" value={f.termDays} onChange={e => setF({ ...f, termDays: e.target.value.replace(/[^0-9]/g, '') })} /></Field>
          <Field label="Upsell (pts)"><input className="inst-input" inputMode="numeric" value={f.upsell} onChange={e => setF({ ...f, upsell: e.target.value.replace(/[^0-9]/g, '') })} /></Field>
        </React.Fragment> : null}
      </div>
    </Modal>
  );
}

function PgBrokered({ fileId, go, toast }) {
  const { BROKERED } = window.ICRM;
  const [q, setQ] = React.useState('');
  const [stageF, setStageF] = React.useState('');
  const [addFor, setAddFor] = React.useState(null);
  const [, tick] = React.useState(0);
  const bestOf = (d) => d.submissions.filter(s => s.status === 'Offer Received').sort((a, b) => b.amount - a.amount)[0] || null;

  if (fileId) {
    const d = BROKERED.find(x => x.id === fileId);
    const best = d ? bestOf(d) : null;
    return (
      <React.Fragment>
        {addFor ? <AddSubmissionModal file={addFor} toast={toast} onClose={() => { setAddFor(null); tick(t => t + 1); }} /> : null}
        <FilePage crumb="Funding / Brokered deals" backLabel="Back to brokered deals" onBack={() => go('Brokered')}
          title={d ? d.biz : 'File not found'}
          sub={d ? d.id + ' · ' + d.owner + ' · opened ' + d.created + ' · rep ' + d.rep : 'No file matches ' + fileId + '.'}
          chips={d ? <React.Fragment><Chip tone={BR_TONE[d.stage]}>{d.stage}</Chip><RenewalChip pct={d.repaid} /></React.Fragment> : null}
          stats={d ? (
            <div style={{ display: 'flex', gap: 26, textAlign: 'right', flexWrap: 'wrap' }}>
              <div><div className="inst-amount lg">{bfmt(d.requested)}</div><div className="inst-amount-cap">Requested</div></div>
              <div><div className="inst-amount lg">{best ? bfmt(best.amount) : '—'}</div><div className="inst-amount-cap">Max offer</div></div>
            </div>
          ) : null}>
          {d ? <BrokeredDetail d={d} onAddSubmission={() => setAddFor(d)} /> : null}
        </FilePage>
      </React.Fragment>
    );
  }

  const list = BROKERED.filter(d =>
    (!stageF || d.stage === stageF) &&
    (!q || (d.biz + d.owner + d.id).toLowerCase().includes(q.toLowerCase())));
  const openFiles = BROKERED.filter(d => !['Funded', 'Dead'].includes(d.stage));
  const offersIn = BROKERED.reduce((s, d) => s + d.submissions.filter(x => x.status === 'Offer Received').length, 0);
  const feesEarned = BROKERED.reduce((s, d) => s + (d.fee || 0), 0);

  return (
    <div className="inst-page">
      {addFor ? <AddSubmissionModal file={addFor} toast={toast} onClose={() => { setAddFor(null); tick(t => t + 1); }} /> : null}
      <div className="inst-greeting" style={{ marginBottom: 16 }}>Brokered deals</div>
      <div className="inst-grid-4" style={{ marginBottom: 20 }}>
        <div className="inst-card inst-stat"><div className="lbl">Open files</div><div className="val">{openFiles.length}</div><div className="sub">Being shopped</div></div>
        <div className="inst-card inst-stat"><div className="lbl">Offers on the table</div><div className="val" style={{ color: 'var(--inst-pos)' }}>{offersIn}</div><div className="sub">Across all files</div></div>
        <div className="inst-card inst-stat"><div className="lbl">Funded via partners</div><div className="val">{BROKERED.filter(d => d.stage === 'Funded').length}</div><div className="sub">This cycle</div></div>
        <div className="inst-card inst-stat"><div className="lbl">Broker fees earned</div><div className="val">{bfmtK(feesEarned)}</div><div className="sub">On funded files</div></div>
      </div>

      <SectionCard bar="Broker pipeline" right={list.length + ' files'}>
        <div style={{ display: 'flex', gap: 10, padding: '12px 14px', borderBottom: '1px solid var(--inst-rule-soft)', flexWrap: 'wrap' }}>
          <input className="inst-input" style={{ maxWidth: 260 }} placeholder="Search files" value={q} onChange={e => setQ(e.target.value)} />
          <select className="inst-input" style={{ maxWidth: 170 }} value={stageF} onChange={e => setStageF(e.target.value)}>
            <option value="">All stages</option>
            {BR_STAGES.map(s => <option key={s}>{s}</option>)}
          </select>
        </div>
        <div className="inst-table-wrap inst-desktop-only">
          <table className="inst-table">
            <thead><tr><th>Business</th><th style={{ textAlign: 'right' }}>Requested</th><th style={{ textAlign: 'right' }}>Max offer</th><th style={{ textAlign: 'right' }}>Subs</th><th style={{ textAlign: 'right' }}>Offers</th><th>Stage</th><th>Rep</th></tr></thead>
            <tbody>
              {list.map(d => {
                const best = bestOf(d);
                return (
                  <React.Fragment key={d.id}>
                    <tr className="clickable" onClick={() => go('Brokered', d.id)}>
                      <td><span className="inst-td-strong">{d.biz}</span><div className="inst-td-id">{d.id} · {d.owner}</div></td>
                      <td className="inst-td-num">{bfmt(d.requested)}</td>
                      <td className="inst-td-num inst-td-strong">{best ? bfmt(best.amount) : '—'}</td>
                      <td className="inst-td-num">{d.submissions.length}</td>
                      <td className="inst-td-num" style={{ color: 'var(--inst-pos)', fontWeight: 700 }}>{d.submissions.filter(s => s.status === 'Offer Received').length}</td>
                      <td><div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}><Chip tone={BR_TONE[d.stage]}>{d.stage}</Chip><RenewalChip pct={d.repaid} /></div></td>
                      <td>{d.rep}</td>
                    </tr>
                  </React.Fragment>
                );
              })}
            </tbody>
          </table>
        </div>
        <div className="inst-mobile-only">
          {list.map(d => {
            const best = bestOf(d);
            return (
              <div key={d.id} className="inst-rec-card" onClick={() => go('Brokered', d.id)}>
                <div className="inst-rec-top">
                  <span className="inst-td-strong">{d.biz}</span>
                  <span className="inst-td-strong" style={{ fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap' }}>{best ? bfmt(best.amount) : bfmt(d.requested)}</span>
                </div>
                <div className="inst-td-id">{d.id} · {d.owner} · {d.submissions.length} submissions</div>
                <div className="inst-rec-meta">
                  <Chip tone={BR_TONE[d.stage]}>{d.stage}</Chip>
                  <RenewalChip pct={d.repaid} />
                  <span className="dim">{d.rep}</span>
                  <span style={{ flex: 1 }}></span>
                  <span className="dim">Open file ›</span>
                </div>
              </div>
            );
          })}
        </div>
      </SectionCard>
    </div>
  );
}

Object.assign(window, { PgBrokered });
