/* Cinco Ranch Village — Rent Roll */
const { useState: rrS } = React;

// Source: CBRE in-place rent roll (ties to IOv2 p.7) — 9 tenants, 20,155 SF, 100% leased
// [suite, name, sf, pct, start, end, psf, total, notes, kind]
const RR_TENANTS = [
  ['A',  'Centerra Ranch Montessori',    4000,  19.8, '2/1/12',  '1/31/28', 26.28, 105120, 'Early childhood · since 2012 · Jan 2028 rollover = biggest upside', 'education'],
  ['B',  'PostNet',                      1200,   6.0, '11/1/21', '10/31/31', 34.00, 40800,  'National franchise · shipping/printing',                                     'service'],
  ['C',  'Orangetheory Fitness',         3695,  18.3, '1/1/15',  '12/31/30', 36.00, 133020, 'National credit tenant · 2% annual bumps',                                   'fitness'],
  ['D',  'Great Clips',                  1200,   6.0, '6/1/26',  '5/31/36', 36.00, 43200,  'National franchise · new 10-yr lease',                                        'service'],
  ['E',  'FYZICAL Therapy',              2160,  10.7, '12/1/21', '11/30/26', 26.52, 57283,  'Medical services · Nov 2026 renewal',                                        'wellness'],
  ['F',  'Nobel Nails Bar',              1600,   7.9, '1/1/22',  '12/31/31', 34.00, 54400,  'Local · strong sales performer',                                             'service'],
  ['G',  'Handroll Social',              2000,   9.9, '8/1/24',  '7/31/29', 35.00, 70000,  'F&B · Japanese concept · Jul 2029',                                          'fnb'],
  ['H',  'AFC Urgent Care',              3100,  15.4, '5/1/26',  '4/30/36', 37.05, 114855, 'New 10-yr lease · national credit tenant',                                    'medical'],
  ['I',  'Suite 190 — Pending',          1200,   6.0, '8/1/26',  '7/31/31', 28.00, 33600,  '** LOI executed · $28/SF NNN · Aug 2026 commencement',                        'pending'],
];

const KIND_DOT = {
  fnb: 'var(--gold)', service: '#7a8a99', wellness: '#8a9a7a',
  fitness: '#a08a7a', medical: '#8a7a9a', education: '#9a8a6a',
  pending: '#c4c4c4',
};

const KIND_LABEL = {
  fnb:'F&B', service:'Service', wellness:'Wellness',
  fitness:'Fitness', medical:'Medical', education:'Education',
  pending:'Pending',
};

const fmtSF  = n => (n==null) ? '—' : n.toLocaleString();
const fmtUSD0 = n => (n==null) ? '—' : '$' + Math.round(n).toLocaleString();
const fmtPSF = n => (n==null) ? '—' : '$' + n.toFixed(2);

