/* ============================================================
   NeuroRoute — Admin (SISL): Customers, Onboard,
   Provider Keys, Pricing, Model Preferences, Health, Audit Log
   All wired to live APIs.
   ============================================================ */

var eventColor=function(e){
  if(!e) return 'gray';
  if(e.startsWith('auth'))return 'blue';
  if(e.startsWith('key'))return e.includes('revok')?'red':'green';
  if(e.startsWith('config')||e.startsWith('pricing'))return 'amber';
  if(e.startsWith('provider'))return 'purple';
  if(e.startsWith('user'))return 'cyan';
  return 'gray';
};

/* =====================  CUSTOMERS  ===================== */
function CustomersPage(){
  var t=useToast();
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  var _customers=useState([]); var customers=_customers[0], setCustomers=_customers[1];
  var _editing=useState(null); var editing=_editing[0], setEditing=_editing[1];
  var _editName=useState(''); var editName=_editName[0], setEditName=_editName[1];
  var _editBudget=useState(''); var editBudget=_editBudget[0], setEditBudget=_editBudget[1];
  var _editSemCache=useState(false); var editSemCache=_editSemCache[0], setEditSemCache=_editSemCache[1];
  var _editComp=useState(false); var editComp=_editComp[0], setEditComp=_editComp[1];
  var _editCompAggr=useState(false); var editCompAggr=_editCompAggr[0], setEditCompAggr=_editCompAggr[1];
  var _saving=useState(false); var saving=_saving[0], setSaving=_saving[1];
  var _onboarding=useState(false); var onboarding=_onboarding[0], setOnboarding=_onboarding[1];
  var _newOrg=useState({org:'',email:'',name:''}); var newOrg=_newOrg[0], setNewOrg=_newOrg[1];
  var _creating=useState(false); var creating=_creating[0], setCreating=_creating[1];
  var _records=useState([]); var records=_records[0], setRecords=_records[1];
  var _finalizing=useState(false); var finalizing=_finalizing[0], setFinalizing=_finalizing[1];

  var thisMonth = function(){ var d=new Date(); return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0'); };

  var loadRecords=function(orgId){
    NR_API.billingRecords(orgId).then(function(res){
      if(res && Array.isArray(res.records)) setRecords(res.records); else setRecords([]);
    }).catch(function(){ setRecords([]); });
  };

  var finalizeBilling=function(){
    if(!editing) return;
    var orgId = editing.id||editing.org_id;
    setFinalizing(true);
    NR_API.finalizeBilling(orgId, thisMonth()).then(function(res){
      setFinalizing(false);
      if(res && res.status==='finalized'){
        t({title:'Billing finalized', msg:thisMonth()+' · '+(res.total_customer_charge!=null?('$'+Number(res.total_customer_charge).toFixed(2)):'')});
        loadRecords(orgId);
      } else {
        t({kind:'error', title:'Finalize failed', msg:(res&&res.error)||'Check server logs.'});
      }
    }).catch(function(){ setFinalizing(false); t({kind:'error', title:'Finalize failed'}); });
  };

  var loadCustomers=function(){
    setLoading(true);
    NR_API.customers().then(function(res){
      if(res && Array.isArray(res.customers||res)) {
        setCustomers(res.customers||res);
      }
      setLoading(false);
    }).catch(function(){ setLoading(false); });
  };

  useEffect(function(){ loadCustomers(); },[]);

  var openEdit=function(c){
    setEditing(c);
    setEditName(c.name||c.org_name||c.org||'');
    setEditBudget(c.monthly_budget_usd!=null ? String(c.monthly_budget_usd) : '');
    setEditSemCache(!!c.semantic_cache_enabled);
    setEditComp(!!c.compression_enabled);
    setEditCompAggr(!!c.compression_aggressive);
    setRecords([]);
    loadRecords(c.id||c.org_id);
  };

  var saveEdit=function(){
    if(!editing || !editName.trim()) return;
    var orgId = editing.id||editing.org_id;
    setSaving(true);
    var payload = {name:editName.trim()};
    // Empty budget field → clear cap (0 = unlimited). A number → set the cap.
    payload.monthly_budget_usd = editBudget.trim()==='' ? 0 : parseFloat(editBudget) || 0;
    payload.semantic_cache_enabled = editSemCache;
    payload.compression_enabled = editComp;
    payload.compression_aggressive = editComp && editCompAggr;
    NR_API.updateOrg(orgId, payload).then(function(res){
      setSaving(false);
      if(res){
        setCustomers(function(list){
          return list.map(function(c){
            if((c.id||c.org_id)===orgId) return Object.assign({}, c, {name:editName.trim(), monthly_budget_usd:payload.monthly_budget_usd||null, semantic_cache_enabled:editSemCache, compression_enabled:editComp, compression_aggressive:payload.compression_aggressive});
            return c;
          });
        });
        setEditing(null);
        t({title:'Organization updated', msg:editName});
      } else {
        t({kind:'error', title:'Failed to update', msg:'Check server logs.'});
      }
    }).catch(function(){ setSaving(false); t({kind:'error', title:'Failed to update'}); });
  };

  var createCustomer=function(){
    if(!newOrg.org||!newOrg.email) return;
    setCreating(true);
    NR_API.onboard(newOrg.org, newOrg.email, newOrg.name).then(function(res){
      setCreating(false);
      if(res && !res.error){
        setOnboarding(false);
        setNewOrg({org:'',email:'',name:''});
        t({title:'Customer onboarded', msg:newOrg.org});
        loadCustomers();
      } else {
        t({kind:'error', title:'Failed to onboard', msg:(res&&res.error&&res.error.message)||'Check server logs.'});
      }
    }).catch(function(){ setCreating(false); t({kind:'error', title:'Failed to onboard'}); });
  };

  if(loading) return <LoadingPage/>;

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="All customer organizations on the NeuroRoute platform.">
        <button className="btn btn-primary btn-sm" onClick={function(){setOnboarding(true);}}><Icon name="onboard" size={15}/>Onboard customer</button>
      </PageHead>

      {customers.length===0 ?
        <EmptyState icon="customers" title="No customers yet"
          desc="Onboard your first customer to start routing their AI requests through NeuroRoute."
          actions={[{label:'Onboard Customer', onClick:function(){setOnboarding(true);}, primary:true}]}/> :
        <>
          <div className="metric-grid">
            <Metric icon="customers" color="blue" value={customers.length} label="Total customers"/>
            <Metric icon="zap" color="cyan" value={fmtNum(customers.reduce(function(a,b){return a+(b.total_requests||b.reqs||0);},0))} label="Requests (30d)"/>
            <Metric icon="dollar" color="green" value={fmtUSD(customers.reduce(function(a,b){return a+(b.total_cost||b.revenue||0);},0),0)} label="Revenue (30d)"/>
          </div>
          <SectionCard title="Organizations" pad={false}>
            <div className="scroll-x"><table className="table">
              <thead><tr><th>Organization</th><th>Plan</th><th style={{textAlign:'right'}}>Requests</th><th style={{textAlign:'right'}}>Cost</th><th>Status</th><th></th></tr></thead>
              <tbody>{customers.map(function(c){
                var id = c.id||c.org_id||c.org;
                return (
                  <tr key={id}>
                    <td><div style={{fontWeight:600,color:'var(--tx-0)'}}>{c.name||c.org_name||c.org}</div><div className="faint" style={{fontSize:12}}>{c.email||c.billing_email||''}</div></td>
                    <td><Badge color={(c.plan||'free')==='enterprise'?'purple':(c.plan||'free')==='pro'?'blue':'gray'}>{c.plan||'Free'}</Badge></td>
                    <td className="num" style={{textAlign:'right'}}>{fmtNum(c.total_requests||c.reqs||0)}</td>
                    <td className="num" style={{textAlign:'right'}}>{fmtUSD(c.total_cost||c.revenue||0,2)}</td>
                    <td><Badge color={(c.status||'active')==='active'?'green':'amber'} dot>{c.status||'Active'}</Badge></td>
                    <td style={{textAlign:'right'}}><button className="btn btn-soft btn-sm" onClick={function(){openEdit(c);}}><Icon name="settings" size={13}/>Edit</button></td>
                  </tr>
                );
              })}</tbody>
            </table></div>
          </SectionCard>
        </>
      }

      {/* Onboard modal */}
      {onboarding && <Modal title="Onboard new customer" sub="Creates a new organization with an admin user." onClose={function(){setOnboarding(false);}}
        footer={<><button className="btn btn-ghost" onClick={function(){setOnboarding(false);}}>Cancel</button><button className="btn btn-primary" disabled={!newOrg.org||!newOrg.email||creating} onClick={createCustomer}>{creating?'Creating…':'Create customer'}</button></>}>
        <div className="grid" style={{gap:16}}>
          <div className="grid" style={{gridTemplateColumns:'1fr 1fr',gap:16}}>
            <Field label="Organization name"><input className="input" placeholder="Acme Corp" value={newOrg.org} onChange={function(e){setNewOrg(Object.assign({},newOrg,{org:e.target.value}));}}/></Field>
            <Field label="Admin name"><input className="input" placeholder="Jane Smith" value={newOrg.name} onChange={function(e){setNewOrg(Object.assign({},newOrg,{name:e.target.value}));}}/></Field>
          </div>
          <Field label="Admin email"><input className="input" type="email" placeholder="admin@acme.com" value={newOrg.email} onChange={function(e){setNewOrg(Object.assign({},newOrg,{email:e.target.value}));}}/></Field>
        </div>
      </Modal>}

      {/* Edit modal */}
      {editing && <Modal title="Edit organization" sub={(editing.email||editing.billing_email||'')} onClose={function(){setEditing(null);}}
        footer={<><button className="btn btn-ghost" onClick={function(){setEditing(null);}}>Cancel</button><button className="btn btn-primary" disabled={!editName.trim()||saving} onClick={saveEdit}>{saving?'Saving…':'Save changes'}</button></>}>
        <div className="grid" style={{gap:16}}>
          <Field label="Organization name"><input className="input" value={editName} onChange={function(e){setEditName(e.target.value);}}/></Field>
          {(editing.id||editing.org_id) && <Field label="Organization ID"><input className="input input-mono" value={editing.id||editing.org_id} readOnly/></Field>}
          <Field label="Monthly budget cap (USD)" hint="Hard limit on provider spend per month. Leave blank for unlimited. Requests are rejected once the cap is reached.">
            <input className="input" type="number" min="0" step="1" placeholder="Unlimited" value={editBudget} onChange={function(e){setEditBudget(e.target.value);}}/>
          </Field>

          <div className="spread" style={{padding:'4px 0'}}>
            <div style={{maxWidth:'70%'}}>
              <div style={{fontWeight:600}}>Semantic cache <Badge color="amber" style={{fontSize:10}}>beta</Badge></div>
              <div className="faint" style={{fontSize:12.5}}>Reuse cached answers for near-duplicate prompts (skips the model call). Big savings on repetitive workloads; can occasionally return a close-but-not-identical answer.</div>
            </div>
            <Switch on={editSemCache} onChange={setEditSemCache}/>
          </div>

          <div className="spread" style={{padding:'4px 0'}}>
            <div style={{maxWidth:'70%'}}>
              <div style={{fontWeight:600}}>Context compression</div>
              <div className="faint" style={{fontSize:12.5}}>Shrink input tokens before the model (whitespace, JSON, log dedup). Deterministic & lossless. Savings shown on the customer's Usage page.</div>
            </div>
            <Switch on={editComp} onChange={setEditComp}/>
          </div>
          {editComp && <div className="spread" style={{padding:'4px 0 4px 16px'}}>
            <div style={{maxWidth:'70%'}}>
              <div style={{fontWeight:600,fontSize:13}}>Aggressive mode <Badge color="red" style={{fontSize:10}}>test only</Badge></div>
              <div className="faint" style={{fontSize:12}}>Lossy — also strips code comments & collapses repeats. Only enable for test orgs.</div>
            </div>
            <Switch on={editCompAggr} onChange={setEditCompAggr}/>
          </div>}

          <hr className="divider"/>
          <div className="spread">
            <div><div style={{fontWeight:600}}>Monthly billing</div><div className="faint" style={{fontSize:12.5}}>Finalize {thisMonth()} into an invoiceable record.</div></div>
            <button className="btn btn-soft btn-sm" disabled={finalizing} onClick={finalizeBilling}><Icon name="billing" size={14}/>{finalizing?'Finalizing…':'Finalize '+thisMonth()}</button>
          </div>

          {records.length>0 && <div>
            <div className="faint" style={{fontSize:12,marginBottom:8,letterSpacing:'.04em',textTransform:'uppercase'}}>Billing records</div>
            <table className="table">
              <thead><tr><th>Period</th><th>Status</th><th style={{textAlign:'right'}}>Markup</th><th style={{textAlign:'right'}}>Total charge</th><th></th></tr></thead>
              <tbody>{records.map(function(rec){
                var m = (rec.period_start||'').slice(0,7); // YYYY-MM
                var orgId = editing.id||editing.org_id;
                return (
                <tr key={rec.id}>
                  <td className="mono faint" style={{fontSize:12}}>{rec.period_start} → {rec.period_end}</td>
                  <td><Badge color={rec.status==='finalized'?'green':rec.status==='exported'?'cyan':'gray'} dot>{rec.status}</Badge></td>
                  <td className="num" style={{textAlign:'right'}}>{fmtUSD(rec.sisl_markup_amount||0,2)}</td>
                  <td className="num" style={{textAlign:'right',fontWeight:700}}>{fmtUSD(rec.total_customer_charge||0,2)}</td>
                  <td style={{textAlign:'right'}}><button className="iconbtn" title="Download CSV" onClick={function(){window.open('/v1/admin/organizations/'+orgId+'/billing/export?month='+m,'_blank');}}><Icon name="download" size={14}/></button></td>
                </tr>
              );})}</tbody>
            </table>
          </div>}
        </div>
      </Modal>}
    </div>
  );
}

