// Deals list page + Deal detail page
const { useState: useS_D, useEffect: useE_D, useMemo: useM_D } = React;

function DealsListPage({ navigate, initialQuery }) {
  const [data, setData] = useS_D(null);
  const [sort, setSort] = useS_D('latest_filing_date');
  const [industry, setIndustry] = useS_D('all');
  const [openOnly, setOpenOnly] = useS_D(false);
  const [search, setSearch] = useS_D(initialQuery || '');
  const [searchResults, setSearchResults] = useS_D(null);
  const [page, setPage] = useS_D(0);
  const limit = 50;

  useE_D(() => {
    setData(null);
    window.api(`/api/deals?real_estate=1&limit=${limit}&offset=${page * limit}&sort=${sort}`)
      .then(r => setData(r.results));
  }, [sort, page]);

  useE_D(() => {
    if (!search.trim()) { setSearchResults(null); return; }
    let cancel = false;
    const t = setTimeout(() => {
      window.api('/api/search?q=' + encodeURIComponent(search.trim()))
        .then(r => { if (!cancel) setSearchResults(r); });
    }, 250);
    return () => { cancel = true; clearTimeout(t); };
  }, [search]);

  const rows = useM_D(() => {
    let list = searchResults ? searchResults.deals : data;
    if (!list) return null;
    if (industry !== 'all') {
      list = list.filter(d => d.industry_group_type === industry);
    }
    if (openOnly) {
      list = list.filter(d => d.is_open === 1);
    }
    return list;
  }, [data, searchResults, industry, openOnly]);

  return (
    <>
      <div className="page-head">
        <div>
          <h1>Deals</h1>
          <p>52,028 attributed real-estate offerings · sortable, filterable, with full amendment history.</p>
        </div>
        <div className="page-head-actions">
          <span style={{ fontSize: 12, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
            {rows ? `${rows.length.toLocaleString()} shown` : '—'}
          </span>
        </div>
      </div>

      <div className="filter-bar">
        <div className="search">
          <span className="search-icon"><I.search /></span>
          <input type="text" placeholder="Search deals & sponsors…" value={search}
                 onChange={(e) => setSearch(e.target.value)} />
        </div>
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.06em', marginRight: 4 }}>Type</span>
          {['all','Commercial','Residential','Other Real Estate'].map(i => (
            <button key={i} className={`chip ${industry === i ? 'active' : ''}`} onClick={() => setIndustry(i)}>
              {i === 'all' ? 'All' : window.industryShort(i)}
            </button>
          ))}
        </div>
        <div style={{ width: 1, height: 20, background: 'var(--line)' }}></div>
        <button className={`chip ${openOnly ? 'active' : ''}`} onClick={() => setOpenOnly(!openOnly)}>
          <span className="status-dot open" style={{ width: 5, height: 5 }}></span>
          Active only
        </button>
        <div style={{ flex: 1 }}></div>
        <div className="sort-bar">
          <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Sort</span>
          <button className={`sort-btn ${sort === 'latest_filing_date' ? 'active' : ''}`} onClick={() => { setSort('latest_filing_date'); setPage(0); }}>
            Most recent {sort === 'latest_filing_date' && <I.desc />}
          </button>
          <button className={`sort-btn ${sort === 'total_raised' ? 'active' : ''}`} onClick={() => { setSort('total_raised'); setPage(0); }}>
            Total raised {sort === 'total_raised' && <I.desc />}
          </button>
        </div>
      </div>

      <div className="deal-table">
        <div className="dt-head">
          <div>Deal</div>
          <div style={{ textAlign: 'right' }}>Total raised</div>
          <div>Lifespan</div>
          <div>Location</div>
          <div style={{ textAlign: 'center' }}>Filings</div>
          <div>Status</div>
        </div>
        {!rows && Array.from({ length: 12 }).map((_, i) => (
          <div className="dt-row" key={i}>
            <div className="dt-name">
              <div className="skel" style={{ height: 14, width: '60%' }}></div>
              <div className="skel" style={{ height: 10, width: '40%', marginTop: 4 }}></div>
            </div>
            <div className="skel" style={{ height: 12, width: 60, marginLeft: 'auto' }}></div>
            <div className="skel" style={{ height: 12, width: 80 }}></div>
            <div className="skel" style={{ height: 12, width: 60 }}></div>
            <div className="skel" style={{ height: 12, width: 40, margin: '0 auto' }}></div>
            <div className="skel" style={{ height: 12, width: 60 }}></div>
          </div>
        ))}
        {rows && rows.length === 0 && <div className="empty">No deals match these filters.</div>}
        {rows && rows.map(d => <DealRow key={d.deal_id} d={d} navigate={navigate} />)}

        {!searchResults && rows && (
          <div className="pager">
            <span>Page {page + 1} · showing {page * limit + 1}–{page * limit + rows.length}</span>
            <div className="pager-controls">
              <button className="btn" disabled={page === 0} onClick={() => setPage(p => Math.max(0, p - 1))}>
                <I.chevL /> Prev
              </button>
              <button className="btn" onClick={() => setPage(p => p + 1)}>
                Next <I.chevR />
              </button>
            </div>
          </div>
        )}
      </div>

      {searchResults && searchResults.sponsors?.length > 0 && (
        <div style={{ marginTop: 24 }}>
          <div className="page-head" style={{ marginBottom: 12 }}>
            <div><h1 style={{ fontSize: 20 }}>Matching sponsors</h1></div>
          </div>
          <div className="card">
            {searchResults.sponsors.map((s, i) => (
              <div className="leaderboard-row" key={s.sponsor_id} onClick={() => navigate({ name: 'sponsor', id: s.sponsor_id })}>
                <span className="lb-rank">{String(i + 1).padStart(2, '0')}</span>
                <div><div className="lb-name">{s.canonical_name}</div></div>
                <div className="lb-amount">{window.fmtMoney(s.total_raised)}</div>
                <div className="lb-deals">{s.deals_count} deals</div>
              </div>
            ))}
          </div>
        </div>
      )}
    </>
  );
}

function DealRow({ d, navigate }) {
  const lifespanY = (() => {
    if (!d.first_filing_date || !d.latest_filing_date) return '';
    const f = new Date(d.first_filing_date), l = new Date(d.latest_filing_date);
    const years = (l - f) / (365.25 * 86400000);
    if (years < 0.1) return 'New';
    if (years < 1) return Math.round(years * 12) + 'mo';
    return years.toFixed(1) + 'y';
  })();
  return (
    <div className="dt-row" onClick={() => navigate({ name: 'deal', id: d.deal_id })}>
      <div className="dt-name">
        <div className="dt-name-main">{d.deal_name}</div>
        <div className="dt-name-sub">
          <span className={`industry-tag ${window.industryClass(d.industry_group_type)}`}>{window.industryShort(d.industry_group_type)}</span>
          {d.target_is_indefinite ? <span style={{ fontStyle: 'italic' }}>Indefinite</span> :
           d.target_offering_amount ? <span>Target {window.fmtMoney(d.target_offering_amount)}</span> : null}
        </div>
      </div>
      <div className={`dt-amount ${!d.total_raised ? 'muted' : ''}`}>{d.total_raised ? window.fmtMoney(d.total_raised) : 'Pending'}</div>
      <div className="dt-date">
        {new Date(d.first_filing_date).getFullYear()}–{new Date(d.latest_filing_date).getFullYear().toString().slice(2)}
        <span style={{ marginLeft: 6, color: 'var(--ink-5)', fontSize: 11 }}>{lifespanY}</span>
      </div>
      <div className="dt-loc">{window.industryShort(d.industry_group_type)}</div>
      <div className="dt-filings">
        <span className="filings-pip">
          {d.filings_count > 1 && <span className="filings-pip-dot"></span>}
          {d.filings_count}
        </span>
      </div>
      <div className="dt-status">
        <span className={`status-dot ${d.is_open ? 'open' : 'closed'}`}></span>
        {d.is_open ? 'Active' : 'Closed'}
      </div>
    </div>
  );
}

// ===== Deal detail page =====

function DealDetailPage({ id, navigate }) {
  const [data, setData] = useS_D(null);
  useE_D(() => {
    setData(null);
    window.api('/api/deals/' + id).then(setData);
  }, [id]);

  if (!data) return <DealDetailSkeleton />;
  const { deal, sponsor, filing_history } = data;
  const history = filing_history || [];
  const sortedHist = [...history].sort((a, b) => a.sequence_in_chain - b.sequence_in_chain);
  const lifespanYears = deal.first_filing_date && deal.latest_filing_date
    ? ((new Date(deal.latest_filing_date) - new Date(deal.first_filing_date)) / (365.25 * 86400000))
    : 0;
  const maxDelta = Math.max(...sortedHist.map(h => Math.abs(h.amount_raised_delta || 0)), 1);

  return (
    <>
      <div className="crumb">
        <a href="#/deals" onClick={(e) => { e.preventDefault(); navigate({ name: 'deals' }); }}>Deals</a>
        <span className="crumb-sep">/</span>
        <span style={{ color: 'var(--ink-3)' }}>{window.industryShort(deal.industry_group_type)}</span>
        <span className="crumb-sep">/</span>
        <span style={{ color: 'var(--ink-2)' }}>{deal.deal_name}</span>
      </div>

      <div className="detail-head">
        <div>
          <h1 className="detail-title">{deal.deal_name}</h1>
          <div className="detail-meta">
            <span className="detail-meta-item">
              <span className={`industry-tag ${window.industryClass(deal.industry_group_type)}`}>{window.industryShort(deal.industry_group_type)}</span>
            </span>
            <span className="detail-meta-item">
              <span className={`status-dot ${deal.is_open ? 'open' : 'closed'}`} style={{ width: 6, height: 6 }}></span>
              {deal.is_open ? 'Active fund' : 'Closed'}
            </span>
            <span className="detail-meta-item">
              <I.tag /> {window.industryShort(deal.industry_group_type)}
            </span>
            <span className="detail-meta-item">
              <I.building /> {deal.entity_type} · {deal.jurisdiction_of_inc} {deal.year_of_inc ? `· ${deal.year_of_inc}` : ''}
            </span>
            {sponsor && (
              <span className="detail-meta-item">
                <I.layers /> Sponsor:{' '}
                <a onClick={() => navigate({ name: 'sponsor', id: sponsor.sponsor_id })}
                   style={{ color: 'var(--accent)', cursor: 'pointer', fontWeight: 500 }}>
                  {sponsor.canonical_name}
                </a>
              </span>
            )}
            {!sponsor && (
              <span className="detail-meta-item" style={{ color: 'var(--ink-4)', fontStyle: 'italic' }}>
                Single-deal sponsor
              </span>
            )}
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <a className="btn" target="_blank" rel="noreferrer"
             href={`https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK=${deal.cik}`}>
            EDGAR <I.ext />
          </a>
        </div>
      </div>

      <div className="metric-strip">
        <div className="metric-cell">
          <div className="metric-label">Total raised</div>
          <div className="metric-value">{deal.total_raised ? window.fmtMoneyFull(deal.total_raised) : '—'}</div>
          <div className="metric-sub">{deal.total_investors ? `${deal.total_investors.toLocaleString()} investors` : 'No investors reported'}</div>
        </div>
        <div className="metric-cell">
          <div className="metric-label">Target</div>
          <div className="metric-value" style={deal.target_is_indefinite ? { fontStyle: 'italic', color: 'var(--ink-3)' } : null}>
            {deal.target_is_indefinite ? 'Indefinite' : (deal.target_offering_amount ? window.fmtMoneyFull(deal.target_offering_amount) : '—')}
          </div>
          <div className="metric-sub">
            {!deal.target_is_indefinite && deal.target_offering_amount && deal.total_raised ?
              `${((deal.total_raised / deal.target_offering_amount) * 100).toFixed(0)}% of target` : 'Open-ended fund'}
          </div>
        </div>
        <div className="metric-cell">
          <div className="metric-label">Filings</div>
          <div className="metric-value">{deal.filings_count}</div>
          <div className="metric-sub">{deal.filings_count > 1 ? `${deal.filings_count - 1} amendments` : 'Original only'}</div>
        </div>
        <div className="metric-cell">
          <div className="metric-label">Lifespan</div>
          <div className="metric-value">
            {lifespanYears < 1 ? `${Math.round(lifespanYears * 12)}mo` : `${lifespanYears.toFixed(1)}y`}
          </div>
          <div className="metric-sub">
            {window.fmtDateShort(deal.first_filing_date)} → {window.fmtDateShort(deal.latest_filing_date)}
          </div>
        </div>
      </div>

      {/* Cumulative chart */}
      <div className="card timeline-card">
        <div className="card-header">
          <h3>Capital trajectory</h3>
          <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
            CUMULATIVE · {sortedHist.length} FILINGS
          </span>
        </div>
        <div style={{ padding: '18px 22px 6px' }}>
          <CumulativeChart history={sortedHist} />
        </div>
      </div>

      {/* Per-filing history */}
      <div className="card" style={{ marginBottom: 24 }}>
        <div className="card-header">
          <h3>Amendment history</h3>
          <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
            EACH ROW = ONE FILING
          </span>
        </div>
        <div className="history-row head">
          <div>#</div>
          <div>Filed</div>
          <div>Type</div>
          <div>Δ Raised</div>
          <div style={{ textAlign: 'right' }}>Cumulative</div>
          <div style={{ textAlign: 'right' }}>Investors</div>
        </div>
        {sortedHist.map(h => {
          const delta = h.amount_raised_delta || 0;
          const pct = Math.abs(delta) / maxDelta;
          return (
            <div className="history-row" key={h.sequence_in_chain}>
              <div className="mono" style={{ color: 'var(--ink-4)', fontSize: 11 }}>
                {String(h.sequence_in_chain).padStart(2, '0')}
              </div>
              <div className="mono" style={{ fontSize: 12 }}>{window.fmtDate(h.filing_date)}</div>
              <div>
                <span className={`submission-tag ${h.submission_type !== 'D' ? 'amend' : ''}`}>{h.submission_type}</span>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <span className={`delta-pill ${delta < 0 ? 'neg' : delta === 0 ? 'zero' : ''}`}>
                  {delta > 0 ? '+' : delta < 0 ? '−' : ''}{delta !== 0 ? window.fmtMoney(Math.abs(delta)) : '$0'}
                </span>
                <div className="history-bar" style={{ flex: 1, maxWidth: 140 }}>
                  <div className={`history-bar-fill ${delta < 0 ? 'neg' : ''}`} style={{ width: `${Math.max(pct * 100, 2)}%` }}></div>
                </div>
              </div>
              <div className="mono tnum" style={{ textAlign: 'right' }}>{window.fmtMoney(h.cumulative_amount_sold)}</div>
              <div className="mono" style={{ textAlign: 'right', color: 'var(--ink-3)', fontSize: 12 }}>
                {h.cumulative_total_investors?.toLocaleString() || '—'}
                {h.investors_delta > 0 && <span style={{ color: 'var(--pos)', marginLeft: 4 }}>+{h.investors_delta}</span>}
              </div>
            </div>
          );
        })}
      </div>

      <div className="row-2col">
        <div className="card">
          <div className="card-header"><h3>Issuer details</h3></div>
          <div style={{ padding: 16, display: 'grid', gridTemplateColumns: '120px 1fr', gap: 8, fontSize: 13 }}>
            <div style={{ color: 'var(--ink-4)' }}>CIK</div>
            <div className="mono">{deal.cik}</div>
            <div style={{ color: 'var(--ink-4)' }}>Entity</div>
            <div>{deal.entity_type}</div>
            <div style={{ color: 'var(--ink-4)' }}>Jurisdiction</div>
            <div>{window.titleCase(deal.jurisdiction_of_inc || '—')}</div>
            <div style={{ color: 'var(--ink-4)' }}>Year of inc.</div>
            <div className="mono">{deal.year_of_inc || '—'}</div>
            <div style={{ color: 'var(--ink-4)' }}>Min. investment</div>
            <div className="mono">{deal.minimum_investment ? window.fmtMoneyFull(deal.minimum_investment) : '—'}</div>
            <div style={{ color: 'var(--ink-4)' }}>First sale</div>
            <div className="mono">{window.fmtDate(deal.first_sale_date)}</div>
          </div>
        </div>

        <div className="card">
          <div className="card-header">
            <h3>{sponsor ? 'Sponsor attribution' : 'Attribution'}</h3>
            {sponsor && <a className="btn ghost" onClick={() => navigate({ name: 'sponsor', id: sponsor.sponsor_id })}>View sponsor <I.arrow /></a>}
          </div>
          <div style={{ padding: 18 }}>
            {sponsor ? (
              <>
                <div style={{ fontFamily: 'var(--font-serif)', fontSize: 22, fontWeight: 500, marginBottom: 4 }}>
                  {sponsor.canonical_name}
                </div>
                <div style={{ fontSize: 12, color: 'var(--ink-4)', marginBottom: 16 }}>
                  {sponsor.deals_count} attributed deals · {window.fmtMoney(sponsor.total_raised)} lifetime · since {new Date(sponsor.first_filing_date).getFullYear()}
                </div>
                <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-4)', marginBottom: 8, fontFamily: 'var(--font-mono)' }}>
                  Why this attribution
                </div>
                <div style={{ fontSize: 13, color: 'var(--ink-3)', lineHeight: 1.6 }}>
                  This SPV shares contact details with {sponsor.deals_count - 1} other filing{sponsor.deals_count > 2 ? 's' : ''} —
                  matching phone <span className="mono" style={{ color: 'var(--ink)' }}>{window.fmtPhoneSignal(sponsor.primary_phone_normalized)}</span>
                  {sponsor.primary_street1 ? ' and a shared corporate address.' : '.'}
                </div>
              </>
            ) : (
              <div style={{ color: 'var(--ink-4)', fontSize: 13 }}>
                <div style={{ fontFamily: 'var(--font-serif)', fontSize: 18, color: 'var(--ink-2)', marginBottom: 8 }}>
                  Single-deal sponsor
                </div>
                This SPV's contact details don't match any other filing in our index — meaning either it's a one-and-done vehicle, or the sponsor has obscured signals.
              </div>
            )}
          </div>
        </div>
      </div>
    </>
  );
}

function CumulativeChart({ history }) {
  if (!history || history.length === 0) return <div className="empty">No filing history</div>;
  if (history.length === 1) {
    const h = history[0];
    return (
      <div style={{ padding: 24, display: 'flex', alignItems: 'center', gap: 24 }}>
        <div style={{ width: 14, height: 14, borderRadius: '50%', background: 'var(--accent)', flexShrink: 0 }}></div>
        <div>
          <div style={{ fontSize: 13, color: 'var(--ink-3)' }}>Single filing on {window.fmtDate(h.filing_date)}</div>
          <div className="mono" style={{ fontSize: 22, fontWeight: 500 }}>{window.fmtMoney(h.cumulative_amount_sold)}</div>
        </div>
      </div>
    );
  }

  const W = 1100, H = 240;
  const pad = { l: 60, r: 24, t: 16, b: 36 };
  const iw = W - pad.l - pad.r;
  const ih = H - pad.t - pad.b;
  const dates = history.map(h => new Date(h.filing_date).getTime());
  const minD = Math.min(...dates), maxD = Math.max(...dates);
  const maxV = Math.max(...history.map(h => h.cumulative_amount_sold || 0), 1);
  const ax = (t) => pad.l + ((t - minD) / Math.max(maxD - minD, 1)) * iw;
  const ay = (v) => pad.t + ih - (v / maxV) * ih;

  // Stepwise line: each filing is a step
  let pathD = '';
  history.forEach((h, i) => {
    const x = ax(new Date(h.filing_date).getTime());
    const y = ay(h.cumulative_amount_sold);
    if (i === 0) {
      pathD += `M ${pad.l} ${pad.t + ih} L ${pad.l} ${y} L ${x} ${y}`;
    } else {
      const prevY = ay(history[i - 1].cumulative_amount_sold);
      pathD += ` L ${x} ${prevY} L ${x} ${y}`;
    }
  });
  pathD += ` L ${pad.l + iw} ${ay(history[history.length-1].cumulative_amount_sold)}`;

  const areaD = pathD + ` L ${pad.l + iw} ${pad.t + ih} L ${pad.l} ${pad.t + ih} Z`;

  // Y ticks
  const yTicks = [0, 0.25, 0.5, 0.75, 1];
  // X ticks: years
  const startYear = new Date(minD).getFullYear();
  const endYear = new Date(maxD).getFullYear();
  const years = [];
  for (let y = startYear; y <= endYear; y++) years.push(y);
  const yearStep = Math.max(1, Math.ceil(years.length / 8));
  const yearTicks = years.filter((_, i) => i % yearStep === 0 || i === years.length - 1);

  return (
    <svg width="100%" height={H} viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{ overflow: 'visible' }}>
      <defs>
        <linearGradient id="cumGrad" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor="var(--accent)" stopOpacity="0.18"/>
          <stop offset="100%" stopColor="var(--accent)" stopOpacity="0"/>
        </linearGradient>
      </defs>
      {yTicks.map((t, i) => {
        const y = pad.t + ih - t * ih;
        return (
          <g key={i}>
            <line x1={pad.l} x2={pad.l + iw} y1={y} y2={y} stroke="var(--line)" strokeDasharray={i === 0 ? null : '2 3'} />
            <text x={pad.l - 8} y={y + 3} fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-4)" textAnchor="end">
              {window.fmtMoney(maxV * t)}
            </text>
          </g>
        );
      })}
      {yearTicks.map(yr => {
        const x = ax(new Date(yr, 0, 1).getTime());
        return (
          <text key={yr} x={x} y={pad.t + ih + 18} fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-4)" textAnchor="middle">
            '{String(yr).slice(2)}
          </text>
        );
      })}
      <path d={areaD} fill="url(#cumGrad)"/>
      <path d={pathD} fill="none" stroke="var(--accent)" strokeWidth="1.75"/>
      {history.map((h, i) => {
        const x = ax(new Date(h.filing_date).getTime());
        const y = ay(h.cumulative_amount_sold);
        const isFirst = i === 0;
        const isLast = i === history.length - 1;
        return (
          <g key={i}>
            <line x1={x} x2={x} y1={y} y2={pad.t + ih} stroke="var(--line)" strokeDasharray="1 3" opacity="0.6"/>
            <circle cx={x} cy={y} r={isLast ? 4 : 3} fill="var(--bg-elev)" stroke="var(--accent)" strokeWidth="1.5"/>
            {(isFirst || isLast) && (
              <text x={x} y={y - 10} fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-2)"
                    textAnchor={isFirst ? 'start' : 'end'} fontWeight="600">
                {window.fmtMoney(h.cumulative_amount_sold)}
              </text>
            )}
          </g>
        );
      })}
    </svg>
  );
}

function DealDetailSkeleton() {
  return (
    <>
      <div className="skel" style={{ height: 12, width: 200, marginBottom: 16 }}></div>
      <div className="skel" style={{ height: 38, width: '60%', marginBottom: 12 }}></div>
      <div className="skel" style={{ height: 14, width: '40%', marginBottom: 32 }}></div>
      <div className="skel" style={{ height: 100, width: '100%', marginBottom: 24 }}></div>
      <div className="skel" style={{ height: 280, width: '100%' }}></div>
    </>
  );
}

window.DealsListPage = DealsListPage;
window.DealDetailPage = DealDetailPage;
