import './vendor';
import 'jquery-sparkline';
import { authFetch } from './authWrap';
import { error, log } from './logger';

interface GpuInfo {
  name: string;
  data: Record<string, string | number>;
  chart?: [number, number];
}

let gpuInterval: ReturnType<typeof setInterval> | null = null;
const chartData: { mem: number[]; load: number[] } = { mem: [], load: [] };

async function updateGPUChart(mem: number, load: number): Promise<void> {
  const maxLen = 120;
  const colorRangeMap = $.range_map({
    '0:5': '#fffafa',
    '6:10': '#fff7ed',
    '11:20': '#fed7aa',
    '21:30': '#fdba74',
    '31:40': '#fb923c',
    '41:50': '#f97316',
    '51:60': '#ea580c',
    '61:70': '#c2410c',
    '71:80': '#9a3412',
    '81:90': '#7c2d12',
    '91:100': '#6c2e12',
  });
  const sparklineConfigLOAD = { type: 'bar', height: '128px', barWidth: '3px', barSpacing: '1px', chartRangeMin: 0, chartRangeMax: 100, barColor: '#89007D' };
  const sparklineConfigMEM = { type: 'bar', height: '128px', barWidth: '3px', barSpacing: '1px', chartRangeMin: 0, chartRangeMax: 100, colorMap: colorRangeMap, composite: true };
  if (chartData.load.length > maxLen) chartData.load.shift();
  chartData.load.push(load);
  if (chartData.mem.length > maxLen) chartData.mem.shift();
  chartData.mem.push(mem);
  $('#gpuChart').sparkline(chartData.load, sparklineConfigLOAD);
  $('#gpuChart').sparkline(chartData.mem, sparklineConfigMEM);
}

async function updateGPU(): Promise<void> {
  const gpuEl = document.getElementById('gpu');
  const gpuTable = document.getElementById('gpu-table');
  if (!gpuEl || !gpuTable) return;
  try {
    const res = await authFetch(`${window.api}/gpu-smi`);
    if (!res || !res.ok) {
      clearInterval(gpuInterval);
      gpuEl.style.display = 'none';
      return;
    }
    const data = (await res.json()) as GpuInfo[];
    if (!data) {
      clearInterval(gpuInterval);
      gpuEl.style.display = 'none';
      return;
    }
    const gpuTbody = gpuTable.querySelector('tbody');
    if (!gpuTbody) return;
    let gpu = { data: {} } as GpuInfo;
    if (Array.isArray(data) && data.length >= 1) gpu = data[0];
    let rows = `<tr><td style="color: var(--color-info)">GPU</td><td>${gpu.name || 'unknown'}</td></tr>`;
    for (const item of Object.entries(gpu.data)) rows += `<tr><td style="color: var(--color-info)">${item[0]}</td><td>${item[1]}</td></tr>`;
    gpuTbody.innerHTML = rows;
    if (gpu.chart && gpu.chart.length === 2) updateGPUChart(gpu.chart[0], gpu.chart[1]);
    gpuEl.style.display = 'block';
  } catch (e) {
    error('updateGPU', e);
    clearInterval(gpuInterval);
    gpuEl.style.display = 'none';
  }
}

export async function startGPU(): Promise<void> {
  const gpuEl = document.getElementById('gpu');
  if (!gpuEl) return;
  gpuEl.style.display = 'block';
  if (gpuInterval) clearInterval(gpuInterval);
  const interval = window.opts?.gpu_monitor || 3000;
  log('startGPUmonitor', interval);
  gpuInterval = setInterval(updateGPU, interval);
  updateGPU();
}

window.startGPU = startGPU;

export async function disableGPU(): Promise<void> {
  clearInterval(gpuInterval);
  const gpuEl = document.getElementById('gpu');
  if (gpuEl) gpuEl.style.display = 'none';
}

window.disableGPU = disableGPU;