function RentRoll(){
  const [sortKey, setSortKey] = rrS('suite');
  const [sortDir, setSortDir] = rrS('asc');
  const [filter, setFilter] = rrS('all');

  const setSort = (k) => {
    if(sortKey===k) setSortDir(d => d==='asc' ? 'desc' : 'asc');
    else { setSortKey(k); setSortDir('asc'); }
  };

  const KIDX = {suite:0, tenant:1, sf:2, pct:3, end:5, psf:6, total:7};

  let rows = RR_TENANTS.filter(r => filter==='all' || r[9]===filter);
  rows = [...rows].sort((a,b)=>{
    const i = KIDX[sortKey];
    const av = a[i], bv = b[i];
    if(av==null) return 1; if(bv==null) return -1;
    if(typeof av === 'number') return sortDir==='asc' ? av-bv : bv-av;
    return sortDir==='asc' ? String(av).localeCompare(String(bv)) : String(bv).localeCompare(String(av));
  });

  // Totals
  const totGLA = RR_TENANTS.reduce((s,r)=>s+r[2],0);
  const totRent = RR_TENANTS.reduce((s,r)=>s+(r[7]||0),0);
  const avgPSF = totRent / RR_TENANTS.reduce((s,r)=>s+(r[6]?r[2]:0),0);

  const filterOptions = [['all','All tenants'], ...Object.entries(KIND_LABEL).filter(([k])=>k!=='pending')];

  // Expiration by year
  const expiringByYear = {};
  RR_TENANTS.forEach(r=>{
    if(!r[5]) return;
    const parts = r[5].split('/');
    const y = parts[2];
    const yr = y && y.length===2 ? '20'+y : y;
    if(!expiringByYear[yr]) expiringByYear[yr] = {sf:0, count:0};
    expiringByYear[yr].sf += r[2];
    expiringByYear[yr].count += 1;
  });

  return <section id="rentroll" style={{padding:'120px 40px', background:'var(--ivory-2)'}}>
    <div style={{maxWidth:1400, margin:'0 auto'}}>
      <SectionLabel num="03" title="Rent Roll"/>

      {/* Header stats */}
      <div style={{display:'grid', gridTemplateColumns:'1.4fr 1fr 1fr 1fr 1fr', gap:24,
        marginBottom:48, paddingBottom:32, borderBottom:'1px solid rgba(244,233,200,0.12)'}}>
        <div>
          <h2 style={{fontSize:'clamp(34px, 4vw, 54px)', letterSpacing:'-0.02em', lineHeight:1.05,
            fontWeight:300, marginBottom:14, marginTop:0}}>
            9 tenants. <em style={{color:'var(--gold)'}}>$655K</em> in-place rent.
          </h2>
          <p style={{color:'var(--muted)', fontSize:14, lineHeight:1.6, margin:0, maxWidth:520}}>
            56% national credit tenancy: AFC Urgent Care, Orangetheory, Great Clips, PostNet, FYZICAL.
            100% leased · 5.0-yr WALT · triple-net structure.
          </p>
        </div>
        {[
          ['Leased SF', fmtSF(totGLA-1200), '94.0% in-place'],
          ['Pending', '1,200 SF', 'LOI executed'],
          ['Total GLA', fmtSF(totGLA), '9 tenant suites'],
          ['In-place rent', '$655K', `${fmtPSF(avgPSF)} wtd avg`],
        ].map(([k,v,s])=>(
          <div key={k}>
            <div style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:9, letterSpacing:'0.2em',
              textTransform:'uppercase', color:'var(--muted)', marginBottom:8}}>{k}</div>
            <div style={{fontFamily:"'Jost',sans-serif", fontSize:32, fontWeight:300,
              letterSpacing:'-0.02em', lineHeight:1, marginBottom:6}} className="tnum">{v}</div>
            <div style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:10,
              color:'var(--muted)'}}>{s}</div>
          </div>
        ))}
      </div>

      {/* Filter strip */}
      <div style={{display:'flex', alignItems:'center', gap:16, marginBottom:20, flexWrap:'wrap'}}>
        <span style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:10, letterSpacing:'0.2em',
          textTransform:'uppercase', color:'var(--muted)'}}>Filter</span>
        {filterOptions.map(([k,l])=>(
          <button key={k} onClick={()=>setFilter(k)} style={{
            padding:'6px 14px', background: filter===k ? 'var(--ink)' : 'transparent',
            color: filter===k ? 'var(--ivory)' : 'var(--ink)',
            border: '1px solid ' + (filter===k ? 'var(--ink)' : 'rgba(244,233,200,0.18)'),
            fontSize:11, letterSpacing:'0.05em', cursor:'pointer',
            fontFamily:"'JetBrains Mono',ui-monospace,monospace",
          }}>{l}</button>
        ))}
        <span style={{marginLeft:'auto', fontFamily:"'JetBrains Mono',ui-monospace,monospace",
          fontSize:10, color:'var(--muted)'}}>Showing {rows.length} of {RR_TENANTS.length}</span>
      </div>

      {/* Table */}
      <div data-mobile-scroll="true">
      <div style={{background:'var(--ivory)', border:'1px solid rgba(244,233,200,0.08)', overflow:'hidden', minWidth:860}}>
        <div style={{display:'grid',
          gridTemplateColumns:'70px 1.2fr 14px 80px 60px 90px 70px 100px 1.4fr',
          gap:12, padding:'14px 24px', background:'var(--ink)', color:'var(--ivory)',
          fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:9.5, letterSpacing:'0.18em',
          textTransform:'uppercase'}}>
          <SortHdr k="suite" cur={sortKey} dir={sortDir} onClick={setSort}>Suite</SortHdr>
          <SortHdr k="tenant" cur={sortKey} dir={sortDir} onClick={setSort}>Tenant</SortHdr>
          <span></span>
          <SortHdr k="sf" cur={sortKey} dir={sortDir} onClick={setSort} right>SF</SortHdr>
          <SortHdr k="pct" cur={sortKey} dir={sortDir} onClick={setSort} right>% GLA</SortHdr>
          <SortHdr k="end" cur={sortKey} dir={sortDir} onClick={setSort} right>Lease end</SortHdr>
          <SortHdr k="psf" cur={sortKey} dir={sortDir} onClick={setSort} right>PSF</SortHdr>
          <SortHdr k="total" cur={sortKey} dir={sortDir} onClick={setSort} right>Annual rent</SortHdr>
          <span>Notes</span>
        </div>

        {rows.map((r,i)=>{
          const isPending = r[9]==='pending';
          return <div key={r[0]} style={{display:'grid',
            gridTemplateColumns:'70px 1.2fr 14px 80px 60px 90px 70px 100px 1.4fr',
            gap:12, padding:'14px 24px', alignItems:'baseline', fontSize:13,
            borderTop:'1px solid rgba(244,233,200,0.06)',
            background: isPending ? 'rgba(160,180,195,0.15)' : (i%2 ? 'rgba(244,233,200,0.018)' : 'transparent'),
            opacity: isPending ? 0.85 : 1,
          }}>
            <span style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:11, color:'var(--muted)'}}>{r[0]}</span>
            <span style={{fontFamily:"'Jost',sans-serif", fontSize:14, fontWeight: isPending ? 400 : 500,
              fontStyle: isPending ? 'italic' : 'normal'}}>{r[1]}</span>
            <span style={{display:'inline-block', width:8, height:8, borderRadius:'50%',
              background: KIND_DOT[r[9]], alignSelf:'center', marginTop:2}}
              title={KIND_LABEL[r[9]]}/>
            <span className="tnum mono" style={{textAlign:'right', fontSize:12}}>{fmtSF(r[2])}</span>
            <span className="tnum mono" style={{textAlign:'right', fontSize:12, color:'var(--muted)'}}>
              {r[3]==null ? '—' : r[3].toFixed(1)+'%'}
            </span>
            <span className="tnum mono" style={{textAlign:'right', fontSize:11, color:'var(--muted)'}}>{r[5] || 'TBD'}</span>
            <span className="tnum mono" style={{textAlign:'right', fontSize:12}}>{fmtPSF(r[6])}</span>
            <span className="tnum mono" style={{textAlign:'right', fontSize:13, fontWeight:500}}>{fmtUSD0(r[7])}</span>
            <span style={{fontSize:11, color:'var(--muted)', lineHeight:1.4}}>{r[8]}</span>
          </div>;
        })}

        {/* Totals */}
        <div style={{display:'grid',
          gridTemplateColumns:'70px 1.2fr 14px 80px 60px 90px 70px 100px 1.4fr',
          gap:12, padding:'18px 24px', background:'var(--ink)', color:'var(--ivory)',
          alignItems:'baseline'}}>
          <span></span>
          <span style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:11,
            letterSpacing:'0.2em', textTransform:'uppercase', fontWeight:600}}>
            Total in-place rent
          </span>
          <span></span>
          <span className="tnum mono" style={{textAlign:'right', fontSize:13, fontWeight:600}}>{fmtSF(totGLA)}</span>
          <span className="tnum mono" style={{textAlign:'right', fontSize:12, color:'rgba(10,10,10,0.6)'}}>100%</span>
          <span></span>
          <span className="tnum mono" style={{textAlign:'right', fontSize:12, color:'rgba(10,10,10,0.7)'}}>
            {fmtPSF(avgPSF)}
          </span>
          <span className="tnum mono" style={{textAlign:'right', fontSize:16, fontWeight:600, color:'var(--gold-soft)'}}>
            {fmtUSD0(totRent)}
          </span>
          <span style={{fontSize:11, color:'rgba(10,10,10,0.6)'}}>Year 1 gross · NNN base rent</span>
        </div>
      </div>
      </div>

      {/* Rollover schedule */}
      <div style={{marginTop:60, display:'grid', gridTemplateColumns:'1.2fr 1fr', gap:60, alignItems:'start'}}>
        <div>
          <div style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:10, letterSpacing:'0.22em',
            textTransform:'uppercase', color:'var(--muted)', marginBottom:24}}>
            — Rollover schedule
          </div>
          <div style={{display:'grid', gridTemplateColumns:'70px 1fr', gap:12, alignItems:'end',
            height:240, paddingBottom:8, borderBottom:'1px solid rgba(244,233,200,0.15)'}}>
            <div style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:9,
              letterSpacing:'0.15em', textTransform:'uppercase', color:'var(--muted)', alignSelf:'start'}}>
              SF expiring
            </div>
            <div style={{display:'grid', gridTemplateColumns:'repeat(10, 1fr)', gap:6, alignItems:'end', height:'100%'}}>
              {Array.from({length:10}).map((_,i)=>{
                const yr = String(2026+i);
                const y = expiringByYear[yr] || {sf:0, count:0};
                const maxSF = Math.max(...Object.values(expiringByYear).map(v=>v.sf), 1);
                const h = (y.sf / maxSF) * 100;
                return <div key={yr} style={{display:'flex', flexDirection:'column', alignItems:'center', gap:6, height:'100%', justifyContent:'flex-end'}}>
                  <div style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:9,
                    color: y.sf>0 ? 'var(--ink)' : 'transparent'}} className="tnum">
                    {y.sf>0 ? (y.sf/1000).toFixed(1)+'K' : '—'}
                  </div>
                  <div style={{width:'100%', height: h+'%', minHeight: y.sf>0 ? 4 : 0,
                    background: yr==='2028' ? 'var(--gold)' : 'var(--ink)',
                    transition:'height 0.6s ease'}}/>
                </div>;
              })}
            </div>
          </div>
          <div style={{display:'grid', gridTemplateColumns:'70px 1fr', gap:12, marginTop:8}}>
            <div></div>
            <div style={{display:'grid', gridTemplateColumns:'repeat(10, 1fr)', gap:6,
              fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:9, color:'var(--muted)', textAlign:'center'}}>
              {Array.from({length:10}).map((_,i)=>(
                <span key={i}>'{String(26+i).padStart(2,'0')}</span>
              ))}
            </div>
          </div>
          <p style={{fontSize:12, color:'var(--muted)', marginTop:24, lineHeight:1.6, maxWidth:520}}>
            2028 is the inflection year — Centerra Ranch Montessori's 4,000 SF rollover at $26.28
            marks-to-market to $35–$40/SF, driving the single largest NOI uplift of the hold.
            Laddered expirations through 2035 (AFC Urgent Care) keep WALT strong.
          </p>
        </div>

        <div>
          <div style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:10, letterSpacing:'0.22em',
            textTransform:'uppercase', color:'var(--muted)', marginBottom:24}}>
            — Tenant mix by SF
          </div>
          <div style={{display:'flex', flexDirection:'column', gap:10}}>
            {(()=>{
              const groups = {};
              RR_TENANTS.forEach(r=>{
                if(!groups[r[9]]) groups[r[9]] = {sf:0, count:0};
                groups[r[9]].sf += r[2];
                groups[r[9]].count += 1;
              });
              return Object.entries(groups).map(([k,g])=>{
                const pct = (g.sf / totGLA) * 100;
                return <div key={k}>
                  <div style={{display:'flex', justifyContent:'space-between', fontSize:12, marginBottom:6}}>
                    <span style={{display:'flex', alignItems:'center', gap:8}}>
                      <span style={{display:'inline-block', width:8, height:8, borderRadius:'50%',
                        background: KIND_DOT[k]}}/>
                      {KIND_LABEL[k]} <span style={{color:'var(--muted)'}}>· {g.count}</span>
                    </span>
                    <span className="tnum mono" style={{color:'var(--muted)'}}>
                      {fmtSF(g.sf)} SF · {pct.toFixed(1)}%
                    </span>
                  </div>
                  <div style={{height:4, background:'rgba(244,233,200,0.06)'}}>
                    <div style={{width: pct+'%', height:'100%', background: KIND_DOT[k]}}/>
                  </div>
                </div>;
              });
            })()}
          </div>

          <div style={{marginTop:32, padding:'18px 20px', background:'var(--ivory)',
            borderLeft:'2px solid var(--gold)'}}>
            <div style={{fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:10, letterSpacing:'0.2em',
              textTransform:'uppercase', color:'var(--gold)', marginBottom:8}}>Credit mix</div>
            <div style={{fontFamily:"'Jost',sans-serif", fontSize:28, fontWeight:300, letterSpacing:'-0.02em',
              marginBottom:6}} className="tnum">56% national</div>
            <div style={{fontSize:13, color:'var(--muted)', lineHeight:1.5}}>
              AFC Urgent Care · Orangetheory · Great Clips · PostNet · FYZICAL.
              Service-heavy, e-commerce resistant mix.
            </div>
          </div>
        </div>
      </div>

      <p style={{fontSize:10, color:'var(--muted)', marginTop:48, fontStyle:'italic',
        fontFamily:"'JetBrains Mono',ui-monospace,monospace", letterSpacing:'0.05em'}}>
        ** Suite 190: Active LOI for 1,200 SF at $28/SF NNN. Figures assume execution in
        Year 1 of ownership. Rent figures reflect current in-place and contractual steps
        per OM; see offering model for projected NOI through Year 10.
      </p>
    </div>
  </section>;
}

function SortHdr({k, cur, dir, onClick, children, right}){
  const active = cur===k;
  return <button onClick={()=>onClick(k)} style={{
    background:'none', border:'none', color:'inherit', cursor:'pointer',
    fontFamily:"'JetBrains Mono',ui-monospace,monospace", fontSize:9.5, letterSpacing:'0.18em',
    textTransform:'uppercase', padding:0, textAlign: right ? 'right' : 'left',
    opacity: active ? 1 : 0.65, fontWeight: active ? 600 : 400,
  }}>
    {children}{active && <span style={{marginLeft:6, color:'var(--gold-soft)'}}>{dir==='asc'?'↑':'↓'}</span>}
  </button>;
}

Object.assign(window, { RentRoll });
