// screens-resources.jsx
// Live CPU/RAM/GPU gauges for Dashboard. Polls /api/v1/cluster/metrics every 5s.
// Falls back to mock data when endpoint unavailable.

const RESOURCE_MOCK={nodes:[
{hostname:"zampp1",cpu_util_pct:42,ram_used_mb:14336,ram_total_mb:32768,
gpus:[{name:"RTX 3060",util_pct:67,memory_used_mb:5120,memory_total_mb:12288}]},
{hostname:"zampp2",cpu_util_pct:18,ram_used_mb:8192,ram_total_mb:32768,
gpus:[{name:"RTX 3060",util_pct:12,memory_used_mb:1024,memory_total_mb:12288}]},
]};

function useClusterMetrics(){
  const [data,setData]=React.useState(null);
  const [usingMock,setUsingMock]=React.useState(false);
  React.useEffect(()=>{
    let cancelled=false;
    const load=()=>{
      window.ZAMPP_API.fetch('/cluster/metrics')
        .then(d=>{
          if(cancelled)return;
          if(d&&Array.isArray(d.nodes)&&d.nodes.length>0){
            setData(d);setUsingMock(false);
          }else{setData(RESOURCE_MOCK);setUsingMock(true);}
        })
        .catch(()=>{if(!cancelled){setData(RESOURCE_MOCK);setUsingMock(true);}});
    };
    load();
    const t=setInterval(load,5000);
    return ()=>{cancelled=true;clearInterval(t);};
  },[]);
  return {data,usingMock};
}

function ResBar({pct,color}){
  const p=Math.min(100,Math.max(0,Math.round(pct||0)));
  const c=color||(p>85?'var(--warning)':p>60?'var(--accent)':'var(--success)');
  return (
    <div className="res-bar-wrap">
      <div className="res-bar"><div className="res-bar-fill" style={{width:p+'%',background:c}}/></div>
      <span className="res-bar-pct">{p}%</span>
    </div>
  );
}

function NodeResourceCard({node}){
  const ramPct=node.ram_total_mb>0?(node.ram_used_mb/node.ram_total_mb)*100:0;
  const ramUsed=(node.ram_used_mb/1024).toFixed(1);
  const ramTotal=(node.ram_total_mb/1024).toFixed(0);
  return (
    <div className="panel res-node-card">
      <div className="res-node-name"><span className="res-node-dot"/>{node.hostname}</div>
      <div className="res-metric">
        <div className="res-metric-label">CPU</div>
        <ResBar pct={node.cpu_util_pct}/>
      </div>
      <div className="res-metric">
        <div className="res-metric-label">RAM <span className="res-metric-sub">{ramUsed}/{ramTotal} GB</span></div>
        <ResBar pct={ramPct} color={ramPct>85?'var(--warning)':'var(--text-2)'}/>
      </div>
      {(node.gpus||[]).map((gpu,i)=>{
        const vramPct=gpu.memory_total_mb>0?(gpu.memory_used_mb/gpu.memory_total_mb)*100:0;
        const vramUsed=(gpu.memory_used_mb/1024).toFixed(1);
        const vramTotal=(gpu.memory_total_mb/1024).toFixed(0);
        const lbl=(node.gpus||[]).length>1?'GPU '+(i+1):'GPU';
        return (
          <React.Fragment key={i}>
            <div className="res-metric">
              <div className="res-metric-label">{lbl} util</div>
              <ResBar pct={gpu.util_pct}/>
            </div>
            <div className="res-metric">
              <div className="res-metric-label">{lbl} VRAM <span className="res-metric-sub">{vramUsed}/{vramTotal} GB</span></div>
              <ResBar pct={vramPct} color={vramPct>85?'var(--warning)':'var(--purple)'}/>
            </div>
          </React.Fragment>
        );
      })}
    </div>
  );
}

function ClusterResources(){
  const {data,usingMock}=useClusterMetrics();
  if(!data)return <div className="dash-panel-empty">Loading resource metrics...</div>;
  return (
    <div>
      {usingMock&&(
        <div className="res-mock-note">&#9888; Metrics API unavailable - showing mock data</div>
      )}
      <div className="res-nodes-grid">
        {data.nodes.map(n=><NodeResourceCard key={n.hostname} node={n}/>)}
      </div>
    </div>
  );
}

window.ClusterResources=ClusterResources;
