/* ============================================================
   NeuroRoute — Portal core: Dashboard, Usage, Billing, Provider Keys
   All data fetched from live APIs — no demo data.
   ============================================================ */
const D = window.DATA;

/* ---- model name + provider cell ---- */
function ModelCell({id}){
  const m=D.modelById(id); if(!m) return <span>{id}</span>;
  return <span className="row" style={{gap:9}}><ProviderLogo id={m.provider} size={26}/><span style={{fontWeight:600,color:'var(--tx-0)'}}>{m.name}</span></span>;
}

/* =====================  DASHBOARD  ===================== */
function DashboardPage(){
  const [loading, setLoading] = React.useState(true);
  const [ov, setOv] = React.useState(null);
  const [timeline, setTimeline] = React.useState([]);
  const [decisions, setDecisions] = React.useState([]);
  const [modelStats, setModelStats] = React.useState([]);
  const [healthData, setHealthData] = React.useState({});

  React.useEffect(()=>{
    Promise.all([
      NR_API.dashboardOverview(),
      NR_API.dashboardUsage(30),
      NR_API.dashboardRouting(8),
      NR_API.dashboardModels(),
      NR_API.health(),
    ]).then(([o,u,r,m,h])=>{
      setOv(o);
      setTimeline(u && u.timeline ? u.timeline : []);
      setDecisions(r && r.decisions ? r.decisions : []);
      setModelStats(m && m.models ? m.models : []);
      setHealthData(h || {});
      setLoading(false);
    }).catch(()=>setLoading(false));
  },[]);

  if(loading) return <LoadingPage/>;

  const hasData = ov && ov.total_requests > 0;

  /* Derive chart data */
  const savingsPct = ov && ov.total_spend > 0 ? Math.round((ov.total_saved / (ov.total_saved + ov.total_spend)) * 100) : 0;
  const baseline = ov ? ov.total_saved + ov.total_spend : 0;
  const labels = timeline.map(d=>{ const dt=new Date(d.date); return (dt.getMonth()+1)+'/'+dt.getDate(); });
  const actuals = timeline.map(d=>d.cost);
  const baselines = timeline.map(d=>gpt4oBaseline(d.input_tokens, d.output_tokens));
  const sparkSav = timeline.slice(-14).map((d,i)=>{ const idx=timeline.length-14+i; return (baselines[idx]||0) - d.cost; });

  /* Model distribution from real stats */
  const totalModelReqs = modelStats.reduce((s,m)=>s+m.request_count, 0);
  const dist = modelStats.slice(0,10).map(m=>({
    label: D.modelById(m.model).name,
    value: totalModelReqs>0 ? Math.round(m.request_count/totalModelReqs*100) : 0,
    model: m.model, reqs: m.request_count,
  }));

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="Live overview of your routing, savings, and provider health.">
        <button className="btn btn-primary btn-sm" onClick={()=>go('playground')}><Icon name="playground" size={15}/>Open Playground</button>
      </PageHead>

      {!hasData ? <>
        <EmptyState icon="dashboard" title="Welcome to NeuroRoute"
          desc="Your intelligent routing dashboard will show savings and performance data once you start sending requests through the API."
          actions={[
            {label:'Create API Key', onClick:()=>go('apikeys')},
            {label:'Open Playground', onClick:()=>go('playground'), primary:true},
          ]}/>
        <HealthSidebar healthData={healthData}/>
      </> : <>
        {/* savings hero banner */}
        <div className="card" style={{position:'relative',overflow:'hidden',padding:'26px 28px'}}>
          <div style={{position:'absolute',inset:0,background:'radial-gradient(120% 160% at 0% 0%, rgba(16,185,129,.16), transparent 50%), radial-gradient(120% 160% at 100% 0%, rgba(226,79,214,.12), transparent 55%)'}}/>
          <div className="spread" style={{position:'relative',flexWrap:'wrap',gap:20}}>
            <div>
              <div className="eyebrow" style={{marginBottom:8}}>SAVINGS THIS MONTH</div>
              <div className="row" style={{gap:14,alignItems:'baseline'}}>
                <span className="display" style={{fontSize:46,lineHeight:1}}>{fmtUSD(ov.total_saved,0)}</span>
                {savingsPct>0 && <Badge color="green" dot>{savingsPct}% saved</Badge>}
              </div>
              <div className="faint" style={{marginTop:8,fontSize:13.5}}>vs {fmtUSD(baseline,0)} GPT-4o baseline · {fmtNum(ov.total_requests)} requests</div>
            </div>
            {timeline.length>=14 && <div style={{textAlign:'right'}}>
              <Spark data={sparkSav} color={COL.green} w={220} h={56}/>
              <div className="faint mono" style={{fontSize:11,marginTop:4}}>last 14 days</div>
            </div>}
          </div>
        </div>

        {/* metric cards */}
        <div className="metric-grid">
          <Metric icon="dollar"    color="green"   value={fmtUSD(ov.total_saved,0)} label="Total saved"/>
          <Metric icon="zap"       color="blue"    value={fmtNum(ov.total_requests)} label="Requests served"/>
          <Metric icon="billing"   color="magenta" value={fmtUSD(ov.total_spend,0)}  label="Actual spend"/>
          <Metric icon="estimator" color="cyan"    value={'$'+(ov.avg_cost_per_request||0).toFixed(4)} label="Avg cost / request"/>
        </div>

        {/* charts row */}
        {timeline.length>0 && <div className="grid" style={{gridTemplateColumns:'1.7fr 1fr'}}>
          <SectionCard title="Cost: NeuroRoute vs GPT-4o baseline" sub="Daily spend over the last 30 days"
            action={<div className="row" style={{gap:14,fontSize:12}}>
              <span className="row" style={{gap:6}}><span style={{width:18,height:2,background:COL.blue,display:'inline-block'}}/>NeuroRoute</span>
              <span className="row" style={{gap:6}}><span style={{width:18,height:0,borderTop:'2px dashed '+COL.red,display:'inline-block'}}/>GPT-4o</span>
            </div>}>
            <LineDual labels={labels} a={actuals} b={baselines} height={268}/>
          </SectionCard>
          {dist.length>0 && <SectionCard title="Model distribution" sub="Share of traffic by model">
            <Donut items={dist} centerLabel={dist.length} centerSub="models" height={210}/>
            <div className="grid" style={{gap:7,marginTop:12}}>
              {dist.slice(0,5).map((d,i)=>{
                const c=[COL.cyan,COL.blue,COL.magenta,COL.green,COL.purple][i];
                return <div key={d.model||i} className="spread" style={{fontSize:12.5}}>
                  <span className="row" style={{gap:8}}><span style={{width:9,height:9,borderRadius:3,background:c}}/>{d.label}</span>
                  <span className="mono faint">{d.value}%</span></div>;
              })}
            </div>
          </SectionCard>}
        </div>}

        {/* recent decisions + health */}
        <div className="grid" style={{gridTemplateColumns:'1.7fr 1fr'}}>
          <SectionCard title="Recent routing decisions" pad={false}
            action={<button className="btn btn-soft btn-sm" onClick={()=>go('explorer')}>Open explorer<Icon name="arrowright" size={14}/></button>}>
            {decisions.length===0 ?
              <div style={{padding:40,textAlign:'center'}} className="faint">No routing decisions yet.</div> :
              <div className="scroll-x">
                <table className="table">
                  <thead><tr><th>Time</th><th>Model</th><th>Task</th><th style={{textAlign:'right'}}>Cost</th><th style={{textAlign:'right'}}>Saved</th><th style={{textAlign:'right'}}>Latency</th><th>Strategy</th></tr></thead>
                  <tbody>
                    {decisions.map(r=>{
                      const saved = gpt4oBaseline(r.input_tokens, r.output_tokens) - r.provider_cost;
                      const task = D.TASKS.find(t=>t.id===r.task_type) || {label:r.task_type||'general', color:'gray'};
                      return (
                        <tr key={r.request_id}>
                          <td className="faint" style={{whiteSpace:'nowrap'}}>{timeAgo(r.created_at)}</td>
                          <td><ModelCell id={r.model}/></td>
                          <td><TaskBadge task={task}/></td>
                          <td className="num" style={{textAlign:'right'}}>${r.provider_cost.toFixed(4)}</td>
                          <td className="num" style={{textAlign:'right',color:saved>0?'var(--green)':'var(--tx-2)'}}>{saved>0?'+':''}${saved.toFixed(4)}</td>
                          <td className="num" style={{textAlign:'right'}}>{r.routing_latency_ms}ms</td>
                          <td><Badge color="gray">{r.routing_strategy}</Badge></td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            }
          </SectionCard>
          <HealthSidebar healthData={healthData}/>
        </div>
      </>}
    </div>
  );
}

/* =====================  USAGE ANALYTICS  ===================== */
function UsagePage(){
  const [loading, setLoading] = React.useState(true);
  const [timeline, setTimeline] = React.useState([]);
  const [modelStats, setModelStats] = React.useState([]);
  const [compression, setCompression] = React.useState(null);
  const [range, setRange] = React.useState('30d');

  React.useEffect(()=>{
    const days = range==='7d'?7 : range==='90d'?90 : 30;
    setLoading(true);
    Promise.all([
      NR_API.dashboardUsage(days),
      NR_API.dashboardModels(),
      NR_API.dashboardCompression(),
    ]).then(([u,m,c])=>{
      setTimeline(u && u.timeline ? u.timeline : []);
      setModelStats(m && m.models ? m.models : []);
      setCompression(c || null);
      setLoading(false);
    }).catch(()=>setLoading(false));
  },[range]);

  if(loading) return <LoadingPage/>;

  /* Compute totals from timeline */
  const totals = timeline.reduce((a,d)=>({
    requests: a.requests+d.requests,
    inTok: a.inTok+d.input_tokens,
    outTok: a.outTok+d.output_tokens,
    cost: a.cost+d.cost,
  }),{requests:0, inTok:0, outTok:0, cost:0});
  const avgLat = modelStats.length>0 ? Math.round(modelStats.reduce((s,m)=>s+m.avg_latency_ms,0)/modelStats.length) : 0;

  const labels = timeline.map(d=>{ const dt=new Date(d.date); return (dt.getMonth()+1)+'/'+dt.getDate(); });
  const palette = [COL.cyan,COL.blue,COL.magenta,COL.green,COL.amber];

  /* Model distribution for stacked chart */
  const totalModelReqs = modelStats.reduce((s,m)=>s+m.request_count,0);
  const topModels = modelStats.slice(0,5);
  const series = topModels.map((ms,i)=>{
    const share = totalModelReqs>0 ? ms.request_count/totalModelReqs : 0;
    return {
      label: D.modelById(ms.model).name, color: palette[i],
      data: timeline.map(day=>Math.round((day.input_tokens+day.output_tokens)*share)),
    };
  });

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="Token consumption, request volume, and latency trends across your workloads.">
        <div className="seg">{['7d','30d','90d'].map(r=><button key={r} className={range===r?'active':''} onClick={()=>setRange(r)}>{r==='7d'?'Last 7d':r==='30d'?'Last 30d':'Last 90d'}</button>)}</div>
      </PageHead>

      {totals.requests===0 ?
        <EmptyState icon="analytics" title="No usage data yet" desc="Send requests through the NeuroRoute API to see token consumption and model usage trends here."/> :
      <>
        <div className="metric-grid">
          <Metric icon="zap"       color="blue"    value={fmtNum(totals.requests)} label="Total requests"/>
          <Metric icon="arrowdown" color="cyan"    value={fmtTok(totals.inTok)}    label="Input tokens"/>
          <Metric icon="arrowup"   color="magenta" value={fmtTok(totals.outTok)}   label="Output tokens"/>
          <Metric icon="clock"     color="amber"   value={avgLat+'ms'}             label="Avg latency"/>
        </div>

        {compression && compression.raw_input_tokens > 0 && <SectionCard title="Context compression" sub={"Input shrunk before the model — "+fmtNum(compression.compressed_requests)+" requests compressed (30d)"}>
          <div className="grid" style={{gridTemplateColumns:'repeat(auto-fit, minmax(160px, 1fr))', gap:14}}>
            <div style={{padding:'12px 14px',background:'var(--bg-inset)',borderRadius:12}}>
              <div className="faint" style={{fontSize:11.5}}>Raw input tokens</div>
              <div className="mono" style={{fontSize:20,marginTop:2}}>{fmtTok(compression.raw_input_tokens)}</div>
            </div>
            <div style={{padding:'12px 14px',background:'var(--bg-inset)',borderRadius:12}}>
              <div className="faint" style={{fontSize:11.5}}>Compressed input tokens</div>
              <div className="mono" style={{fontSize:20,marginTop:2,color:'var(--cyan)'}}>{fmtTok(compression.compressed_input_tokens)}</div>
            </div>
            <div style={{padding:'12px 14px',background:'var(--bg-inset)',borderRadius:12}}>
              <div className="faint" style={{fontSize:11.5}}>Compression</div>
              <div className="display route-text" style={{fontSize:24,marginTop:2}}>{(compression.compression_pct||0).toFixed(1)}%</div>
            </div>
            <div style={{padding:'12px 14px',background:'var(--green-t)',borderRadius:12,border:'1px solid rgba(16,185,129,.3)'}}>
              <div className="faint" style={{fontSize:11.5}}>Approx. money saved</div>
              <div className="display route-text" style={{fontSize:24,marginTop:2}}>{fmtUSD(compression.money_saved_usd||0,4)}</div>
              <div className="faint" style={{fontSize:10.5,marginTop:2}}>{fmtTok(compression.saved_input_tokens)} input tokens avoided</div>
            </div>
          </div>
          <div className="faint" style={{fontSize:11.5,marginTop:12}}>Estimated (≈4 chars/token). Compression is lossless in default mode; aggressive mode is test-only.</div>
        </SectionCard>}
        <div className="grid" style={{gridTemplateColumns:'1.6fr 1fr'}}>
          {series.length>0 && <SectionCard title="Daily token usage by model" sub="Input + output tokens, stacked">
            <BarStacked labels={labels} series={series} height={280}/>
          </SectionCard>}
          <SectionCard title="Requests per day" sub="Volume trend">
            <BarSimple labels={labels} data={timeline.map(d=>d.requests)} color={COL.blue} height={280} fmt={fmtTok}/>
          </SectionCard>
        </div>
        {modelStats.length>0 && <SectionCard title="Top models by usage" sub="Ranked by request count" pad={false}>
          <div className="scroll-x">
            <table className="table">
              <thead><tr><th>Model</th><th>Provider</th><th style={{textAlign:'right'}}>Requests</th><th style={{textAlign:'right'}}>Avg Latency</th><th style={{textAlign:'right'}}>Total Cost</th><th>% of traffic</th></tr></thead>
              <tbody>
                {modelStats.map((ms,i)=>{
                  const m=D.modelById(ms.model); const c=palette[i%palette.length];
                  const pct = totalModelReqs>0 ? Math.round(ms.request_count/totalModelReqs*100) : 0;
                  return (
                    <tr key={ms.model}>
                      <td><ModelCell id={ms.model}/></td>
                      <td className="faint">{D.providerById(m.provider).name}</td>
                      <td className="num" style={{textAlign:'right'}}>{fmtNum(ms.request_count)}</td>
                      <td className="num" style={{textAlign:'right'}}>{ms.avg_latency_ms}ms</td>
                      <td className="num" style={{textAlign:'right'}}>{fmtUSD(ms.total_cost,2)}</td>
                      <td><span className="row" style={{gap:10}}><MiniBar pct={pct} color={c}/><span className="mono faint" style={{fontSize:12}}>{pct}%</span></span></td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </SectionCard>}
      </>}
    </div>
  );
}

/* =====================  BILLING  ===================== */
function BillingPage(){
  const [loading, setLoading] = React.useState(true);
  const [billing, setBilling] = React.useState(null);
  const [config, setConfig] = React.useState(null);
  const [timeline, setTimeline] = React.useState([]);

  React.useEffect(()=>{
    Promise.all([
      NR_API.billingSummary(),
      NR_API.billingConfig(),
      NR_API.dashboardUsage(30),
    ]).then(([b,c,u])=>{
      setBilling(b);
      setConfig(c);
      setTimeline(u && u.timeline ? u.timeline : []);
      setLoading(false);
    }).catch(()=>setLoading(false));
  },[]);

  if(loading) return <LoadingPage/>;

  const hasBilling = billing && (billing.total_charge > 0 || billing.byok_savings > 0);
  const labels = timeline.map(d=>{ const dt=new Date(d.date); return (dt.getMonth()+1)+'/'+dt.getDate(); });

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="Your spend, savings share, and billing details.">
        {hasBilling && <button className="btn btn-soft btn-sm" onClick={function(){
          var m = (billing && billing.billing_month) || '';
          window.open('/v1/customer/billing-summary/export'+(m?('?month='+m):''), '_blank');
        }}><Icon name="download" size={15}/>Download statement (CSV)</button>}
      </PageHead>

      {!hasBilling ?
        <EmptyState icon="billing" title="No billing data yet" desc="Billing information will appear here once you start using the API. Charges are calculated at the end of each billing cycle."/> :
      <>
        <div className="grid" style={{gridTemplateColumns:'1.3fr 1fr 1fr'}}>
          <div className="card" style={{position:'relative',overflow:'hidden',padding:24}}>
            <div style={{position:'absolute',inset:0,background:'radial-gradient(120% 140% at 100% 0%, rgba(59,130,246,.14), transparent 55%)'}}/>
            <div style={{position:'relative'}}>
              <div className="eyebrow" style={{marginBottom:8}}>CURRENT MONTH</div>
              <div className="display" style={{fontSize:40,lineHeight:1}}>{fmtUSD(billing.total_charge||0,2)}</div>
              <div className="faint" style={{marginTop:8,fontSize:13}}>Charge so far this period</div>
              {billing.projected_total > (billing.total_charge||0) && <div className="row" style={{gap:6,marginTop:10}}>
                <Icon name="trendup" size={14} style={{color:'var(--blue)'}}/>
                <span className="faint" style={{fontSize:12.5}}>Projected month-end: <b style={{color:'var(--tx-0)'}}>{fmtUSD(billing.projected_total,2)}</b></span>
              </div>}
            </div>
          </div>
          <Metric icon="dollar" color="green" value={fmtUSD(billing.byok_savings||0,0)} label="BYOK savings"/>
          <Metric icon="billing" color="magenta" value={fmtUSD(billing.sisl_your_charge||0,0)} label="Your usage charge"/>
        </div>

        <div className="grid" style={{gridTemplateColumns:'1fr 1fr'}}>
          <SectionCard title="Billing breakdown" sub="How your bill is calculated">
            <div className="grid" style={{gap:14}}>
              <div className="spread" style={{padding:'12px 14px',background:'var(--bg-inset)',borderRadius:12}}>
                <div><div style={{fontWeight:600}}>BYOK — Bring Your Own Keys</div><div className="faint" style={{fontSize:12.5}}>You pay providers directly · NeuroRoute takes savings share</div></div>
                <div style={{textAlign:'right'}}><div className="mono" style={{color:'var(--green)'}}>+{fmtUSD(billing.byok_savings||0,0)} saved</div><div className="faint mono" style={{fontSize:12}}>fee {fmtUSD(billing.byok_neuroroute_fee||0,2)}</div></div>
              </div>
              <div className="spread" style={{padding:'12px 14px',background:'var(--bg-inset)',borderRadius:12}}>
                <div><div style={{fontWeight:600}}>SISL-managed keys</div><div className="faint" style={{fontSize:12.5}}>Usage routed through NeuroRoute's provider keys</div></div>
                <div style={{textAlign:'right'}}><div className="mono">{fmtUSD(billing.sisl_your_charge||0,2)}</div><div className="faint mono" style={{fontSize:12}}>your charge</div></div>
              </div>
              <hr className="divider"/>
              <div className="spread"><span style={{fontWeight:700}}>Total this period</span><span className="display" style={{fontSize:22}}>{fmtUSD(billing.total_charge||0,2)}</span></div>
            </div>
          </SectionCard>
          {timeline.length>0 && <SectionCard title="Spend by day" sub="Provider cost over the last 30 days">
            <BarSimple labels={labels} data={timeline.map(d=>d.cost)} color={COL.magenta} height={228} fmt={(v)=>'$'+Math.round(v)}/>
          </SectionCard>}
        </div>

        {billing.by_model && billing.by_model.length>0 && <SectionCard title="Charge by model" sub="This month's usage and charge per model" pad={false}>
          <div className="scroll-x"><table className="table">
            <thead><tr><th>Model</th><th style={{textAlign:'right'}}>Requests</th><th style={{textAlign:'right'}}>Input tok</th><th style={{textAlign:'right'}}>Output tok</th><th style={{textAlign:'right'}}>Savings</th><th style={{textAlign:'right'}}>Charge</th></tr></thead>
            <tbody>{billing.by_model.slice().sort((a,b)=>b.charge-a.charge).map(m=>(
              <tr key={m.model}>
                <td><ModelCell id={m.model}/></td>
                <td className="num" style={{textAlign:'right'}}>{fmtNum(m.requests)}</td>
                <td className="num faint" style={{textAlign:'right'}}>{fmtNum(m.input_tokens)}</td>
                <td className="num faint" style={{textAlign:'right'}}>{fmtNum(m.output_tokens)}</td>
                <td className="num" style={{textAlign:'right',color:'var(--green)'}}>{fmtUSD(m.savings||0,4)}</td>
                <td className="num" style={{textAlign:'right',fontWeight:700}}>{fmtUSD(m.charge||0,4)}</td>
              </tr>
            ))}</tbody>
          </table></div>
        </SectionCard>}
      </>}
    </div>
  );
}

/* =====================  MY PROVIDER KEYS  ===================== */
function MyKeysPage(){
  const t=useToast();
  const [loading, setLoading] = React.useState(true);
  const [keys, setKeys] = React.useState([]);
  const [modal, setModal] = React.useState(false);
  const [prov, setProv] = React.useState('openai');
  const [val, setVal] = React.useState('');
  const [saving, setSaving] = React.useState(false);

  React.useEffect(()=>{
    NR_API.customerKeys().then(data=>{
      setKeys(data && data.keys ? data.keys : []);
      setLoading(false);
    }).catch(()=>setLoading(false));
  },[]);

  if(loading) return <LoadingPage/>;

  const statusColor = (s) => s==='active'?'green':s==='expired'?'amber':'gray';

  /* Merge with full provider list to show all providers */
  const merged = D.PROVIDERS.map(p=>{
    const k = keys.find(k=>k.provider===p.id);
    return k ? {...p, key: '••••••••'+k.key_last_4, status: k.status||'active', added: k.created_at ? new Date(k.created_at).toLocaleDateString() : '—', keyId: k.key_id}
             : {...p, key: null, status: 'Not Set', added: null, keyId: null};
  });

  const addKey = ()=>{
    setSaving(true);
    NR_API.addCustomerKey(prov, val).then(res=>{
      setSaving(false);
      if(res && res.key_id) {
        setKeys(ks=>[...ks, {key_id:res.key_id, provider:prov, key_last_4:val.slice(-4), status:'active', created_at:new Date().toISOString()}]);
        setModal(false); setVal('');
        t({title:'Key saved & validated', msg:D.providerById(prov).name+' is now active.'});
      } else {
        t({kind:'error', title:'Failed to save key', msg:(res&&res.error)||'Unknown error'});
      }
    }).catch(()=>{ setSaving(false); t({kind:'error', title:'Failed to save key'}); });
  };

  const removeKey = (keyId, provId)=>{
    NR_API.deleteCustomerKey(keyId).then(()=>{
      setKeys(ks=>ks.filter(k=>k.key_id!==keyId));
      t({kind:'info', title:'Key removed', msg:D.providerById(provId).name+' key deleted.'});
    });
  };

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="Bring your own provider keys. NeuroRoute routes through them and you keep the savings.">
        <button className="btn btn-primary btn-sm" onClick={()=>setModal(true)}><Icon name="plus" size={15}/>Add key</button>
      </PageHead>
      <div className="card card-pad row" style={{gap:12,background:'var(--blue-t)',borderColor:'rgba(59,130,246,.3)'}}>
        <Icon name="lock" size={18} style={{color:'var(--blue)'}}/>
        <span style={{fontSize:13.5}}>Keys are encrypted with <b>AES-256-GCM</b> envelope encryption. We never store or log your raw keys.</span>
      </div>
      <div className="cards-grid">
        {merged.map(k=>(
          <div key={k.id} className="card card-pad card-hover">
            <div className="spread"><span className="row" style={{gap:11}}><ProviderLogo id={k.id} size={40}/><div><div style={{fontWeight:700}}>{k.name}</div><div className="faint" style={{fontSize:12}}>{k.added?'Added '+k.added:'No key configured'}</div></div></span>
              <Badge color={statusColor(k.status)} dot>{k.status}</Badge></div>
            <div className="mono" style={{margin:'18px 0',fontSize:13,color:k.key?'var(--tx-1)':'var(--tx-3)',background:'var(--bg-inset)',padding:'10px 12px',borderRadius:8,border:'1px solid var(--line)'}}>{k.key||'— not set —'}</div>
            <div className="row" style={{gap:8}}>
              {k.key ? <button className="btn btn-danger btn-sm btn-block" onClick={()=>removeKey(k.keyId, k.id)}><Icon name="trash" size={14}/>Remove</button>
                     : <button className="btn btn-ghost btn-sm btn-block" onClick={()=>{setProv(k.id);setModal(true);}}><Icon name="plus" size={14}/>Add key</button>}
            </div>
          </div>
        ))}
      </div>
      {modal && <Modal title="Add provider key" sub="Encrypted and stored securely." onClose={()=>setModal(false)}
        footer={<><button className="btn btn-ghost" onClick={()=>setModal(false)}>Cancel</button><button className="btn btn-primary" disabled={!val||saving} onClick={addKey}>{saving?'Saving…':'Validate & save'}</button></>}>
        <div className="grid" style={{gap:16}}>
          <Field label="Provider"><select className="select" value={prov} onChange={e=>setProv(e.target.value)}>{D.PROVIDERS.map(p=><option key={p.id} value={p.id}>{p.name}</option>)}</select></Field>
          <Field label="API key" hint="Encrypted with AES-256-GCM. Never logged."><input className="input input-mono" placeholder="sk-..." value={val} onChange={e=>setVal(e.target.value)}/></Field>
        </div>
      </Modal>}
    </div>
  );
}

window.PAGES = Object.assign(window.PAGES||{}, {dashboard:DashboardPage, usage:UsagePage, billing:BillingPage, mykeys:MyKeysPage});
