/* ============================================================
   REYAH PLATFORM, ADMIN APP (Reyah internal)
   Portfolio health · deliverability monitoring · per-client SLA
   ============================================================ */
/* Data binding. A / AMETRICS / ANAV are re-derived after REYAH_DATA.load()
   resolves (mock or live) in the bootstrap at the bottom of this file. */
let A = window.RYH.admin;
const apct = v => v+"%";

function buildAMetrics(){
  const AMETRICS = {
  positives:{ id:"a-positives", icon:"zap", label:"Positive replies", value:A.totals.positiveReplies, raw:A.totals.positiveReplies, kind:"cumulative",
    delta:A.deltas.positiveReplies, deltaLabel:"vs last 30 days", color:"#1F8A5B",
    breakdownTitle:"By client", breakdown:A.clients.map(c=>({label:c.name,value:c.positive,pct:c.positive/28*100,kind:"pos"})),
    note:"Total positive replies across every live campaign. The portfolio north-star." },
  contacted:{ id:"a-contacted", icon:"users", label:"Doctors contacted", value:A.totals.contacted.toLocaleString(), raw:A.totals.contacted, kind:"cumulative",
    delta:A.deltas.contacted, deltaLabel:"vs last 30 days", color:"#FF4A1C",
    breakdownTitle:"By client", breakdown:A.clients.map(c=>({label:c.name,value:c.contacted,pct:c.contacted/392*100,kind:"info"})) },
  hires:{ id:"a-hires", icon:"hire", label:"Hires placed", value:A.totals.hires, raw:A.totals.hires, kind:"cumulative",
    delta:A.deltas.hires, deltaLabel:"this quarter", color:"#1F8A5B",
    breakdownTitle:"By client", breakdown:A.clients.filter(c=>c.hires>0).map(c=>({label:c.name,value:c.hires,pct:c.hires/3*100,kind:"pos"})) },
  deliver:{ id:"a-deliver", icon:"send", label:"Avg deliverability", value:A.totals.avgDeliver, unit:"%", raw:A.totals.avgDeliver, kind:"rate",
    delta:A.deltas.avgDeliver, deltaUnit:"pts", deltaLabel:"vs last 30 days", color:"#1F8A5B", fmt:apct,
    breakdownTitle:"By client", breakdown:A.clients.map(c=>({label:c.name,value:c.deliver+"%",pct:c.deliver,kind:c.status==="bad"?"warn":"pos"})),
    note:"Portfolio-wide inbox placement. Drops below 96% trigger an internal review and domain rotation." },
  clients:{ id:"a-clients", icon:"building", label:"Active clients", value:A.totals.clients, raw:A.totals.clients, kind:"cumulative",
    delta:+1, deltaLabel:"this quarter", color:"#FF4A1C" },
  domains:{ id:"a-domains", icon:"globe", label:"Sending domains", value:A.totals.domains, raw:A.totals.domains, kind:"cumulative",
    delta:+3, deltaLabel:"provisioned this month", color:"#2A6FDB" },
  alerts:{ id:"a-alerts", icon:"alert", label:"Reply alerts today", value:A.totals.alertsToday, raw:A.totals.alertsToday, kind:"count",
    delta:+2, deltaLabel:"vs yesterday", color:"#FF4A1C", note:"Positive-reply alerts fired to clients (<60s). Re-alerts at 4h / 12h / 24h until the clinic responds." },
  campaigns:{ id:"a-campaigns", icon:"target", label:"Active campaigns", value:A.totals.activeCampaigns, raw:A.totals.activeCampaigns, kind:"cumulative",
    delta:0, deltaLabel:"live now", color:"#2A6FDB" }
};
  // Deltas derived from each metric's own trend data (live-data ready).
  Object.keys(AMETRICS).forEach(function(k){ AMETRICS[k]=trendDelta(AMETRICS[k]); });
  return AMETRICS;
}
let AMETRICS = buildAMetrics();
const SITE=(window.REYAH_CONFIG&&window.REYAH_CONFIG.siteBase)||"../site";

function buildANav(){ return [
  {label:"Operations", links:[
    {id:"overview", label:"Portfolio overview", icon:"grid"},
    {id:"deliverability", label:"Deliverability monitor", icon:"send", count:3, hot:true},
    {id:"sla", label:"Response-time SLA", icon:"clock"}
  ]},
  {label:"Clients", links:[
    {id:"clients", label:"All clients", icon:"building", count:A.totals.clients},
    {id:"accounts", label:"Client accounts", icon:"key"}
  ]},
  {label:"Reyah", links:[
    {id:"settings", label:"Settings", icon:"settings"}
  ]}
]; }
let ANAV = buildANav();
const ATITLES={
  overview:["Portfolio overview","Every client campaign, one screen"],
  deliverability:["Deliverability monitor","Domain health across all clients"],
  sla:["Response-time SLA","How fast clients action positive replies"],
  clients:["All clients","Live campaign health by clinic"],
  accounts:["Client accounts","Provision & manage clinic logins"],
  settings:["Settings","Workspace, alerts and integrations"]
};

function AKpiCard({m, onOpen, feature}){
  return (
    <div className={"kpi clickable"+(feature?" feature":"")} onClick={function(){onOpen(m);}}>
      <div className="kpi__top"><span className="ic"><Icon n={m.icon} /></span><span className="lab">{m.label}</span></div>
      <div className="kpi__num">{m.value}{m.unit&&<span className="u">{m.unit}</span>}</div>
      <div className="kpi__sub">
        {m.delta!=null && <span className={"delta "+((m.deltaGood?-m.delta:m.delta)>=0?"up":"down")}><Icon n={m.delta>=0?"arrowUp":"arrowDown"} />{m.delta>=0?"+":""}{m.delta}{m.deltaUnit||""}</span>}
        <span>{m.deltaLabel}</span>
      </div>
    </div>
  );
}

function statusTag(s, label){
  if(s==="pos") return <Tag kind="pos" dot>{label||"Healthy"}</Tag>;
  if(s==="warn") return <Tag kind="warn" dot>{label||"Watch"}</Tag>;
  return <Tag kind="bad" dot>{label||"Action"}</Tag>;
}