/* =====================  ONBOARD CUSTOMER  ===================== */
function OnboardPage(){
  var t=useToast();
  var _form=useState({org:'',email:'',name:''}); var form=_form[0], setForm=_form[1];
  var _done=useState(null); var done=_done[0], setDone=_done[1];
  var _submitting=useState(false); var submitting=_submitting[0], setSubmitting=_submitting[1];
  var set=function(k,v){setForm(function(f){var n=Object.assign({},f); n[k]=v; return n;});};

  var create=function(){
    setSubmitting(true);
    NR_API.onboard(form.org, form.email, form.name).then(function(res){
      setSubmitting(false);
      if(res && !res.error) {
        setDone(Object.assign({}, form, res));
        t({title:'Customer created'});
      } else {
        t({kind:'error', title:'Failed to onboard', msg:(res&&res.error&&res.error.message)||'Check server logs.'});
      }
    }).catch(function(){ setSubmitting(false); t({kind:'error', title:'Failed to onboard'}); });
  };

  return (
    <div className="grid" style={{gap:18,maxWidth:760}}>
      <PageHead desc="Provision a new customer organization with an admin account."/>
      {!done ? <SectionCard title="New customer">
        <div className="grid" style={{gap:16}}>
          <div className="grid" style={{gridTemplateColumns:'1fr 1fr',gap:16}}>
            <Field label="Organization name"><input className="input" placeholder="Acme Corp" value={form.org} onChange={function(e){set('org',e.target.value);}}/></Field>
            <Field label="Admin name"><input className="input" placeholder="Jane Smith" value={form.name} onChange={function(e){set('name',e.target.value);}}/></Field>
          </div>
          <Field label="Admin email"><input className="input" type="email" placeholder="admin@acme.com" value={form.email} onChange={function(e){set('email',e.target.value);}}/></Field>
          <button className="btn btn-primary btn-block btn-lg" disabled={!form.org||!form.email||submitting} onClick={create}>
            <Icon name="onboard" size={16}/>{submitting?'Creating…':'Create customer'}
          </button>
        </div>
      </SectionCard> : (
        <SectionCard title="Customer created">
          <div className="card card-pad" style={{background:'var(--green-t)',borderColor:'rgba(16,185,129,.3)',marginBottom:16}}>
            <div className="row" style={{gap:10}}><Icon name="checkcircle" size={20} style={{color:'var(--green)'}}/><b style={{fontSize:15}}>{done.org||done.org_name} is ready</b></div>
          </div>
          <div className="grid" style={{gap:12}}>
            {[
              ['Organization', done.org||done.org_name],
              ['Admin email', done.email],
              done.org_id ? ['Organization ID', done.org_id] : null,
              done.api_key ? ['API Key', done.api_key] : null,
            ].filter(Boolean).map(function(pair){return (
              <div key={pair[0]} className="spread" style={{padding:'12px 14px',background:'var(--bg-inset)',borderRadius:10}}>
                <span className="faint">{pair[0]}</span><span className="mono" style={{color:'var(--tx-0)'}}>{pair[1]}</span>
              </div>
            );})}
          </div>
          <div className="row" style={{gap:10,marginTop:18}}>
            <button className="btn btn-primary" onClick={function(){setDone(null);setForm({org:'',email:'',name:''});}}>Onboard another</button>
            <button className="btn btn-ghost" onClick={function(){go('customers');}}>View customers</button>
          </div>
        </SectionCard>
      )}
    </div>
  );
}

