/* ParallelOS Control Plane — Compute (consumer) views */
const { useState:cS, useMemo:cM, useRef:cR, useEffect:cE } = React;

const ST = {
  provisioning:['s-warn','Provisioning'], running:['s-run','Running'],
  completed:['s-ok','Completed'], failed:['s-err','Failed'], queued:['s-warn','Queued']
};
function Pill({s}){const[c,l]=ST[s]||['s-off',s];return <span className={'s '+c}><span className="d"></span>{l}</span>;}

function manifestYaml(d){
  const env=(d.env||[]).map(e=>`    ${e.k}: ${JSON.stringify(e.v)}`).join('\n');
  return (
`<span class="c"># parallelos deployment manifest</span>
<span class="k">apiVersion</span>: parallelos/v1
<span class="k">kind</span>: Deployment
<span class="k">name</span>: <span class="s">${d.name}</span>
<span class="k">image</span>: <span class="s">${d.image}</span>
<span class="k">command</span>: <span class="s">${JSON.stringify(d.cmd)}</span>
<span class="k">resources</span>:
    <span class="k">gpu</span>: <span class="s">${d.gpu}</span>
    <span class="k">count</span>: <span class="n">${d.gpuCount}</span>
    <span class="k">region</span>: <span class="s">${d.region}</span>
<span class="k">limits</span>:
    <span class="k">maxRuntime</span>: <span class="s">${d.maxH}h</span>
    <span class="k">maxBudget</span>: <span class="n">${d.budget}</span> <span class="c"># PLOS</span>
<span class="k">inputs</span>: <span class="s">${d.inputs||'none'}</span>${env?`\n<span class="k">env</span>:\n${env}`:''}
<span class="k">outputs</span>: <span class="s">ipfs://&lt;assigned-on-completion&gt;</span>`);
}

