export interface SystemInfo {
  os_version: string;
  physical_memory: string;
  processor: string;
  devices: Devices;
  recipes?: Recipes;
  // Recipes with nothing runnable on this host: every built-in model was
  // dropped by the system-memory heuristic. `recipes` stays canonical, so
  // listings that reflect this host must subtract this set themselves.
  unavailable_recipes?: string[];
}

interface Devices {
  amd_dgpu: GPUDevice[];
  amd_igpu: GPUDevice;
  cpu: CPUInfo;
  npu: NPUInfo;
  nvidia_gpu: GPUDevice[];
}

interface Device {
  name: string;
  available: boolean;
  error?: string;
}

interface GPUDevice extends Device {
  vram_gb: number;
  virtual_mem_gb?: number;
}

interface CPUInfo extends Device {
  cores: number;
  threads: number;
}

interface NPUInfo extends Device {
}

// New recipes structure from system-info endpoint
// Fully dynamic - no hardcoded recipe or backend names
export interface Recipes {
  [recipeName: string]: Recipe;
}

// Per-recipe option schema, generated from the C++ backend descriptor.
export interface RecipeOptionSchema {
  name: string;
  cli_flag: string;
  default: unknown;
  type_name: string;
  help: string;
  group: string;
}

export interface Recipe {
  default_backend?: string;
  // Descriptor metadata (generated from the C++ backend descriptors).
  display_name?: string;
  selectable_backend?: boolean;
  uses_ctx_size?: boolean;
  options?: RecipeOptionSchema[];
  backends: {
    [backendName: string]: BackendInfo;
  };
}

export interface BackendInfo {
  devices: string[];
  state: 'unsupported' | 'installable' | 'update_required' | 'action_required' | 'installed' | 'update_available';
  message: string;
  action: string;
  can_uninstall?: boolean;
  version?: string;
  release_url?: string;
  download_filename?: string;
  download_size_mb?: number;
  download_size_bytes?: number;
}

export interface SystemData {
  info?: SystemInfo;
}

const fetchSystemInfoFromAPI = async (): Promise<SystemData> => {
  const { serverFetch } = await import('./serverConfig');

  try {
    const response = await serverFetch('/system-info');
    if (!response.ok) {
      throw new Error(`Failed to fetch system info: ${response.status} ${response.statusText}`);
    }

    const data = await response.json();
    const systemInfo: SystemInfo = { ...data };

    // Seed recipe display names from the descriptor-generated /system-info data
    // so the UI doesn't hardcode per-recipe names.
    const { updateRecipeDisplayNames } = await import('./recipeNames');
    updateRecipeDisplayNames(systemInfo.recipes);

    return { info: systemInfo };
  } catch (error) {
    console.error('Failed to fetch supported inference data from API:', error);
    return {};
  }
};

export const fetchSystemInfoData = async (): Promise<SystemData> => {
  return fetchSystemInfoFromAPI();
};