/* =====================  SISL PROVIDER KEYS  ===================== */
function SislKeysPage(){
  var t=useToast();
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  var _keys=useState([]); var keys=_keys[0], setKeys=_keys[1];
  var _modal=useState(false); var modal=_modal[0], setModal=_modal[1];
  var _provider=useState('openai'); var provider=_provider[0], setProvider=_provider[1];
  var _key=useState(''); var key=_key[0], setKey=_key[1];
  var _label=useState(''); var label=_label[0], setLabel=_label[1];
  var _adding=useState(false); var adding=_adding[0], setAdding=_adding[1];

  useEffect(function(){
    NR_API.providerKeys().then(function(res){
      if(res && Array.isArray(res.keys||res)) { setKeys(res.keys||res); }
      setLoading(false);
    }).catch(function(){ setLoading(false); });
  },[]);

  var addKey=function(){
    if(!key) return;
    setAdding(true);
    NR_API.addProviderKey(provider, key, label||provider).then(function(res){
      setAdding(false);
      if(res && !res.error) {
        setKeys(function(ks){return [{provider:provider, label:label||provider, masked:'••••'+key.slice(-4), created_at:new Date().toISOString(), status:'active'}].concat(ks);});
        setModal(false); setKey(''); setLabel('');
        t({title:'Provider key added'});
      } else {
        t({kind:'error',title:'Failed to add key',msg:(res&&res.error&&res.error.message)||''});
      }
    }).catch(function(){ setAdding(false); t({kind:'error',title:'Failed to add key'}); });
  };

  if(loading) return <LoadingPage/>;

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="SISL-managed provider API keys used as fallback for customers without their own keys.">
        <button className="btn btn-primary btn-sm" onClick={function(){setModal(true);}}><Icon name="plus" size={15}/>Add provider key</button>
      </PageHead>

      {keys.length===0 ?
        <EmptyState icon="key" title="No provider keys registered"
          desc="Add your provider API keys (OpenAI, Anthropic, Google, etc.) so NeuroRoute can route requests through them."
          actions={[{label:'Add Provider Key', onClick:function(){setModal(true);}, primary:true}]}/> :
        <SectionCard title="Provider keys" sub={keys.length+' keys'} pad={false}>
          <div className="scroll-x"><table className="table">
            <thead><tr><th>Provider</th><th>Label</th><th>Key (masked)</th><th>Added</th><th>Status</th></tr></thead>
            <tbody>{keys.map(function(k,i){
              var prov = window.DATA.providerById(k.provider||'');
              return (
                <tr key={i}>
                  <td><span className="row" style={{gap:8}}><ProviderLogo id={k.provider} size={24}/>{prov.name}</span></td>
                  <td className="faint">{k.label||k.provider}</td>
                  <td className="mono faint" style={{fontSize:12}}>{k.masked||k.key_preview||'••••••'}</td>
                  <td className="faint">{timeAgo(k.created_at)||'—'}</td>
                  <td><Badge color={(k.status||'active')==='active'?'green':'amber'} dot>{k.status||'active'}</Badge></td>
                </tr>
              );
            })}</tbody>
          </table></div>
        </SectionCard>
      }

      {modal && <Modal title="Add provider key" onClose={function(){setModal(false);}}
        footer={<><button className="btn btn-ghost" onClick={function(){setModal(false);}}>Cancel</button><button className="btn btn-primary" disabled={!key||adding} onClick={addKey}>{adding?'Adding…':'Add key'}</button></>}>
        <div className="grid" style={{gap:16}}>
          <Field label="Provider"><select className="select" value={provider} onChange={function(e){setProvider(e.target.value);}}>
            {window.DATA.PROVIDERS.map(function(p){return <option key={p.id} value={p.id}>{p.name}</option>;})}</select></Field>
          <Field label="Label" hint="Optional — to distinguish multiple keys per provider."><input className="input" placeholder="e.g. Production" value={label} onChange={function(e){setLabel(e.target.value);}}/></Field>
          <Field label="API key"><input className="input input-mono" placeholder="sk-..." value={key} onChange={function(e){setKey(e.target.value);}}/></Field>
        </div>
      </Modal>}
    </div>
  );
}