function AdminOverview({openMetric, goClient}){
  const [range,setRange]=React.useState("3m");
  const ser=window.RYH.genSeries("a-ovpos",range,21,"count");
  const ser2=window.RYH.genSeries("a-ovsent",range,520,"count").data.map(v=>Math.round(v/12));
  return (
    <div className="stack-gap">
      <div className="kpis">
        <AKpiCard m={AMETRICS.positives} onOpen={openMetric} feature />
        <AKpiCard m={AMETRICS.contacted} onOpen={openMetric} />
        <AKpiCard m={AMETRICS.hires} onOpen={openMetric} />
        <AKpiCard m={AMETRICS.deliver} onOpen={openMetric} />
      </div>
      <div className="kpis">
        <AKpiCard m={AMETRICS.clients} onOpen={openMetric} />
        <AKpiCard m={AMETRICS.campaigns} onOpen={openMetric} />
        <AKpiCard m={AMETRICS.domains} onOpen={openMetric} />
        <AKpiCard m={AMETRICS.alerts} onOpen={openMetric} />
      </div>

      <div className="grid-32">
        <PCard title="Portfolio positive replies" sub="Across all live campaigns"
          action={<Seg options={[{value:"30d",label:"30D"},{value:"3m",label:"3M"},{value:"12m",label:"12M"}]} value={range} onChange={setRange} />}>
          <AreaLine labels={ser.labels} height={230} series={[
            {data:ser.data, color:"#1F8A5B", name:"Positive replies"},
            {data:ser2, color:"#FF4A1C", fill:false, name:"Sends (×12)"}
          ]} />
          <div className="legend" style={{marginTop:14}}>
            <span><i style={{background:'#1F8A5B'}} />Positive replies</span>
            <span><i style={{background:'#FF4A1C'}} />Sends (×12)</span>
          </div>
        </PCard>
        <PCard title="Needs attention" sub="Act on these first">
          <Feed items={A.feed} />
        </PCard>
      </div>

      <PCard title="Per-client breakdown" sub={A.totals.clients+" clients · "+A.totals.activeCampaigns+" live campaigns"} pad={false}
        action={<button className="btn btn--ghost btn--sm" onClick={function(){window.ryToast("Exported portfolio breakdown to CSV");}}><Icon n="download" /> Export</button>}>
        <div className="tbl-wrap">
          <table className="tbl">
            <thead><tr>
              <th>Clinic</th><th className="num">Contacted</th><th className="num">Reply %</th>
              <th className="num">Positive</th><th className="num">Hires</th><th className="num">Deliver</th><th>Health</th>
            </tr></thead>
            <tbody>
              {A.clients.map(function(c,i){
                return (
                  <tr key={i} onClick={function(){goClient(c);}}>
                    <td><div className="docname"><span className="av">{c.init}</span><div><b>{c.name}</b><span>{c.region} · {c.campaign}</span></div></div></td>
                    <td className="num" style={{fontWeight:600,color:'var(--ink)'}}>{c.contacted}</td>
                    <td className="num">{c.replyRate}%</td>
                    <td className="num" style={{fontWeight:600,color:'var(--pos)'}}>{c.positive}</td>
                    <td className="num">{c.hires}</td>
                    <td className="num">{c.deliver}%</td>
                    <td><div className="health"><span className={"dotstat "+c.status} />{c.health}</div></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </PCard>
    </div>
  );
}

function AdminDeliverability(){
  return (
    <div className="stack-gap">
      <div className="grid-2">
        <PCard title="Deliverability by client" sub="Inbox placement across all domains">
          <div style={{display:'flex',flexDirection:'column',gap:16}}>
            {A.clients.map(function(c,i){
              return (
                <div key={i}>
                  <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:7}}>
                    <span style={{display:'flex',alignItems:'center',gap:9,fontSize:'var(--fs-sm)',fontWeight:500}}><span className={"dotstat "+c.status} />{c.name}</span>
                    <b style={{fontVariantNumeric:'tabular-nums'}}>{c.deliver}%</b>
                  </div>
                  <Meter pct={c.deliver} kind={c.status==='bad'?'warn':c.status==='warn'?'warn':'pos'} />
                </div>
              );
            })}
          </div>
        </PCard>
        <PCard title="Domains needing attention" sub="Auto-flagged across the portfolio">
          <div style={{display:'flex',flexDirection:'column',gap:13}}>
            {A.domainsAttention.map(function(d,i){
              return (
                <div key={i} style={{display:'flex',gap:13,alignItems:'flex-start',padding:'13px',border:'1px solid var(--line-soft)',borderRadius:'var(--r-sm)',background:'var(--bg-soft)'}}>
                  <span className={"dotstat "+d.status} style={{marginTop:6}} />
                  <div style={{flex:1}}>
                    <div style={{display:'flex',justifyContent:'space-between',gap:10}}><b style={{fontFamily:'var(--f-mono)',fontSize:'13px',color:'var(--ink)'}}>{d.dom}</b>{statusTag(d.status, d.status==='bad'?'Bounce spike':'Warming')}</div>
                    <div className="muted xs" style={{marginTop:3}}>{d.client} · {d.note}</div>
                    <div style={{display:'flex',gap:18,marginTop:9,fontSize:'12px'}}>
                      <span className="muted">Deliver <b style={{color:'var(--ink)'}}>{d.deliver}%</b></span>
                      <span className="muted">Bounce <b style={{color:'var(--bad)'}}>{d.bounce}%</b></span>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </PCard>
      </div>
      <PCard title="All sending domains" sub={A.totals.domains+" dedicated domains across "+A.totals.clients+" clients"}>
        <div style={{display:'flex',alignItems:'center',gap:24,flexWrap:'wrap'}}>
          <Donut size={150} center={{value:A.totals.avgDeliver+"%",label:"avg deliver"}} segments={[
            {value:16,color:"#1F8A5B"},{value:3,color:"#C77B12"},{value:2,color:"#D81F23"}
          ]} />
          <div style={{flex:1,minWidth:200,display:'flex',flexDirection:'column',gap:14}}>
            <div style={{display:'flex',alignItems:'center',gap:10}}><i style={{width:11,height:11,borderRadius:3,background:'#1F8A5B'}} /><span style={{flex:1,fontSize:'var(--fs-sm)'}}>Healthy</span><b>16 domains</b></div>
            <div style={{display:'flex',alignItems:'center',gap:10}}><i style={{width:11,height:11,borderRadius:3,background:'#C77B12'}} /><span style={{flex:1,fontSize:'var(--fs-sm)'}}>Warming / watch</span><b>3 domains</b></div>
            <div style={{display:'flex',alignItems:'center',gap:10}}><i style={{width:11,height:11,borderRadius:3,background:'#D81F23'}} /><span style={{flex:1,fontSize:'var(--fs-sm)'}}>Action needed</span><b>2 domains</b></div>
          </div>
        </div>
      </PCard>
    </div>
  );
}

function AdminSLA(){
  return (
    <PCard title="Client response-time SLA" sub="Positive replies must be actioned same-day (24h ceiling). Reply speed is the #1 conversion lever" pad={false}>
      <div className="tbl-wrap">
        <table className="tbl">
          <thead><tr><th>Client</th><th>Avg response</th><th className="num">Within 24h</th><th className="num">Breaches</th><th>Status</th></tr></thead>
          <tbody>
            {A.sla.map(function(s,i){
              return (
                <tr key={i}>
                  <td style={{fontWeight:600,color:'var(--ink)'}}>{s.client}</td>
                  <td style={{fontWeight:600,color:s.status==='bad'?'var(--bad)':'var(--ink-2)'}}>{s.avg}</td>
                  <td className="num"><div style={{display:'flex',alignItems:'center',gap:10,justifyContent:'flex-end'}}><div style={{width:90}}><Meter pct={s.within24} kind={s.status==='bad'?'warn':'pos'} /></div><b style={{minWidth:38,textAlign:'right'}}>{s.within24}%</b></div></td>
                  <td className="num" style={{fontWeight:600,color:s.breached>3?'var(--bad)':'var(--ink-2)'}}>{s.breached}</td>
                  <td>{statusTag(s.status, s.status==='pos'?'On track':s.status==='warn'?'Watch':'At risk')}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </PCard>
  );
}

function AdminClients({goClient}){
  return (
    <div className="grid-3">
      {A.clients.map(function(c,i){
        return (
          <div className="pcard" key={i} style={{cursor:'pointer'}} onClick={function(){goClient(c);}}>
            <div className="pcard__body">
              <div style={{display:'flex',alignItems:'center',gap:12,marginBottom:16}}>
                <span className="av" style={{width:44,height:44,borderRadius:12,background:'var(--bg-soft-2)',border:'1px solid var(--line)',display:'flex',alignItems:'center',justifyContent:'center',fontWeight:700,fontSize:14,color:'var(--ink-2)'}}>{c.init}</span>
                <div style={{flex:1,minWidth:0}}><b style={{fontWeight:600,color:'var(--ink)',display:'block'}}>{c.name}</b><span className="muted xs">{c.region}</span></div>
                <span className={"dotstat "+c.status} />
              </div>
              <div className="muted xs" style={{marginBottom:14}}>{c.campaign}</div>
              <div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:10}}>
                <div><div style={{fontSize:'1.3rem',fontWeight:700,letterSpacing:'-0.03em',color:'var(--ink)'}}>{c.contacted}</div><div className="muted" style={{fontSize:'10.5px',textTransform:'uppercase',letterSpacing:'0.04em'}}>Contacted</div></div>
                <div><div style={{fontSize:'1.3rem',fontWeight:700,letterSpacing:'-0.03em',color:'var(--pos)'}}>{c.positive}</div><div className="muted" style={{fontSize:'10.5px',textTransform:'uppercase',letterSpacing:'0.04em'}}>Positive</div></div>
                <div><div style={{fontSize:'1.3rem',fontWeight:700,letterSpacing:'-0.03em',color:'var(--ink)'}}>{c.hires}</div><div className="muted" style={{fontSize:'10.5px',textTransform:'uppercase',letterSpacing:'0.04em'}}>Hires</div></div>
              </div>
              <div className="hr" style={{margin:'16px 0 13px'}} />
              <div style={{display:'flex',alignItems:'center',justifyContent:'space-between'}}>
                <span style={{fontSize:'12px',color:'var(--muted)'}}>Deliver <b style={{color:'var(--ink)'}}>{c.deliver}%</b> · {c.domains} domains</span>
                <span style={{fontSize:'12px',color:'var(--muted)'}}>{c.lastReply}</span>
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ---- derive a full per-client dashboard from summary data ---- */
function deriveProfile(c){
  const replied = Math.round(c.contacted*c.replyRate/100);
  const engaged = Math.round(c.contacted*0.66);
  const posRate = Math.round(c.positive/Math.max(1,replied)*100);
  const interviews = Math.max(c.hires, Math.round(c.positive*0.28));
  const bookings = Math.max(c.hires, Math.round(c.positive*0.2));
  const slaRow = (A.sla.find(s=>s.client===c.name)) || {avg:"-"};
  const base = c.name.toLowerCase().replace(/[^a-z]/g,"").slice(0,12) || c.init.toLowerCase();
  const clamp = v => Math.min(99.4, Math.max(88, +v.toFixed(1)));
  const suff = ["-careers.com","-medical.com","-gp.com","-clinic.com","-recruit.com"];
  const domains = [];
  for(let i=0;i<c.domains;i++){
    const warming = (c.status!=="pos" && i===c.domains-1);
    domains.push({ dom:base+suff[i%suff.length], sent:Math.round(c.contacted/c.domains*(2+i*0.3)),
      deliver: clamp(c.deliver + (i-1)*0.5), status: warming?"watch":(c.status==="bad"&&i===0?"watch":"healthy"),
      warm: warming?"Warming · day "+(6+i*4):"Warm" });
  }
  const funnel = [
    {label:"Doctors contacted", n:c.contacted, pct:100},
    {label:"Opened / engaged", n:engaged, pct:Math.round(engaged/c.contacted*100)},
    {label:"Replied", n:replied, pct:c.replyRate},
    {label:"Positive reply", n:c.positive, pct:Math.round(c.positive/c.contacted*100)},
    {label:"Interview booked", n:interviews, pct:Math.round(interviews/c.contacted*100)},
    {label:"Hired", n:c.hires, pct:+(c.hires/c.contacted*100).toFixed(1)}
  ];
  const feed = [
    {ic:"pos",icon:"reply",title:"Positive reply for "+c.name, body:"Doctor open to a confidential chat · alert sent to clinic", time:c.lastReply},
    {ic:"accent",icon:"alert",title:"Reply alert delivered", body:"Slack + SMS to "+c.name+" · respond same-day", time:c.lastReply},
    {ic:"info",icon:"send",title:"Day 10 emails sent", body:"Final email + one-pager across "+c.domains+" domains", time:"5h"},
    {ic:"neutral",icon:"calendar",title:"Interview booked", body:c.campaign+" · with practice owner", time:"Yesterday"}
  ];
  function mk(id,icon,label,value,raw,kind,opt){ return Object.assign({id:"p-"+c.init+"-"+id,icon,label,value,raw,kind},opt||{}); }
  const metrics = {
    positiveRate: mk("posrate","target","Positive reply rate",posRate,posRate,"rate",{unit:"%",feature:true,delta:+4,deltaUnit:"pts",deltaLabel:"vs last 30 days",color:"#FFFFFF",fmt:v=>v+"%",note:"North-star metric for "+c.name+", share of replies that are positive."}),
    contacted: mk("cont","users","Doctors contacted",c.contacted.toLocaleString(),c.contacted,"cumulative",{delta:+Math.round(c.contacted*0.12),deltaLabel:"vs last 30 days",color:"#FF4A1C"}),
    replyRate: mk("reply","reply","Reply rate",c.replyRate,c.replyRate,"rate",{unit:"%",delta:+2,deltaUnit:"pts",deltaLabel:"vs last 30 days",color:"#2A6FDB",fmt:v=>v+"%"}),
    positive: mk("pos","zap","Positive replies",c.positive,c.positive,"cumulative",{delta:+Math.round(c.positive*0.2),deltaLabel:"vs last 30 days",color:"#1F8A5B"}),
    bookings: mk("book","book","Calls booked",bookings,bookings,"cumulative",{delta:+1,deltaLabel:"this campaign",color:"#2A6FDB"}),
    hires: mk("hire","hire","Hires",c.hires,c.hires,"cumulative",{delta:c.hires>0?+1:0,deltaLabel:"this campaign",color:"#1F8A5B"}),
    response: mk("resp","clock","Avg response time",slaRow.avg,parseFloat(slaRow.avg)||3,(slaRow.avg.indexOf("min")>=0?"time":"time"),{delta:-1,deltaGood:true,deltaLabel:"faster vs last 30 days",color:"#FF4A1C",target:"Same-day",note:"How fast "+c.name+" actions positive replies. Reply speed is the #1 conversion lever."}),
    deliver: mk("deliver","send","Deliverability",c.deliver,c.deliver,"rate",{unit:"%",delta:+0.3,deltaUnit:"pts",deltaLabel:"vs last 30 days",color:"#1F8A5B",fmt:v=>v+"%",breakdownTitle:"By sending domain",breakdown:domains.map(d=>({label:d.dom,value:d.deliver+"%",pct:d.deliver,kind:d.status==="healthy"?"pos":"warn"}))})
  };
  Object.keys(metrics).forEach(function(k){ metrics[k]=trendDelta(metrics[k]); });
  return {replied,interviews,bookings,domains,funnel,feed,metrics};
}

/* ---- client switcher rail ---- */
function ClientSwitcher({active, onPick}){
  return (
    <div style={{display:'flex',gap:8,flexWrap:'wrap',marginBottom:20}}>
      {A.clients.map(function(c){
        const on=c.init===active.init;
        return (
          <button key={c.init} onClick={function(){onPick(c);}}
            style={{display:'inline-flex',alignItems:'center',gap:9,padding:'8px 14px 8px 9px',borderRadius:'var(--r-pill)',cursor:'pointer',fontFamily:'inherit',
              border:'1px solid '+(on?'transparent':'var(--line)'),background:on?'var(--ink-bg)':'var(--bg)',color:on?'#fff':'var(--ink-2)',
              fontSize:'var(--fs-sm)',fontWeight:600,boxShadow:on?'var(--sh-sm)':'var(--sh-xs)',transition:'.15s'}}>
            <span style={{width:24,height:24,borderRadius:7,background:on?'rgba(255,255,255,0.16)':'var(--bg-soft-2)',color:on?'#fff':'var(--ink-2)',display:'flex',alignItems:'center',justifyContent:'center',fontSize:10,fontWeight:700}}>{c.init}</span>
            {c.name}
            <span className={"dotstat "+c.status} />
          </button>
        );
      })}
    </div>
  );
}

/* ---- full per-client dashboard inside admin ---- */
function ClientProfile({client, onPick, onBack, openMetric}){
  const [range,setRange]=React.useState("30d");
  const p=deriveProfile(client);
  const m=p.metrics;
  const ser=window.RYH.genSeries("cp-"+client.init,range,42,"count");
  const pos=window.RYH.genSeries("cp-pos-"+client.init,range,4,"count");
  function K({metric}){
    return (
      <div className={"kpi clickable"+(metric.feature?" feature":"")} onClick={function(){openMetric(metric);}}>
        <div className="kpi__top"><span className="ic"><Icon n={metric.icon} /></span><span className="lab">{metric.label}</span></div>
        <div className="kpi__num">{metric.value}{metric.unit&&<span className="u">{metric.unit}</span>}</div>
        <div className="kpi__sub">
          {metric.delta!=null && <span className={"delta "+((metric.deltaGood?-metric.delta:metric.delta)>=0?"up":"down")}><Icon n={metric.delta>=0?"arrowUp":"arrowDown"} />{metric.delta>=0?"+":""}{metric.delta}{metric.deltaUnit||""}</span>}
          <span>{metric.deltaLabel}</span>
        </div>
      </div>
    );
  }
  return (
    <div className="stack-gap">
      <button className="btn-link" onClick={onBack} style={{alignSelf:'flex-start',whiteSpace:'nowrap'}}>
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{width:16,height:16,transform:'rotate(180deg)'}}><path d="M5 12h14M13 6l6 6-6 6"/></svg>
        Back to all clients
      </button>
      <ClientSwitcher active={client} onPick={onPick} />

      {/* client header */}
      <div className="pcard"><div className="pcard__body" style={{display:'flex',alignItems:'center',gap:16,flexWrap:'wrap'}}>
        <span className="av" style={{width:52,height:52,borderRadius:14,background:'var(--bg-soft-2)',border:'1px solid var(--line)',display:'flex',alignItems:'center',justifyContent:'center',fontWeight:700,fontSize:16,color:'var(--ink-2)',flex:'0 0 auto'}}>{client.init}</span>
        <div style={{flex:1,minWidth:200}}>
          <div style={{display:'flex',alignItems:'center',gap:11,flexWrap:'wrap'}}><b style={{fontSize:'1.25rem',fontWeight:600,letterSpacing:'-0.02em',color:'var(--ink)'}}>{client.name}</b>{statusTag(client.status, client.health)}</div>
          <div className="muted xs" style={{marginTop:3}}>{client.region} · {client.campaign} · {client.domains} sending domains</div>
        </div>
        <a className="btn btn--primary btn--sm" href="client.html">Open client workspace <Icon n="arrowRt" /></a>
      </div></div>

      {/* KPIs */}
      <div className="kpis">
        <K metric={m.positiveRate} /><K metric={m.contacted} /><K metric={m.replyRate} /><K metric={m.positive} />
      </div>
      <div className="kpis">
        <K metric={m.bookings} /><K metric={m.hires} /><K metric={m.response} /><K metric={m.deliver} />
      </div>

      {/* chart + funnel */}
      <div className="grid-32">
        <PCard title="Sends & positive replies" sub={client.name+" · campaign performance"}
          action={<Seg options={[{value:"7d",label:"7D"},{value:"30d",label:"30D"},{value:"3m",label:"3M"},{value:"12m",label:"12M"}]} value={range} onChange={setRange} />}>
          <AreaLine labels={ser.labels} height={220} series={[{data:ser.data,color:"#FF4A1C", name:"Sends"},{data:pos.data,color:"#1F8A5B", name:"Positive replies"}]} />
          <div className="legend" style={{marginTop:14}}><span><i style={{background:'#FF4A1C'}} />Sends</span><span><i style={{background:'#1F8A5B'}} />Positive replies</span></div>
        </PCard>
        <PCard title="Conversion funnel" sub="Contact → hire"><Funnel steps={p.funnel} /></PCard>
      </div>

      {/* deliverability + activity */}
      <div className="grid-23">
        <PCard title="Deliverability" sub="Inbox placement" action={<button className="btn btn--ghost btn--sm" onClick={function(){openMetric(m.deliver);}}>Details</button>}>
          <div style={{display:'flex',alignItems:'center',gap:22,flexWrap:'wrap'}}>
            <Donut size={140} center={{value:client.deliver+"%",label:"delivered"}} segments={[{value:client.deliver,color:client.status==='bad'?'#C77B12':'#1F8A5B'},{value:100-client.deliver,color:'#F1EDE6'}]} />
            <div style={{flex:1,minWidth:160,display:'flex',flexDirection:'column',gap:11}}>
              {p.domains.map(function(d,i){
                return <div key={i}><div style={{display:'flex',justifyContent:'space-between',fontSize:'12.5px',marginBottom:5}}><span style={{fontFamily:'var(--f-mono)',color:'var(--ink-2)'}}>{d.dom}</span><b style={{fontVariantNumeric:'tabular-nums'}}>{d.deliver}%</b></div><Meter pct={d.deliver} kind={d.status==='healthy'?'pos':'warn'} /></div>;
              })}
            </div>
          </div>
        </PCard>
        <PCard title="Recent activity" sub={client.name}><Feed items={p.feed} /></PCard>
      </div>
    </div>
  );
}

/* ---- admin: provision & manage client logins ---- */
function accountStatusTag(s){
  if(s==="Active") return <Tag kind="pos" dot>Active</Tag>;
  if(s==="Pending invite") return <Tag kind="warn" dot>Pending invite</Tag>;
  if(s==="Provisioning") return <Tag kind="info" dot>Provisioning</Tag>;
  return <Tag kind="neutral" dot>{s}</Tag>;
}
function AdminAccounts(){
  const [accounts,setAccounts]=React.useState(A.accounts);
  const [open,setOpen]=React.useState(false);
  const blank={clinic:"",contact:"",email:"",region:"",campaign:"",plan:"Headhunting System",domains:3,invite:true};
  const [form,setForm]=React.useState(blank);
  function set(k,v){ setForm(Object.assign({},form,{[k]:v})); }
  function submit(e){
    e.preventDefault();
    const acct={ clinic:form.clinic||"New clinic", contact:form.contact||"-", email:form.email||"-",
      region:form.region||"-", status: form.invite?"Pending invite":"Provisioning",
      created:"Today", lastLogin:"-" };
    setAccounts([acct].concat(accounts));
    setForm(blank); setOpen(false);
    window.ryToast(form.invite?("Account created · invite emailed to "+(acct.email)):"Account created · provisioning workspace");
  }
  const inputStyle={width:'100%',border:'1px solid var(--line-strong)',borderRadius:'var(--r-sm)',padding:'11px 14px',fontFamily:'inherit',fontSize:'var(--fs-sm)',color:'var(--ink)',outline:'none',background:'var(--bg)'};
  const labStyle={display:'block',fontSize:'12px',fontWeight:600,color:'var(--ink-2)',marginBottom:6};
  return (
    <div className="stack-gap">
      {/* automation explainer */}
      <div className="pcard"><div className="pcard__body" style={{display:'flex',gap:16,alignItems:'flex-start',flexWrap:'wrap'}}>
        <span style={{width:42,height:42,borderRadius:11,background:'var(--accent-wash)',color:'var(--accent-2)',display:'flex',alignItems:'center',justifyContent:'center',fontSize:19,flex:'0 0 auto'}}><Icon n="zap" /></span>
        <div style={{flex:1,minWidth:240}}>
          <b style={{fontWeight:600,color:'var(--ink)'}}>Logins are created automatically on onboarding</b>
          <p style={{fontSize:'var(--fs-sm)',color:'var(--muted)',marginTop:3,maxWidth:'70ch'}}>When a contract is signed and the first payment clears, the onboarding automation provisions the clinic's workspace and emails them a secure login. Use the manual form below only to create or re-issue an account by hand.</p>
        </div>
        <button className="btn btn--primary btn--sm" onClick={function(){setOpen(!open);}}><Icon n="userPlus" /> {open?"Close":"Create account"}</button>
      </div></div>

      {/* manual create form */}
      {open && (
        <PCard title="Create a client account" sub="Provisions a workspace + sends a login invite">
          <form onSubmit={submit}>
            <div className="grid-2" style={{gap:16}}>
              <div><label style={labStyle}>Clinic / practice name</label><input style={inputStyle} value={form.clinic} onChange={function(e){set('clinic',e.target.value);}} placeholder="e.g. Brunswick Family Practice" /></div>
              <div><label style={labStyle}>Primary contact</label><input style={inputStyle} value={form.contact} onChange={function(e){set('contact',e.target.value);}} placeholder="Dr Jane Smith" /></div>
              <div><label style={labStyle}>Login email</label><input style={inputStyle} type="email" value={form.email} onChange={function(e){set('email',e.target.value);}} placeholder="jane@clinic.com.au" /></div>
              <div><label style={labStyle}>Region</label><input style={inputStyle} value={form.region} onChange={function(e){set('region',e.target.value);}} placeholder="Brunswick VIC" /></div>
              <div><label style={labStyle}>Campaign focus</label><input style={inputStyle} value={form.campaign} onChange={function(e){set('campaign',e.target.value);}} placeholder="GP · Inner North" /></div>
              <div><label style={labStyle}>Sending domains</label><input style={inputStyle} type="number" min="2" max="6" value={form.domains} onChange={function(e){set('domains',e.target.value);}} /></div>
            </div>
            <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',gap:16,marginTop:18,flexWrap:'wrap'}}>
              <label style={{display:'flex',alignItems:'center',gap:9,fontSize:'var(--fs-sm)',color:'var(--ink-2)',fontWeight:500}}>
                <input type="checkbox" checked={form.invite} onChange={function(e){set('invite',e.target.checked);}} style={{width:16,height:16,accentColor:'var(--accent)'}} />
                Email a login invite now
              </label>
              <div style={{display:'flex',gap:10}}>
                <button type="button" className="btn btn--ghost btn--sm" onClick={function(){setForm(blank);setOpen(false);}}>Cancel</button>
                <button type="submit" className="btn btn--primary btn--sm">Create account <Icon n="arrowRt" /></button>
              </div>
            </div>
          </form>
        </PCard>
      )}

      {/* existing accounts */}
      <PCard title="Provisioned accounts" sub={accounts.length+" client logins"} pad={false}
        action={<button className="btn btn--ghost btn--sm" onClick={function(){window.ryToast("Exported "+accounts.length+" accounts to CSV");}}><Icon n="download" /> Export</button>}>
        <div className="tbl-wrap">
          <table className="tbl">
            <thead><tr><th>Clinic</th><th>Primary contact</th><th>Login email</th><th>Created</th><th>Last login</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {accounts.map(function(a,i){
                return (
                  <tr key={i}>
                    <td><div className="docname"><span className="av">{a.clinic.split(/\s+/).map(w=>w[0]).join("").slice(0,2).toUpperCase()}</span><div><b>{a.clinic}</b><span>{a.region}</span></div></div></td>
                    <td>{a.contact}</td>
                    <td className="muted" style={{fontFamily:'var(--f-mono)',fontSize:'12.5px'}}>{a.email}</td>
                    <td className="muted">{a.created}</td>
                    <td className="muted">{a.lastLogin}</td>
                    <td>{accountStatusTag(a.status)}</td>
                    <td style={{textAlign:'right'}}>
                      <span style={{display:'inline-flex',gap:8}}>
                        {a.status!=="Active" && <button className="btn btn--ghost btn--sm" style={{padding:'6px 12px'}} onClick={function(){window.ryToast("Invite re-sent to "+a.email);}}>Resend invite</button>}
                        <button className="iconbtn" style={{width:34,height:34}} aria-label="More" onClick={function(){window.ryToast("Account actions for "+a.clinic);}}><Icon n="dots" /></button>
                      </span>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </PCard>
    </div>
  );
}

function AdminIntegrations(){
  const src = (window.RYH && window.RYH.client && window.RYH.client.integrations)
    || (window.REYAH_MOCK && window.REYAH_MOCK.client && window.REYAH_MOCK.client.integrations) || [];
  const [list,setList]=React.useState(src);
  const [modal,setModal]=React.useState(null);
  function connect(it){ setList(list.map(x=>x.id===it.id?Object.assign({},x,{status:"connected"}):x)); setModal(null); }
  function disconnect(it){ setList(list.map(x=>x.id===it.id?Object.assign({},x,{status:"disconnected"}):x)); }
  return (
    <div className="stack-gap">
      <div className="pcard"><div className="pcard__body" style={{display:'flex',gap:16,alignItems:'flex-start',flexWrap:'wrap'}}>
        <span style={{width:42,height:42,borderRadius:11,background:'var(--accent-wash)',color:'var(--accent-2)',display:'flex',alignItems:'center',justifyContent:'center',fontSize:19,flex:'0 0 auto'}}><Icon n="globe" /></span>
        <div style={{flex:1,minWidth:240}}>
          <b style={{fontWeight:600,color:'var(--ink)'}}>Provider connections</b>
          <p style={{fontSize:'var(--fs-sm)',color:'var(--muted)',marginTop:3,maxWidth:'72ch'}}>The GoHighLevel and PlusVibe accounts Reyah operates across every client. Each client also gets their own scoped credentials at onboarding and connects their own Google Calendar.</p>
        </div>
      </div></div>
      <div className="intg-grid">
        {list.map(function(it){ return <IntegrationCard key={it.id} it={it} data={(window.RYH&&window.RYH.client)||(window.REYAH_MOCK&&window.REYAH_MOCK.client)} onConnect={setModal} onDisconnect={disconnect} />; })}
      </div>
      {modal && <ConnectModal it={modal} onClose={function(){setModal(null);}} onConfirm={connect} />}
    </div>
  );
}

function AdminSettings(){
  const [tab,setTab]=React.useState("Workspace");
  const tabs=["Workspace","Alerts","Integrations","Team","API"];
  const [s,setS]=React.useState({
    org:"Reyah", region:"AU & NZ", defaultDomains:4,
    slaHours:24, bounceAlert:3, deliverFloor:96, aEmail:true, aSlack:true, aSms:true,
    twofa:true
  });
  function up(k,v){ setS(Object.assign({},s,{[k]:v})); }
  const team=[{n:"Jamie King",r:"Founder · Owner",i:"JK"},{n:"Ops team",r:"Campaign managers · 3 seats",i:"OP"}];
  return (
    <div className="stack-gap" style={{maxWidth:960, margin:'0 auto', width:'100%'}}>
      <div className="settabs">{tabs.map(function(x){ return <button key={x} className={tab===x?"active":""} onClick={function(){setTab(x);}}>{x}</button>; })}</div>
      {tab==="Integrations" ? <AdminIntegrations /> : <PCard>
        {tab==="Workspace" && <div>
          <SRow title="Organisation name"><input className="setinput" value={s.org} onChange={function(e){up('org',e.target.value);}} /></SRow>
          <SRow title="Markets served"><RSelect value={s.region} options={["AU & NZ","AU only","AU, NZ & US"]} onChange={function(v){up('region',v);}} /></SRow>
          <SRow title="Default sending domains per client" desc="Provisioned automatically at onboarding."><input className="setinput" type="number" min="2" max="6" value={s.defaultDomains} onChange={function(e){up('defaultDomains',e.target.value);}} /></SRow>
        </div>}
        {tab==="Alerts" && <div>
          <SRow title="Client response-time SLA" desc="Flag clients who take longer than this to action a positive reply."><span style={{display:'flex',alignItems:'center',gap:8}}><input className="setinput" style={{minWidth:80}} type="number" value={s.slaHours} onChange={function(e){up('slaHours',e.target.value);}} /><span className="muted sm">hours</span></span></SRow>
          <SRow title="Bounce-rate alert" desc="Auto-suppress + alert when a domain exceeds this bounce rate."><span style={{display:'flex',alignItems:'center',gap:8}}><input className="setinput" style={{minWidth:80}} type="number" value={s.bounceAlert} onChange={function(e){up('bounceAlert',e.target.value);}} /><span className="muted sm">%</span></span></SRow>
          <SRow title="Deliverability floor" desc="Review + rotate domains when placement drops below this."><span style={{display:'flex',alignItems:'center',gap:8}}><input className="setinput" style={{minWidth:80}} type="number" value={s.deliverFloor} onChange={function(e){up('deliverFloor',e.target.value);}} /><span className="muted sm">%</span></span></SRow>
          <SRow title="Alert channels" desc="Where internal ops alerts are sent."><span style={{display:'flex',gap:14,alignItems:'center'}}><label style={{display:'flex',gap:6,alignItems:'center',fontSize:13}}><Toggle on={s.aSlack} onChange={function(v){up('aSlack',v);}} />Slack</label></span></SRow>
        </div>}
        {tab==="Team" && <div>
          {team.map(function(m,i){ return <SRow key={i} title={m.n} desc={m.r}><span className="av" style={{width:34,height:34,borderRadius:'50%',background:'var(--bg-soft-2)',border:'1px solid var(--line)',display:'inline-flex',alignItems:'center',justifyContent:'center',fontSize:12,fontWeight:700,color:'var(--ink-2)'}}>{m.i}</span></SRow>; })}
          <div style={{paddingTop:14}}><button className="btn btn--ghost btn--sm" onClick={function(){window.ryToast("Teammate invite sent");}}><Icon n="userPlus" /> Invite teammate</button></div>
        </div>}
        {tab==="API" && <div>
          <SRow title="Backend / proxy base" desc="The browser only talks to your backend, never GHL/PlusVibe directly."><input className="setinput" defaultValue={(window.REYAH_CONFIG&&window.REYAH_CONFIG.apiBase)||"/api"} /></SRow>
          <SRow title="Webhook endpoint" desc="GHL + PlusVibe push events here (positive replies, bookings, bounces)."><input className="setinput" defaultValue="/api/webhooks" /></SRow>
          <SRow title="API key" desc="Server-side only. Rotate if exposed."><button className="btn btn--ghost btn--sm" onClick={function(){window.ryToast("New API key generated");}}>Regenerate key</button></SRow>
          <SRow title="Compliance & privacy" desc="Public policy pages on the website."><span style={{display:'flex',gap:8}}><a className="btn btn--ghost btn--sm" href={SITE+"/compliance/index.html"} target="_blank" rel="noopener">Compliance</a><a className="btn btn--ghost btn--sm" href={SITE+"/privacy/index.html"} target="_blank" rel="noopener">Privacy</a></span></SRow>
        </div>}
      </PCard>}
      {tab!=="Integrations" && <div style={{display:'flex',justifyContent:'flex-end',gap:10}}>
        <button className="btn btn--ghost btn--sm" onClick={function(){window.ryToast("Changes discarded");}}>Cancel</button>
        <button className="btn btn--primary btn--sm" onClick={function(){window.ryToast("Settings saved");}}>Save changes</button>
      </div>}
    </div>
  );
}

function AdminApp(){
  const [screen,setScreen]=React.useState("overview");
  const [metric,setMetric]=React.useState(null);
  const [profile,setProfile]=React.useState(null);
  const [noti,setNoti]=React.useState(false);
  const [notifs,setNotifs]=React.useState(A.notifications);
  // Browser-history wiring: mirror the active view (section + open client
  // profile) into history so Back walks pages instead of leaving to sign-in.
  const popping = React.useRef(false);
  React.useEffect(function(){
    if(popping.current){ popping.current=false; return; }
    var st={screen:screen, profile:profile};
    if(window.history.state){ window.history.pushState(st,""); } else { window.history.replaceState(st,""); }
  },[screen,profile]);
  React.useEffect(function(){
    function onPop(e){ popping.current=true; var st=e.state||{}; setScreen(st.screen||"overview"); setProfile(st.profile||null); setMetric(null); setNoti(false); }
    window.addEventListener("popstate",onPop);
    return function(){ window.removeEventListener("popstate",onPop); };
  },[]);
  const unread=notifs.filter(function(n){return n.unread;}).length;
  function goClient(c){ setProfile(c); setScreen("profile"); window.scrollTo(0,0); }
  const isProfile = screen==="profile";
  const t = isProfile ? [profile.name, "Client dashboard · "+profile.region] : ATITLES[screen];

  const searchIndex=React.useMemo(function(){
    function ini(s){ return (s||"").split(" ").filter(Boolean).map(function(w){return w[0];}).slice(0,2).join("").toUpperCase(); }
    var idx=[];
    (A.clients||[]).forEach(function(c){
      idx.push({id:"cl-"+c.name, cat:"Clients", av:c.init, label:c.name, sub:[c.region,c.campaign].filter(Boolean).join(" · "),
        tag:c.health, tagKind:c.status, kw:[c.name,c.region,c.campaign,c.health].join(" ").toLowerCase(), onPick:function(){ goClient(c); }});
    });
    (A.accounts||[]).forEach(function(a){
      idx.push({id:"ac-"+a.email, cat:"Accounts", av:ini(a.contact), label:a.contact, sub:[a.clinic,a.email].filter(Boolean).join(" · "),
        tag:a.status, tagKind:a.status==="Active"?"pos":(a.status==="Provisioning"?"bad":"neutral"),
        kw:[a.contact,a.clinic,a.email,a.region,a.status].join(" ").toLowerCase(), onPick:function(){ setScreen("accounts"); }});
    });
    (A.domainsAttention||[]).forEach(function(d){
      idx.push({id:"dm-"+d.dom, cat:"Domains", label:d.dom, sub:[d.client,d.note].filter(Boolean).join(" · "),
        tag:d.status==="bad"?"At risk":"Warming", tagKind:d.status,
        kw:[d.dom,d.client,d.note].join(" ").toLowerCase(), onPick:function(){ setScreen("deliverability"); }});
    });
    return idx;
  },[]);

  function render(){
    switch(screen){
      case "overview": return <AdminOverview openMetric={setMetric} goClient={goClient} />;
      case "deliverability": return <AdminDeliverability />;
      case "sla": return <AdminSLA />;
      case "clients": return <AdminClients goClient={goClient} />;
      case "accounts": return <AdminAccounts />;
      case "settings": return <AdminSettings />;
      case "profile": return <ClientProfile client={profile} onPick={goClient} onBack={function(){setScreen("clients");}} openMetric={setMetric} />;
      default: return null;
    }
  }
  return (
    <div className="shell">
      <Sidebar
        org={{name:"Reyah Ops", sub:"Admin · all clients", init:"R", onClick:function(){ window.ryToast("Reyah admin workspace"); }}}
        items={ANAV} active={isProfile?"clients":screen} onNav={setScreen} user={A.user}
        footerExtra={<a className="navitem" href="client.html" style={{marginBottom:6}}><Icon n="building" /><span>Client view</span></a>} />
      <div className="main">
        <Topbar title={t[0]} sub={t[1]} search="Search clients, accounts, domains…" searchIndex={searchIndex} right={
          <React.Fragment>
            <span className="tag tag--bad" style={{marginRight:4}}><span className="d" />1 domain at risk</span>
            <button className="iconbtn" aria-label="Notifications" onClick={function(){setNoti(!noti);}}><Icon n="bell" />{unread>0 && <span className="dot" />}</button>
          </React.Fragment>
        } />
        <div className="content">{render()}</div>
      </div>
      {metric && <MetricDrawer metric={metric} onClose={function(){setMetric(null);}} />}
      {noti && <NotificationsPanel items={notifs} onClose={function(){setNoti(false);}} onAllRead={function(){setNotifs(notifs.map(function(n){return Object.assign({},n,{unread:false});}));}} />}
    </div>
  );
}

/* ---- bootstrap: guard session (admin) → load canonical data → render ----
   Mock mode renders instantly off window.REYAH_MOCK with no guard. Live mode
   requires an admin session (client role is redirected to client.html), then
   loads { client, admin }. 501 → "Coming soon"; other failure → error screen. */
(async function bootstrap(){
  const cfg = window.REYAH_CONFIG || { useMock:true };
  const root = ReactDOM.createRoot(document.getElementById("root"));

  if (!cfg.useMock){
    try {
      const me = await window.REYAH_AUTH.requireSession("admin");
      if (!me) return; // a redirect is in flight
    } catch (e) {
      root.render(<BootScreen kind="error" message="We couldn't verify your session. Please try again." onRetry={function(){ window.location.reload(); }} />);
      return;
    }
  }

  try {
    const d = await window.REYAH_DATA.load();
    if (d && d.admin)  { window.RYH.admin  = d.admin;  }
    if (d && d.client) { window.RYH.client = d.client; }
  } catch (e) {
    if (cfg.useMock) {
      console.error("[Reyah] mock load failed:", e);
    } else if (e && e.status === 501) {
      root.render(<BootScreen kind="comingsoon" message="The portfolio dashboard is being provisioned. Check back shortly." />);
      return;
    } else {
      root.render(<BootScreen kind="error" message="We couldn't load the portfolio. Please try again." onRetry={function(){ window.location.reload(); }} />);
      return;
    }
  }

  A = window.RYH.admin;           // re-bind to whatever load() returned
  AMETRICS = buildAMetrics();
  ANAV = buildANav();
  root.render(<AdminApp />);
})();