/* ============ OVERVIEW ============ */
function Overview({go,openDep}){
  const { state } = useApp();
  const running=state.deployments.filter(d=>d.status==='running'||d.status==='provisioning').length;
  const onlineDev=state.devices.filter(d=>d.status!=='offline').length;
  const earned=state.devices.reduce((a,d)=>a+d.earned,0);
  const spent=state.deployments.reduce((a,d)=>a+(d.cost||0),0);
  return (
    <div className="view">
      <div className="grid g4">
        <div className="metric"><div className="ml"><Icon n="wallet"/>Wallet balance</div><div className="mv">{state.balance.toLocaleString('en-US',{maximumFractionDigits:0})}<span className="u">PLOS</span></div><div className="mt">≈ ${(state.balance*0.42).toLocaleString('en-US',{maximumFractionDigits:0})} USD</div></div>
        <div className="metric"><div className="ml"><Icon n="layers"/>Active deployments</div><div className="mv">{running}</div><div className="mt up">{state.deployments.length} total</div></div>
        <div className="metric"><div className="ml"><Icon n="server"/>Provider devices</div><div className="mv">{onlineDev}<span className="u">/ {state.devices.length}</span></div><div className="mt up">online</div></div>
        <div className="metric"><div className="ml"><Icon n="coins"/>Unclaimed earnings</div><div className="mv">{earned.toLocaleString('en-US',{maximumFractionDigits:0})}<span className="u">PLOS</span></div><div className="mt up">▲ accruing</div></div>
      </div>

      <div className="cols" style={{marginTop:16}}>
        <div className="panel">
          <div className="panel-h"><h3>Recent deployments</h3><button className="b b-ghost b-sm" onClick={()=>go('deployments')}>View all</button></div>
          <div style={{padding:0}}>
            {state.deployments.length===0
              ? <div className="empty"><Icon n="layers"/><div>No deployments yet</div><button className="b b-pri b-sm" style={{marginTop:14}} onClick={()=>go('new')}>New deployment</button></div>
              : <table className="tbl"><thead><tr><th>Name</th><th>GPU</th><th>Status</th><th style={{textAlign:'right'}}>Cost</th></tr></thead>
                <tbody>{state.deployments.slice().reverse().slice(0,5).map(d=>(
                  <tr key={d.id} onClick={()=>openDep(d.id)}>
                    <td><div className="nm">{d.name}</div><div className="id">{d.id}</div></td>
                    <td className="mc">{d.gpu} ×{d.gpuCount}</td>
                    <td><Pill s={d.status}/></td>
                    <td className="mc" style={{textAlign:'right'}}>{(d.cost||0).toFixed(2)}</td>
                  </tr>))}</tbody></table>}
          </div>
        </div>
        <div className="panel">
          <div className="panel-h"><h3>Activity</h3><span className="sub">live</span></div>
          <div className="panel-b">
            <div className="activity">
              {state.activity.slice(0,7).map((a,i)=>(
                <div className="act" key={i}><span className="ai" style={{color:a.k==='ok'?'var(--ok)':'var(--accent)'}}><Icon n={a.ic}/></span>
                  <span className="at" dangerouslySetInnerHTML={{__html:a.t}}></span><span className="aw">{ago(a.ts)}</span></div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============ DEPLOYMENTS LIST ============ */
function Deployments({go,openDep}){
  const { state } = useApp();
  return (
    <div className="view">
      <div className="panel">
        <div className="panel-h"><h3>Deployments</h3><button className="b b-pri b-sm" onClick={()=>go('new')}><Icon n="plus"/>New deployment</button></div>
        {state.deployments.length===0
          ? <div className="empty"><Icon n="layers"/><div>No deployments yet</div></div>
          : <table className="tbl"><thead><tr><th>Name</th><th>Image</th><th>Resources</th><th>Node</th><th>Status</th><th>Progress</th><th style={{textAlign:'right'}}>Cost</th></tr></thead>
            <tbody>{state.deployments.slice().reverse().map(d=>(
              <tr key={d.id} onClick={()=>openDep(d.id)}>
                <td><div className="nm">{d.name}</div><div className="id">{d.id} · {ago(d.createdAt)}</div></td>
                <td className="mc" style={{maxWidth:180,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{d.image.split('/').pop()}</td>
                <td className="mc">{d.gpu} ×{d.gpuCount}</td>
                <td className="id">{d.node?d.node.split(' · ')[0]:'—'}</td>
                <td><Pill s={d.status}/></td>
                <td><div className="meter" style={{minWidth:120}}><div className="pbar" style={{flex:1}}><i className={d.status==='completed'?'':''} style={{width:(d.progress*100)+'%',background:d.status==='completed'?'var(--ok)':'var(--accent)'}}></i></div><span className="mc" style={{fontSize:11,minWidth:34}}>{Math.round(d.progress*100)}%</span></div></td>
                <td className="mc" style={{textAlign:'right'}}>{(d.cost||0).toFixed(2)}</td>
              </tr>))}</tbody></table>}
      </div>
    </div>
  );
}

/* ============ DEPLOYMENT DETAIL ============ */
function DeploymentDetail({id,go}){
  const { state, update } = useApp();
  const toast=useToast();
  const d=state.deployments.find(x=>x.id===id);
  const [tab,setTab]=cS('overview');
  const logRef=cR(null);
  cE(()=>{ if(logRef.current) logRef.current.scrollTop=logRef.current.scrollHeight; },[d&&d.logs&&d.logs.length,tab]);
  if(!d) return <div className="view"><div className="empty"><Icon n="layers"/>Deployment not found</div></div>;
  const live=d.status==='running'||d.status==='provisioning';
  const tabs=[['overview','Overview'],['spec','Manifest'],['logs','Logs'],['results','Results']];
  return (
    <div className="view">
      <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',gap:14,marginBottom:18,flexWrap:'wrap'}}>
        <div style={{display:'flex',alignItems:'center',gap:14}}>
          <h2 style={{fontFamily:'var(--f-display)',fontSize:22}}>{d.name}</h2><Pill s={d.status}/>
        </div>
        <div style={{display:'flex',gap:10}}>
          {d.status==='completed' && <button className="b b-sec b-sm" onClick={()=>toast({kind:'ok',msg:'Results download started',sub:d.results[0].n})}><Icon n="download"/>Download all</button>}
          <button className="b b-sec b-sm" onClick={()=>{go('new',{prefill:{clone:d}});}}>Re-deploy</button>
        </div>
      </div>

      <div className="panel">
        <div className="tabs">{tabs.map(([k,l])=><button key={k} className={'tab'+(tab===k?' on':'')} onClick={()=>setTab(k)}>{l}{k==='results'&&d.results?` (${d.results.length})`:''}</button>)}</div>

        {tab==='overview' && <div className="panel-b">
          <div className="kv">
            <div className="k">Deployment ID</div><div className="v">{d.id}</div>
            <div className="k">Image</div><div className="v">{d.image}</div>
            <div className="k">Command</div><div className="v">{d.cmd}</div>
            <div className="k">Resources</div><div className="v">{d.gpu} ×{d.gpuCount} · {d.region}</div>
            <div className="k">Assigned node</div><div className="v">{d.node||'pending scheduling…'}</div>
            <div className="k">Runtime</div><div className="v">{d.status==='completed'?dur(d.maxH*3600*0.6):live?'running…':'—'}</div>
            <div className="k">Cost</div><div className="v">{(d.cost||0).toFixed(2)} PLOS · budget {d.budget}</div>
            {d.status==='completed' && <><div className="k">Exit code</div><div className="v" style={{color:d.exitCode===0?'var(--ok)':'var(--err)'}}>{d.exitCode}</div></>}
          </div>
        </div>}

        {tab==='spec' && <div className="panel-b"><div className="codewrap"><div className="codeblk" dangerouslySetInnerHTML={{__html:manifestYaml(d)}}></div></div>
          <p style={{fontSize:12.5,color:'var(--app-faint)',marginTop:12}}>This manifest is the job payload sent to the network. The Core System validates it, schedules a matching node and streams the result back.</p></div>}

        {tab==='logs' && <div className="panel-b"><div className="term" ref={logRef}>
          {(d.logs||[]).map((l,i)=>(<div className="ln" key={i}><span className="tt">{l.t}</span><span className={'lv '+l.lv}>{l.lv.toUpperCase()}</span><span className="msg">{l.msg}</span></div>))}
          {live && <div className="ln"><span className="tt">{new Date().toTimeString().slice(0,8)}</span><span className="lv info">····</span><span className="msg"><span className="cur"></span></span></div>}
        </div></div>}

        {tab==='results' && <div className="panel-b">
          {d.status!=='completed'
            ? <div className="empty"><Icon n="download"/><div>Results will appear here when the deployment completes</div></div>
            : <>
              <div style={{display:'grid',gridTemplateColumns:'repeat(3,1fr)',gap:12,marginBottom:18}}>
                <div className="metric"><div className="ml">Exit code</div><div className="mv" style={{color:'var(--ok)',fontSize:20}}>{d.exitCode} · OK</div></div>
                <div className="metric"><div className="ml">GPU util (avg)</div><div className="mv" style={{fontSize:20}}>{d.metrics.gpu}%</div></div>
                <div className="metric"><div className="ml">Throughput</div><div className="mv" style={{fontSize:20}}>{d.metrics.thr}</div></div>
              </div>
              <div className="sectitle" style={{margin:'0 0 10px'}}>Output artifacts</div>
              {d.results.map((f,i)=>(<div className="file" key={i}><span className="fic"><Icon n="doc"/></span><div className="fm"><div className="fn">{f.n}</div><div className="fs">{f.s}</div></div><button className="b b-sec b-sm" onClick={()=>toast({kind:'ok',msg:'Download started',sub:f.n})}><Icon n="download"/></button></div>))}
            </>}
        </div>}
      </div>
    </div>
  );
}

Object.assign(window,{Overview,Deployments,DeploymentDetail,Pill,manifestYaml});