/* =====================  PRICING  ===================== */
function PricingPage(){
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  var _models=useState([]); var models=_models[0], setModels=_models[1];

  useEffect(function(){
    NR_API.models().then(function(res){
      var list = (res && (res.data||res.models||res)) || [];
      /* Merge with reference data for pricing/quality (server only returns id + owned_by) */
      setModels(list.map(function(m){
        var info = window.DATA.modelById(m.id);
        return Object.assign({}, info, {id:m.id});
      }));
      setLoading(false);
    }).catch(function(){
      setModels(window.DATA.MODELS);
      setLoading(false);
    });
  },[]);

  if(loading) return <LoadingPage/>;

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc={'Platform pricing — '+models.length+' models registered. Cost per 1M tokens used for billing & savings calculations.'}/>
      <SectionCard title="Per-model pricing" pad={false}>
        <div className="scroll-x"><table className="table">
          <thead><tr><th>Model</th><th>Provider</th><th style={{textAlign:'right'}}>Input / 1M</th><th style={{textAlign:'right'}}>Output / 1M</th><th style={{textAlign:'right'}}>Quality</th><th style={{textAlign:'right'}}>Avg latency</th><th style={{textAlign:'right'}}>Context</th></tr></thead>
          <tbody>{models.map(function(m){return (
            <tr key={m.id}>
              <td><ModelCell id={m.id}/></td>
              <td className="faint">{window.DATA.providerById(m.provider).name}</td>
              <td className="num" style={{textAlign:'right'}}>${(m.in||0).toFixed(2)}</td>
              <td className="num" style={{textAlign:'right'}}>${(m.out||0).toFixed(2)}</td>
              <td className="num" style={{textAlign:'right'}}><Badge color={m.q>=95?'green':m.q>=85?'cyan':'gray'}>{m.q||'—'}</Badge></td>
              <td className="num" style={{textAlign:'right'}}>{m.lat?m.lat+'ms':'—'}</td>
              <td className="num faint" style={{textAlign:'right'}}>{m.ctx||'—'}</td>
            </tr>
          );})}</tbody>
        </table></div>
      </SectionCard>
    </div>
  );
}

/* =====================  MODEL PERFORMANCE  ===================== */
function ModelPrefPage(){
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  var _stats=useState([]); var stats=_stats[0], setStats=_stats[1];
  var _filter=useState('All'); var filter=_filter[0], setFilter=_filter[1];

  useEffect(function(){
    /* Pull live stats from /v1/dashboard/models and reference data from window.DATA */
    Promise.all([NR_API.dashboardModels(), NR_API.models()]).then(function(results){
      var dashData = results[0];
      var modelsData = results[1];
      /* Build a model -> stats map */
      var statsByModel = {};
      var liveList = (dashData && dashData.models) || [];
      liveList.forEach(function(s){ statsByModel[s.model] = s; });
      /* Build the registered models list */
      var registered = [];
      if(modelsData && (modelsData.data || modelsData.models)) {
        registered = modelsData.data || modelsData.models;
      } else {
        /* Fallback to reference data */
        registered = window.DATA.MODELS.map(function(m){return {id:m.id};});
      }
      /* Merge live stats with reference attributes */
      var merged = registered.map(function(m){
        var info = window.DATA.modelById(m.id);
        var live = statsByModel[m.id] || {};
        return {
          id: m.id,
          name: info.name || m.id,
          provider: info.provider || m.owned_by || 'unknown',
          quality: info.q || 0,
          inputPrice: info.in || 0,
          outputPrice: info.out || 0,
          latency: live.avg_latency_ms || info.lat || 0,
          requests: live.request_count || 0,
          totalCost: live.total_cost || 0,
          errorRate: (live.error_rate || 0) * 100, /* convert to % */
        };
      });
      setStats(merged);
      setLoading(false);
    }).catch(function(){ setLoading(false); });
  },[]);

  if(loading) return <LoadingPage/>;

  /* Build provider tab list from reference data + actual data */
  var providers = window.DATA.PROVIDERS.slice();
  /* Also include "self-hosted" pseudo-provider if any model is self-hosted */
  var providerCounts = {};
  stats.forEach(function(s){
    var pid = s.provider;
    providerCounts[pid] = (providerCounts[pid]||0) + 1;
  });

  var visibleProviders = providers.filter(function(p){return providerCounts[p.id]>0;});
  /* Apply filter */
  var filtered = filter==='All' ? stats : stats.filter(function(s){return s.provider===filter;});

  var totalRequests = stats.reduce(function(a,b){return a+b.requests;},0);
  var totalSpend = stats.reduce(function(a,b){return a+b.totalCost;},0);

  /* Color helpers */
  var latColor = function(ms){
    if(!ms) return 'var(--tx-3)';
    if(ms < 200) return 'var(--green)';
    if(ms < 400) return 'var(--amber)';
    return 'var(--red)';
  };
  var errColor = function(pct){
    if(pct < 0.2) return 'var(--green)';
    if(pct < 1.0) return 'var(--amber)';
    return 'var(--red)';
  };
  var fmtCost = function(v){
    if(v >= 1000) return '$'+(v/1000).toFixed(1)+'K';
    if(v >= 1) return '$'+v.toFixed(2);
    return '$'+v.toFixed(4);
  };
  var fmtReq = function(n){
    if(n >= 1000) return (n/1000).toFixed(1)+'K';
    return ''+n;
  };

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc={stats.length+' models · '+fmtNum(totalRequests)+' requests · '+fmtUSD(totalSpend,2)+' total spend (30d)'}/>

      {/* Provider filter tabs */}
      <div className="row" style={{gap:8,flexWrap:'wrap'}}>
        <button className={'chip'+(filter==='All'?' chip-active':'')} onClick={function(){setFilter('All');}}
          style={filter==='All'?{background:'var(--blue-t)',color:'var(--blue)',borderColor:'rgba(59,130,246,.4)'}:null}>
          <span className="statusdot" style={{background:filter==='All'?'var(--blue)':'var(--tx-3)'}}/>
          All <span className="faint">{stats.length}</span>
        </button>
        {visibleProviders.map(function(p){
          var active = filter===p.id;
          return (
            <button key={p.id} className="chip" onClick={function(){setFilter(p.id);}}
              style={active?{background:'rgba(59,130,246,.12)',color:'var(--tx-0)',borderColor:p.color}:null}>
              <span className="statusdot" style={{background:active?p.color:'var(--tx-3)'}}/>
              {p.name} <span className="faint">{providerCounts[p.id]||0}</span>
            </button>
          );
        })}
      </div>

      {filtered.length===0 ?
        <EmptyState icon="modelpref" title="No model data"
          desc="No requests have been routed through these models yet. Send a request via the Playground to see performance stats."/> :
        <div className="grid" style={{gridTemplateColumns:'repeat(auto-fill, minmax(300px, 1fr))', gap:14}}>
          {filtered.map(function(m){
            var prov = window.DATA.providerById(m.provider);
            return (
              <div key={m.id} className="card" style={{padding:16, borderLeft:'3px solid '+prov.color}}>
                {/* Header */}
                <div className="row" style={{gap:10,marginBottom:14}}>
                  <ProviderLogo id={m.provider} size={36}/>
                  <div className="stack" style={{minWidth:0,flex:1}}>
                    <div style={{fontWeight:700,fontSize:14,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{m.id}</div>
                    <div className="faint" style={{fontSize:11.5}}>{prov.name}</div>
                  </div>
                </div>

                {/* p50 Latency */}
                <div style={{marginBottom:10}}>
                  <div className="spread" style={{fontSize:12,marginBottom:4}}>
                    <span className="faint">p50 Latency</span>
                    <span className="mono" style={{color:latColor(m.latency),fontWeight:700}}>{m.latency?Math.round(m.latency)+'ms':'—'}</span>
                  </div>
                  <div className="meter"><span style={{width:Math.min(100,(m.latency/600)*100)+'%',background:latColor(m.latency)}}/></div>
                </div>

                {/* Quality Score */}
                <div style={{marginBottom:14}}>
                  <div className="spread" style={{fontSize:12,marginBottom:4}}>
                    <span className="faint">Quality Score</span>
                    <span className="mono" style={{fontWeight:700,color:'var(--tx-0)'}}>{m.quality?m.quality.toFixed(1)+'%':'—'}</span>
                  </div>
                  <div className="meter"><span style={{width:Math.min(100,m.quality)+'%',background:'var(--blue)'}}/></div>
                </div>

                {/* Bottom stats */}
                <div className="grid" style={{gridTemplateColumns:'repeat(3,1fr)',gap:8,paddingTop:12,borderTop:'1px solid var(--line)'}}>
                  <div>
                    <div className="faint" style={{fontSize:11}}>Error Rate</div>
                    <div className="mono" style={{fontSize:13,marginTop:2,color:errColor(m.errorRate),fontWeight:700}}>{m.errorRate.toFixed(2)}%</div>
                  </div>
                  <div>
                    <div className="faint" style={{fontSize:11}}>Requests</div>
                    <div className="mono" style={{fontSize:13,marginTop:2,fontWeight:700}}>{fmtReq(m.requests)}</div>
                  </div>
                  <div>
                    <div className="faint" style={{fontSize:11}}>Cost (30d)</div>
                    <div className="mono" style={{fontSize:13,marginTop:2,fontWeight:700}}>{fmtCost(m.totalCost)}</div>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      }
    </div>
  );
}

/* =====================  HEALTH MONITOR  ===================== */
function HealthPage(){
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  var _healthData=useState(null); var healthData=_healthData[0], setHealthData=_healthData[1];
  var _modelStats=useState({}); var modelStats=_modelStats[0], setModelStats=_modelStats[1];
  var _routingDecisions=useState([]); var routingDecisions=_routingDecisions[0], setRoutingDecisions=_routingDecisions[1];
  var _lastRefresh=useState(null); var lastRefresh=_lastRefresh[0], setLastRefresh=_lastRefresh[1];
  var _expanded=useState({}); var expanded=_expanded[0], setExpanded=_expanded[1];

  var refresh=function(){
    setLoading(true);
    Promise.all([NR_API.health(), NR_API.dashboardModels(), NR_API.dashboardRouting(100)]).then(function(results){
      setHealthData(results[0]);
      /* Build model stats map keyed by model id */
      var statMap = {};
      var liveList = (results[1] && results[1].models) || [];
      liveList.forEach(function(s){ statMap[s.model] = s; });
      setModelStats(statMap);
      setRoutingDecisions((results[2] && results[2].decisions) || []);
      setLastRefresh(new Date());
      setLoading(false);
    }).catch(function(){ setLoading(false); });
  };

  useEffect(function(){
    refresh();
    /* Auto-refresh every 60s */
    var iv = setInterval(refresh, 60000);
    return function(){ clearInterval(iv); };
  },[]);

  if(loading && !healthData) return <LoadingPage/>;

  /* Group health data by provider with real metrics */
  var groups = groupHealthByProvider(healthData).map(function(g){
    /* Aggregate per-provider metrics from model_stats */
    var totalLat = 0, latCount = 0, totalReqs = 0, totalErrors = 0;
    g.models.forEach(function(m){
      var stat = modelStats[m.id];
      if(stat) {
        if(stat.avg_latency_ms > 0) { totalLat += stat.avg_latency_ms; latCount++; }
        totalReqs += stat.request_count || 0;
        totalErrors += (stat.error_rate || 0) * (stat.request_count || 0);
      }
    });
    var avgLat = latCount>0 ? Math.round(totalLat/latCount) : 0;
    var successRate = totalReqs>0 ? Math.max(0, Math.min(100, 100 - (totalErrors/totalReqs)*100)) : 100;
    /* Score = blend of health (70%) + success (30%) */
    var healthScore = g.total>0 ? (g.healthy/g.total)*100 : 0;
    var score = Math.round(healthScore*0.7 + successRate*0.3);
    /* Build a synthetic 24-bucket latency sparkline from recent routing decisions for this provider */
    var providerLatencies = routingDecisions
      .filter(function(d){
        var mInfo = window.DATA.modelById(d.model||d.Model||'');
        return mInfo.provider === g.id;
      })
      .map(function(d){ return d.routing_latency_ms || d.RoutingLatencyMs || avgLat || 0; });
    /* If no real history, fall back to a flat line at avgLat (still real — not random) */
    var spark = providerLatencies.length >= 3 ? providerLatencies.slice(0,24).reverse() :
                (avgLat > 0 ? [avgLat,avgLat,avgLat,avgLat,avgLat,avgLat,avgLat,avgLat] : []);
    return Object.assign({}, g, {avgLat:avgLat, successRate:successRate, score:score, totalReqs:totalReqs, spark:spark});
  });

  var overallOk = groups.length>0 && groups.every(function(g){return g.status==='optimal';});
  var hasDegraded = groups.some(function(g){return g.status!=='optimal';});

  /* Build "Recent incidents" list from groups currently degraded */
  var incidents = groups.filter(function(g){return g.status!=='optimal';}).map(function(g){
    var downModels = g.models.filter(function(m){return m.status!=='ok';});
    return {
      provider: g,
      severity: g.status==='down' ? 'red' : 'amber',
      title: g.status==='down' ? 'Provider unavailable' : (downModels.length+' of '+g.total+' models failing health probe'),
      detail: downModels.map(function(m){return m.name;}).join(', ') || 'unknown',
    };
  });

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc={'Real-time provider health from background probes. Auto-refreshes every 60s.'}>
        <div className="row" style={{gap:10}}>
          {lastRefresh && <span className="faint" style={{fontSize:12}}>Updated {timeAgo(lastRefresh.toISOString())}</span>}
          <button className="btn btn-soft btn-sm" onClick={refresh} disabled={loading}><Icon name="refresh" size={15}/>{loading?'Refreshing…':'Refresh'}</button>
        </div>
      </PageHead>

      <div className="card card-pad" style={{background:overallOk?'var(--green-t)':'var(--amber-t)',borderColor:overallOk?'rgba(16,185,129,.3)':'rgba(245,158,11,.3)'}}>
        <div className="row" style={{gap:10}}>
          <Icon name={overallOk?'checkcircle':'alert'} size={20} style={{color:overallOk?'var(--green)':'var(--amber)'}}/>
          <b style={{fontSize:15}}>{overallOk ? 'All providers operational' : 'Some providers degraded'}</b>
          {healthData && healthData.status && <Badge color={healthData.status==='ok'?'green':'amber'}>{healthData.status}</Badge>}
          <span className="faint" style={{marginLeft:'auto',fontSize:12}}>
            {groups.length} provider{groups.length===1?'':'s'} · {groups.reduce(function(a,b){return a+b.healthy;},0)}/{groups.reduce(function(a,b){return a+b.total;},0)} models healthy
          </span>
        </div>
      </div>

      {groups.length===0 ?
        <EmptyState icon="health" title="No health data"
          desc="The health endpoint returned no provider information. Make sure models are registered and the health monitor is running."/> :
        <div className="cards-grid">
          {groups.map(function(g){
            var statusColor = g.status==='optimal'?'green':g.status==='degraded'?'amber':'red';
            var latColor = g.avgLat===0 ? 'var(--tx-3)' : g.avgLat<350 ? COL.green : g.avgLat<700 ? COL.amber : COL.red;
            var isExpanded = expanded[g.id];
            return (
              <div key={g.id} className="card card-pad" style={{borderLeft:'3px solid '+g.color}}>
                {/* Header — provider + gauge */}
                <div className="spread" style={{marginBottom:8}}>
                  <span className="row" style={{gap:11}}>
                    <ProviderLogo id={g.id} size={40}/>
                    <div>
                      <div style={{fontWeight:700,fontSize:15}}>{g.name}</div>
                      <Badge color={statusColor} dot>{g.status}</Badge>
                    </div>
                  </span>
                  <Gauge value={g.score} size={64}/>
                </div>

                {/* Latency + Success rate tiles */}
                <div className="grid" style={{gridTemplateColumns:'1fr 1fr',gap:10,margin:'14px 0 12px'}}>
                  <div style={{padding:'10px 12px',background:'var(--bg-inset)',borderRadius:10,border:'1px solid var(--line)'}}>
                    <div className="faint" style={{fontSize:11.5}}>Avg latency</div>
                    <div className="mono" style={{fontSize:18,color:latColor,marginTop:2,fontWeight:700}}>{g.avgLat>0 ? g.avgLat+'ms' : '—'}</div>
                  </div>
                  <div style={{padding:'10px 12px',background:'var(--bg-inset)',borderRadius:10,border:'1px solid var(--line)'}}>
                    <div className="faint" style={{fontSize:11.5}}>Success rate</div>
                    <div className="mono" style={{fontSize:18,marginTop:2,fontWeight:700,color: g.successRate>=99 ? COL.green : g.successRate>=95 ? COL.amber : COL.red}}>{g.successRate.toFixed(1)}%</div>
                  </div>
                </div>

                {/* Latency sparkline */}
                {g.spark.length>0 && <div style={{marginTop:6}}>
                  <div className="spread" style={{marginBottom:4}}>
                    <span className="faint" style={{fontSize:11}}>Latency · recent {g.spark.length} requests</span>
                    <span className="mono faint" style={{fontSize:10}}>{g.totalReqs>0 ? fmtNum(g.totalReqs)+' total reqs' : 'no traffic yet'}</span>
                  </div>
                  <Spark data={g.spark} color={latColor} w={280} h={42} fill={false}/>
                </div>}

                {/* Model breakdown — collapsible */}
                <button className="btn btn-soft btn-sm" style={{marginTop:12,width:'100%'}} onClick={function(){
                  setExpanded(function(e){var n=Object.assign({},e); n[g.id]=!n[g.id]; return n;});
                }}>
                  <Icon name={isExpanded?'arrowup':'arrowdown'} size={13}/>
                  {isExpanded?'Hide':'Show'} {g.total} model{g.total===1?'':'s'}
                </button>

                {isExpanded && <div className="grid" style={{gap:6,marginTop:10}}>
                  {g.models.map(function(m){
                    var stat = modelStats[m.id];
                    return (
                      <div key={m.id} className="row" style={{gap:8,padding:'7px 10px',background:'var(--bg-inset)',borderRadius:8}}>
                        <span className="statusdot" style={{background:m.status==='ok'?'var(--green)':'var(--red)'}}/>
                        <span style={{fontSize:12.5,fontWeight:600,flex:1,minWidth:0,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{m.name}</span>
                        {stat && stat.avg_latency_ms > 0 && <span className="mono faint" style={{fontSize:11}}>{Math.round(stat.avg_latency_ms)}ms</span>}
                        <span className="mono faint" style={{fontSize:10.5,width:30,textAlign:'right'}}>{m.status}</span>
                      </div>
                    );
                  })}
                </div>}
              </div>
            );
          })}
        </div>
      }

      {/* Recent incidents */}
      {incidents.length>0 && <SectionCard title="Active incidents" sub="Providers currently in a degraded state" pad={false}>
        <table className="table">
          <tbody>
            {incidents.map(function(inc,i){return (
              <tr key={i}>
                <td>
                  <span className="row" style={{gap:8}}>
                    <span className="statusdot" style={{background:'var(--'+inc.severity+')'}}/>
                    <b style={{color:'var(--tx-0)'}}>{inc.provider.name}</b>
                  </span>
                </td>
                <td><Badge color={inc.severity}>{inc.provider.status}</Badge></td>
                <td className="faint" style={{fontSize:13}}>{inc.title}</td>
                <td className="faint mono" style={{fontSize:12,textAlign:'right'}}>{inc.detail}</td>
              </tr>
            );})}
          </tbody>
        </table>
      </SectionCard>}

      {!hasDegraded && groups.length>0 && <div className="card card-pad" style={{background:'var(--bg-inset)',textAlign:'center'}}>
        <Icon name="checkcircle" size={20} style={{color:'var(--green)',marginRight:8}}/>
        <span className="faint" style={{fontSize:13}}>No active incidents · All probes returning <span className="mono">ok</span></span>
      </div>}
    </div>
  );
}

/* =====================  AUDIT LOG  ===================== */
function AuditPage(){
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  var _events=useState([]); var events=_events[0], setEvents=_events[1];

  useEffect(function(){
    NR_API.auditLog().then(function(res){
      if(res && Array.isArray(res.events||res)) {
        setEvents(res.events||res);
      }
      setLoading(false);
    }).catch(function(){ setLoading(false); });
  },[]);

  if(loading) return <LoadingPage/>;

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="Immutable record of security-sensitive actions across the platform."/>

      {events.length===0 ?
        <EmptyState icon="audit" title="No audit events yet"
          desc="Security-sensitive actions (key creation, role changes, config updates) will appear here automatically."/> :
        <SectionCard title="Audit log" sub={events.length+' events'} pad={false}>
          <div className="scroll-x"><table className="table">
            <thead><tr><th>Timestamp</th><th>Actor</th><th>Event</th><th>Resource</th><th>IP address</th></tr></thead>
            <tbody>{events.map(function(a,i){return (
              <tr key={i}>
                <td className="num faint" style={{whiteSpace:'nowrap'}}>{a.ts||a.timestamp||timeAgo(a.created_at)}</td>
                <td style={{color:'var(--tx-0)'}}>{a.actor||a.user||'system'}</td>
                <td><Badge color={eventColor(a.event||a.action)}>{a.event||a.action}</Badge></td>
                <td className="num faint">{a.resource||a.details||''}</td>
                <td className="num faint">{a.ip||a.ip_address||'—'}</td>
              </tr>
            );})}</tbody>
          </table></div>
        </SectionCard>
      }
    </div>
  );
}

/* =====================  LOGIN ACCESS (domain allowlist)  ===================== */
function AccessPage(){
  var t=useToast();
  var _loading=useState(true); var loading=_loading[0], setLoading=_loading[1];
  var _domains=useState([]); var domains=_domains[0], setDomains=_domains[1];
  var _input=useState(''); var input=_input[0], setInput=_input[1];
  var _adding=useState(false); var adding=_adding[0], setAdding=_adding[1];

  var load=function(){
    NR_API.allowedDomains().then(function(res){
      if(res && Array.isArray(res.domains)) setDomains(res.domains); else setDomains([]);
      setLoading(false);
    }).catch(function(){ setLoading(false); });
  };
  useEffect(load, []);

  var add=function(){
    var d=input.trim();
    if(!d) return;
    setAdding(true);
    NR_API.addAllowedDomain(d).then(function(res){
      setAdding(false);
      if(res && res.status==='allowed'){
        setInput('');
        t({title:'Domain whitelisted', msg:res.domain});
        load();
      } else {
        t({kind:'error', title:'Failed to add domain', msg:(res&&res.error)||'Enter a valid domain like acme.com'});
      }
    }).catch(function(){ setAdding(false); t({kind:'error', title:'Failed to add domain'}); });
  };

  var remove=function(domain){
    NR_API.removeAllowedDomain(domain).then(function(ok){
      if(ok){ setDomains(function(ds){return ds.filter(function(x){return x.domain!==domain;});}); t({kind:'info', title:'Domain removed', msg:domain}); }
      else t({kind:'error', title:'Failed to remove domain'});
    }).catch(function(){ t({kind:'error', title:'Failed to remove domain'}); });
  };

  if(loading) return <LoadingPage/>;

  return (
    <div className="grid" style={{gap:18}}>
      <PageHead desc="Only users whose email domain is whitelisted here can sign in. Everyone else sees a “Contact SISL CloudWorx Sales” page. SISL admins always have access."/>

      <SectionCard title="Add a domain" sub="e.g. acme.com — onboarding a customer auto-adds their domain.">
        <div className="row" style={{gap:10}}>
          <input className="input" style={{flex:1}} placeholder="acme.com or admin@acme.com" value={input}
            onChange={function(e){setInput(e.target.value);}} onKeyDown={function(e){if(e.key==='Enter') add();}}/>
          <button className="btn btn-primary" disabled={!input.trim()||adding} onClick={add}><Icon name="plus" size={15}/>{adding?'Adding…':'Whitelist domain'}</button>
        </div>
      </SectionCard>

      {domains.length===0 ?
        <div className="card card-pad" style={{background:'var(--amber-t)',borderColor:'rgba(245,158,11,.3)'}}>
          <div className="row" style={{gap:10}}><Icon name="alert" size={17} style={{color:'var(--amber)'}}/>
          <span><b>No domains whitelisted.</b> Only SISL admins can sign in right now. Add a customer's domain (or onboard them) to let them log in.</span></div>
        </div> :
        <SectionCard title="Whitelisted domains" sub={domains.length+' domain'+(domains.length===1?'':'s')+' may sign in'} pad={false}>
          <table className="table">
            <thead><tr><th>Domain</th><th>Added by</th><th>Added</th><th></th></tr></thead>
            <tbody>{domains.map(function(d){return (
              <tr key={d.domain}>
                <td style={{fontWeight:600,color:'var(--tx-0)'}}>@{d.domain}</td>
                <td className="mono faint" style={{fontSize:12}}>{d.added_by||'—'}</td>
                <td className="faint">{timeAgo(d.created_at)||'—'}</td>
                <td style={{textAlign:'right'}}><button className="btn btn-danger btn-sm" onClick={function(){remove(d.domain);}}>Remove</button></td>
              </tr>
            );})}</tbody>
          </table>
        </SectionCard>
      }
    </div>
  );
}

window.PAGES = Object.assign(window.PAGES||{}, {customers:CustomersPage, onboard:OnboardPage,
  sislkeys:SislKeysPage, pricing:PricingPage, modelpref:ModelPrefPage, health:HealthPage, access:AccessPage, audit:AuditPage});
