'use strict';

const fs = require('fs');
const path = require('path');
const http = require('http');
const { execFile } = require('child_process');
const { jsonResponse: _jsonResponseDataFirst } = require('./api-utils');
const {
  isPortkeyGatewayCredentialRow,
  isPortkeyProviderRow,
  syncPortkeyGatewayModels,
} = require('../llm/portkey-sync');
const {
  buildPortkeyHeaders,
  defaultPortkeyBaseUrl,
} = require('../llm/portkey');
const { getDevboxClaudePortkeyGateway } = require('../runtime/devbox-gateway');

let brain = null;
try { brain = require('../brain'); } catch {}

const SETUP_PROVIDER_TYPES = ['anthropic', 'openai', 'google', 'ollama', 'deepseek', 'moonshot'];
const PORTKEY_GATEWAY_PROVIDER_TYPES = ['anthropic', 'deepseek', 'google', 'moonshot', 'openai'];
const SHELL_ENV_CACHE_TTL_MS = 5 * 60 * 1000;
const SHELL_ENV_LOOKUP_TIMEOUT_MS = 5000;
const _shellEnvCache = new Map();
const _shellEnvInflight = new Map();
let _shellEnvExecFile = execFile;

function getBrain() {
  if (!brain) return null;
  try { brain.getDb(); } catch {
    try { brain.initDb(); } catch { return null; }
  }
  return brain;
}

// NOTE: this module's local `jsonResponse` keeps (res, status, data) ordering
// for readability of HTTP-status-first dispatch chains, while the project-wide
// helper in `./api-utils` uses (res, data, status). Delegate so the two
// implementations can never drift apart silently. Callers in this file should
// continue to pass `(res, status, data)`.
function jsonResponse(res, status, data) {
  return _jsonResponseDataFirst(res, data, status);
}

function parseScorecardDays(value, fallbackDays) {
  const raw = String(value || '').trim().toLowerCase();
  if (raw === 'all' || raw === 'all-time' || raw === 'all_time' || raw === 'everything') return null;
  const days = parseInt(raw, 10);
  return Number.isFinite(days) && days > 0 ? days : fallbackDays;
}

function getShellRcSource(shell) {
  const name = path.basename(shell || '');
  if (name.includes('zsh')) {
    return 'source ~/.zprofile 2>/dev/null; source ~/.zshrc 2>/dev/null;';
  }
  if (name.includes('bash')) {
    return 'source ~/.bash_profile 2>/dev/null; source ~/.bashrc 2>/dev/null;';
  }
  return '';
}

function isSupportedEnvName(name) {
  return /^[A-Z_][A-Z0-9_]*$/.test(String(name || ''));
}

function normalizeShellEnvValue(value) {
  const str = String(value || '').trim();
  return str && str.length > 3 ? str : null;
}

function _cachedShellEnvValue(name, nowMs = Date.now()) {
  const cached = _shellEnvCache.get(name);
  if (!cached) return null;
  if (nowMs - cached.checkedAt > SHELL_ENV_CACHE_TTL_MS) return null;
  return cached.value || null;
}

function _setShellEnvCache(name, value, nowMs = Date.now()) {
  _shellEnvCache.set(name, { value: normalizeShellEnvValue(value), checkedAt: nowMs });
}

function _shellEnvLookupScript(names, shell) {
  const refs = names.map((name) => `"$${name}"`).join(' ');
  return `${getShellRcSource(shell)} printf '%s\\0' ${refs}`;
}

function _readShellEnvValues(names, options = {}) {
  const uniqueNames = Array.from(new Set((names || []).filter(isSupportedEnvName)));
  const out = new Map();
  const nowMs = options.nowMs || Date.now();
  const missing = [];
  for (const name of uniqueNames) {
    const direct = normalizeShellEnvValue(process.env[name]);
    if (direct) {
      out.set(name, direct);
      _setShellEnvCache(name, direct, nowMs);
      continue;
    }
    const cached = options.ignoreCache ? null : _cachedShellEnvValue(name, nowMs);
    if (cached) {
      out.set(name, cached);
      continue;
    }
    missing.push(name);
  }
  if (!missing.length) return Promise.resolve(out);

  const shell = process.env.SHELL || '/bin/zsh';
  const script = _shellEnvLookupScript(missing, shell);
  const timeoutMs = options.timeoutMs || SHELL_ENV_LOOKUP_TIMEOUT_MS;
  const inflightKey = `${shell}\n${timeoutMs}\n${missing.join('\0')}`;
  const inflight = _shellEnvInflight.get(inflightKey);
  if (inflight) {
    return inflight.then((missingValues) => {
      for (const [name, value] of missingValues.entries()) {
        if (value) out.set(name, value);
      }
      return out;
    });
  }
  const lookup = new Promise((resolve) => {
    _shellEnvExecFile(shell, ['-lc', script], {
      encoding: 'utf8',
      timeout: timeoutMs,
      maxBuffer: 128 * 1024,
    }, (err, stdout) => {
      const missingValues = new Map();
      if (err) {
        for (const name of missing) _setShellEnvCache(name, null, nowMs);
        resolve(missingValues);
        return;
      }
      const values = String(stdout || '').split('\0');
      missing.forEach((name, index) => {
        const value = normalizeShellEnvValue(values[index] || '');
        _setShellEnvCache(name, value, nowMs);
        if (value) missingValues.set(name, value);
      });
      resolve(missingValues);
    });
  }).finally(() => {
    _shellEnvInflight.delete(inflightKey);
  });
  _shellEnvInflight.set(inflightKey, lookup);
  return lookup.then((missingValues) => {
    for (const [name, value] of missingValues.entries()) out.set(name, value);
    return out;
  });
}

async function getShellEnvValue(name, options = {}) {
  if (!isSupportedEnvName(name)) return null;
  const values = await _readShellEnvValues([name], options);
  return values.get(name) || null;
}

function readSmallJsonBody(req, maxBytes = 65536) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    let size = 0;
    req.on('data', (chunk) => {
      size += chunk.length;
      if (size > maxBytes) {
        reject(new Error('Body too large'));
        req.destroy();
        return;
      }
      chunks.push(chunk);
    });
    req.on('end', () => {
      try { resolve(JSON.parse(Buffer.concat(chunks).toString() || '{}')); }
      catch (err) { reject(err); }
    });
    req.on('error', reject);
  });
}

function parseCustomHeaders(value) {
  if (!value) return undefined;
  if (typeof value === 'object') return value;
  try { return JSON.parse(value); } catch {}
  return undefined;
}

function isSqliteCatalogReadError(err) {
  return !!err && (
    err.code === 'SQLITE_CORRUPT'
    || /database disk image is malformed|malformed database schema|btree/i.test(err.message || '')
  );
}

function addCatalogWarning(warnings, where, err, extra = {}) {
  if (!warnings) return;
  const warning = {
    code: 'model_registry_unavailable',
    where,
    message: err && err.message ? err.message : String(err || 'Model registry read failed'),
    ...extra,
  };
  const key = JSON.stringify([warning.code, warning.where, warning.provider_id || '', warning.message]);
  if (!warnings.some((item) => item._key === key)) warnings.push({ ...warning, _key: key });
}

function publicCatalogWarnings(warnings) {
  return (warnings || []).map(({ _key, ...warning }) => warning);
}

function catalogStatusPayload(warnings) {
  return warnings && warnings.length
    ? {
      catalog_status: 'partial',
      catalog_unavailable: true,
      catalog_warnings: publicCatalogWarnings(warnings),
    }
    : { catalog_status: 'ok' };
}

function safeGetProviderWithKey(brainApi, provider, warnings) {
  try {
    return brainApi.getModelProviderWithKey(provider.id);
  } catch (err) {
    if (!isSqliteCatalogReadError(err)) throw err;
    addCatalogWarning(warnings, 'model_provider_key', err, { provider_id: provider.id });
    return provider;
  }
}

function safeProviderRoutePolicy(brainApi, type, warnings) {
  if (typeof brainApi.getProviderRoutePolicy !== 'function') return 'auto';
  try {
    return brainApi.getProviderRoutePolicy(type);
  } catch (err) {
    if (!isSqliteCatalogReadError(err)) throw err;
    addCatalogWarning(warnings, 'provider_route_policy', err, { provider_type: type });
    return 'auto';
  }
}

function safeListModelsByProvider(brainApi, providerId, warnings) {
  try {
    return { ok: true, models: brainApi.listModelsByProvider(providerId) || [] };
  } catch (err) {
    if (!isSqliteCatalogReadError(err)) throw err;
    addCatalogWarning(warnings, 'models_by_provider', err, { provider_id: providerId });
    return { ok: false, models: [], error: err };
  }
}

function safeModelCountsByProvider(brainApi, warnings) {
  try {
    if (typeof brainApi.listModelCountsByProvider !== 'function') {
      return { ok: false, counts: new Map(), error: null };
    }
    const rows = brainApi.listModelCountsByProvider();
    const counts = new Map();
    for (const row of rows || []) {
      counts.set(String(row.provider_id || ''), Number(row.model_count || 0));
    }
    return { ok: true, counts };
  } catch (err) {
    if (!isSqliteCatalogReadError(err)) throw err;
    addCatalogWarning(warnings, 'model_counts_by_provider', err);
    return { ok: false, counts: new Map(), error: err };
  }
}

function isPortkeyCatalogProviderRoute(provider = {}, models = []) {
  const id = String(provider.id || provider.provider_id || '').toLowerCase();
  const name = String(provider.name || '').toLowerCase();
  if (id.includes('-portkey-catalog-') || /\bvia\s+portkey\s+catalog\b/.test(name)) return true;
  if (!Array.isArray(models) || !models.length) return false;
  return models.every((model) => {
    const source = String(model.source || '').toLowerCase();
    const status = String(model.verification_status || model.verificationStatus || '').toLowerCase();
    return source === 'portkey_catalog' || status === 'catalog';
  });
}

function providerCatalogSortRank(provider = {}) {
  return provider.is_catalog === true || provider.catalog_only === true ? 1 : 0;
}

function getProviderWithMeta(brainApi, provider, options = {}) {
  const warnings = options.warnings || null;
  const full = Object.prototype.hasOwnProperty.call(options, 'full')
    ? options.full
    : safeGetProviderWithKey(brainApi, provider, warnings);
  const routePolicy = safeProviderRoutePolicy(brainApi, provider.type, warnings);
  const connectionKind = isPortkeyProviderRow(full || provider) ? 'portkey' : (provider.auth_method && provider.auth_method !== 'api_key' ? provider.auth_method : 'direct');
  const modelRead = options.modelRead || null;
  const isCatalog = isPortkeyCatalogProviderRoute(provider, modelRead && modelRead.ok ? modelRead.models : []);
  const {
    api_key_encrypted: _apiKeyEncrypted,
    apiKeyEncrypted: _apiKeyEncryptedCamel,
    custom_headers: _customHeaders,
    customHeaders: _customHeadersCamel,
    ...safeProvider
  } = provider || {};
  return {
    ...safeProvider,
    has_key: !!(full && full.api_key_encrypted),
    is_default_instance: provider.id.endsWith('-default') || provider.id.endsWith('-auto'),
    connection_kind: connectionKind,
    connection_source: isCatalog ? 'portkey_catalog' : connectionKind,
    is_catalog: isCatalog,
    catalog_only: isCatalog,
    route_policy: routePolicy,
    model_catalog_status: options.modelCatalogStatus || 'ok',
    ...(Number.isFinite(Number(options.modelCount)) ? { model_count: Number(options.modelCount) } : {}),
  };
}

function _portkeyLastErrorMap(lastError) {
  const out = new Map();
  for (const part of String(lastError || '').split(/;\s*/)) {
    if (!part) continue;
    const idx = part.indexOf(':');
    if (idx <= 0) continue;
    const routeId = part.slice(0, idx).trim();
    const message = part.slice(idx + 1).trim();
    if (routeId && message) out.set(routeId, message);
  }
  return out;
}

function getVerifiedPortkeyProviderTypes(brainApi, warnings = null) {
  const providers = brainApi.listModelProviders()
    .map((provider) => safeGetProviderWithKey(brainApi, provider, warnings) || provider)
    .filter(isPortkeyProviderRow);
  const countsRead = safeModelCountsByProvider(brainApi, warnings);
  const supported = new Set(
    providers
      .filter((provider) => {
        if (countsRead.ok) return (countsRead.counts.get(String(provider.id || '')) || 0) > 0;
        const modelRead = safeListModelsByProvider(brainApi, provider.id, warnings);
        return modelRead.ok && modelRead.models.length > 0;
      })
      .map((provider) => provider.type)
  );
  const known = PORTKEY_GATEWAY_PROVIDER_TYPES.filter((type) => supported.has(type));
  const custom = Array.from(supported).filter((type) => !PORTKEY_GATEWAY_PROVIDER_TYPES.includes(type)).sort();
  return known.concat(custom);
}

function buildGatewaySummary(brainApi, warnings = null) {
  const providers = brainApi.listModelProviders().map((provider) => {
    const full = safeGetProviderWithKey(brainApi, provider, warnings) || provider;
    return { ...provider, ...full };
  });
  const allPortkeyRoutes = providers.filter(isPortkeyProviderRow);
  const gatewayCredentials = providers.filter(isPortkeyGatewayCredentialRow);
  const credentialRows = gatewayCredentials.length ? gatewayCredentials : allPortkeyRoutes.slice(0, 1);
  const routeModelReads = new Map();
  const readRouteModels = (route) => {
    if (!routeModelReads.has(route.id)) {
      routeModelReads.set(route.id, safeListModelsByProvider(brainApi, route.id, warnings));
    }
    return routeModelReads.get(route.id);
  };
  const portkeyRoutes = allPortkeyRoutes.filter((route) => {
    const modelRead = readRouteModels(route);
    return modelRead.ok && modelRead.models.length > 0;
  });
  const configuredTypeSet = new Set(portkeyRoutes.map((route) => route.type).filter(Boolean));
  const providerTypes = PORTKEY_GATEWAY_PROVIDER_TYPES
    .filter((type) => configuredTypeSet.has(type))
    .concat(Array.from(configuredTypeSet).filter((type) => !PORTKEY_GATEWAY_PROVIDER_TYPES.includes(type)).sort());
  const lastSuccess = brainApi.getKv?.('model_gateway_sync:portkey:last_success_at') || '';
  const lastRun = brainApi.getKv?.('model_gateway_sync:portkey:last_run_at') || '';
  const lastError = brainApi.getKv?.('model_gateway_sync:portkey:last_error') || '';
  const routeErrors = _portkeyLastErrorMap(lastError);
  const routes = portkeyRoutes.map((route) => {
    const models = readRouteModels(route).models;
    const modelCount = models.length;
    const catalogModelCount = models.filter((model) => model.source === 'portkey_catalog').length;
    const gatewayModelCount = Math.max(0, modelCount - catalogModelCount);
    const supported = modelCount > 0;
    return {
      id: route.id,
      name: route.name,
      type: route.type,
      enabled: route.enabled,
      model_count: modelCount,
      catalog_model_count: catalogModelCount,
      gateway_model_count: gatewayModelCount,
      supported,
      support_status: supported ? (gatewayModelCount > 0 ? 'supported' : 'catalog') : (routeErrors.has(route.id) ? 'error' : 'unverified'),
      sync_error: routeErrors.get(route.id) || null,
      route_policy: safeProviderRoutePolicy(brainApi, route.type, warnings),
    };
  });
  const routesByType = new Map();
  for (const route of routes) {
    if (!routesByType.has(route.type)) routesByType.set(route.type, []);
    routesByType.get(route.type).push(route);
  }
  const supportedProviderTypes = providerTypes
    .filter((type) => (routesByType.get(type) || []).some((route) => route.supported));
  const supportedProviders = providerTypes.map((type) => {
    const typeRoutes = routesByType.get(type) || [];
    const supportedRoute = typeRoutes.find((route) => route.supported);
    const errorRoute = typeRoutes.find((route) => route.support_status === 'error');
    const route = supportedRoute || errorRoute || typeRoutes[0] || null;
    const supported = Boolean(supportedRoute);
    const supportStatus = supported ? 'supported' : (errorRoute ? 'error' : (typeRoutes.length ? 'unverified' : 'not_configured'));
    return {
      type,
      name: _providerDisplayName(type),
      configured: typeRoutes.length > 0,
      supported,
      support_status: supportStatus,
      route_id: route ? route.id : null,
      model_count: typeRoutes.reduce((sum, item) => sum + item.model_count, 0),
      catalog_model_count: typeRoutes.reduce((sum, item) => sum + (item.catalog_model_count || 0), 0),
      gateway_model_count: typeRoutes.reduce((sum, item) => sum + (item.gateway_model_count || 0), 0),
      sync_error: errorRoute ? errorRoute.sync_error : null,
      route_policy: safeProviderRoutePolicy(brainApi, type, warnings),
    };
  });
  const policies = {};
  for (const type of providerTypes) {
    policies[type] = safeProviderRoutePolicy(brainApi, type, warnings);
  }
  const totalModelCount = routes.reduce((sum, route) => sum + route.model_count, 0);
  const totalCatalogModelCount = routes.reduce((sum, route) => sum + (route.catalog_model_count || 0), 0);
  const totalGatewayModelCount = routes.reduce((sum, route) => sum + (route.gateway_model_count || 0), 0);
  const visibleLastError = totalModelCount > 0 ? '' : lastError;
  return [{
    type: 'portkey',
    name: 'Portkey Gateway',
    enabled: credentialRows.some((row) => row.enabled !== 0) || portkeyRoutes.some((route) => route.enabled !== 0),
    configured: credentialRows.length > 0 || allPortkeyRoutes.length > 0,
    credential_count: credentialRows.length,
    route_count: routes.length,
    provider_count: providerTypes.length,
    verified_provider_count: supportedProviderTypes.length,
    model_count: totalModelCount,
    catalog_model_count: totalCatalogModelCount,
    gateway_model_count: totalGatewayModelCount,
    provider_types: providerTypes,
    configured_provider_types: providerTypes,
    supported_provider_types: supportedProviderTypes,
    supported_providers: supportedProviders,
    routes,
    policies,
    last_success_at: lastSuccess,
    last_run_at: lastRun,
    last_error: visibleLastError,
    last_warning: visibleLastError ? '' : lastError,
    next_sync_hint: 'hourly',
  }];
}

function _slugFromLabel(label) {
  return String(label || '')
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '')
    .slice(0, 40);
}

function _providerDisplayName(type) {
  switch (type) {
    case 'anthropic': return 'Anthropic';
    case 'openai': return 'OpenAI';
    case 'google': return 'Google Gemini';
    case 'deepseek': return 'DeepSeek';
    case 'moonshot': return 'Moonshot / Kimi';
    default:
      return String(type || 'Provider')
        .split(/[-_]+/)
        .filter(Boolean)
        .map((part) => part.length <= 3 ? part.toUpperCase() : part.charAt(0).toUpperCase() + part.slice(1))
        .join(' ') || 'Provider';
  }
}

function _sanitizeSetupProviderType(value) {
  const sanitized = typeof value === 'string'
    ? value.toLowerCase().replace(/[^a-z]/g, '').slice(0, 20)
    : '';
  if (['kimi', 'kimik', 'kimik2', 'moonshotai', 'moonshotkimi'].includes(sanitized)) return 'moonshot';
  return sanitized;
}

function _sanitizeSetupModel(value) {
  return typeof value === 'string'
    ? value.replace(/[\r\n\s]/g, '').slice(0, 100)
    : '';
}

function handleLocalModelOwnerWrite(pathname, { method = 'POST', body = null } = {}) {
  const brainApi = getBrain();
  if (!brainApi) throw new Error('Wall-E brain not available');
  const p = String(pathname || '');
  const m = String(method || 'POST').toUpperCase();
  const payload = body && typeof body === 'object' ? body : {};

  if (p === '/api/wall-e/setup/provider' && m === 'POST') {
    const type = _sanitizeSetupProviderType(payload.type);
    if (!type) throw new Error('Invalid provider type');
    if (!SETUP_PROVIDER_TYPES.includes(type)) {
      throw new Error('Invalid provider type. Must be one of: ' + SETUP_PROVIDER_TYPES.join(', '));
    }
    const hasBaseUrl = Object.prototype.hasOwnProperty.call(payload, 'base_url')
      || Object.prototype.hasOwnProperty.call(payload, 'baseUrl');
    const result = brainApi.saveSetupProvider({
      id: payload.id || `${type}-default`,
      name: payload.name || _providerDisplayName(type),
      type,
      baseUrl: hasBaseUrl ? (payload.base_url || payload.baseUrl || null) : undefined,
      apiKeyEncrypted: typeof payload.api_key === 'string'
        ? payload.api_key.replace(/[\r\n\s]/g, '').slice(0, 200)
        : (payload.apiKeyEncrypted || null),
      customHeaders: payload.custom_headers || payload.customHeaders || null,
      enabled: payload.enabled !== false,
      model: _sanitizeSetupModel(payload.model),
      setDefault: Boolean(payload.set_default),
      authMethod: payload.auth_method || null,
    });
    return { ok: true, authority: 'wall-e-local-model-admin', owner_write: 'wall-e-local-model-admin', ...result };
  }

  if (p === '/api/wall-e/setup/default-provider' && m === 'POST') {
    const type = _sanitizeSetupProviderType(payload.type);
    if (!type) throw new Error('Invalid provider type');
    if (!SETUP_PROVIDER_TYPES.includes(type)) {
      throw new Error('Invalid provider type. Must be one of: ' + SETUP_PROVIDER_TYPES.join(', '));
    }
    const result = brainApi.setDefaultProviderSelection({
      type,
      requestedModel: _sanitizeSetupModel(payload.requested_model ?? payload.requestedModel ?? payload.model),
      targetModel: _sanitizeSetupModel(payload.target_model ?? payload.targetModel ?? payload.model),
    });
    return { ok: true, authority: 'wall-e-local-model-admin', owner_write: 'wall-e-local-model-admin', ...result };
  }

  const providerDelete = p.match(/^\/api\/wall-e\/setup\/provider\/([a-z0-9_-]+)$/);
  if (providerDelete && m === 'DELETE') {
    const type = _sanitizeSetupProviderType(providerDelete[1]);
    if (!type) throw new Error('Invalid provider type');
    const result = brainApi.disableModelProviderByType(type);
    return { ok: true, authority: 'wall-e-local-model-admin', owner_write: 'wall-e-local-model-admin', ...result };
  }

  throw new Error(`No local model owner write exists for ${m} ${p}`);
}

function _portkeyRuntimeBaseUrl(baseUrl, type) {
  const normalized = String(baseUrl || defaultPortkeyBaseUrl('openai')).trim().replace(/\/+$/, '');
  if (type === 'anthropic' && /^https:\/\/api\.portkey\.ai\/v1$/i.test(normalized)) {
    return defaultPortkeyBaseUrl('anthropic');
  }
  return normalized || defaultPortkeyBaseUrl(type);
}

function _resolveDevboxPortkeyGateway(body = {}, apiKey = '') {
  const source = String(body.source || body.credentialSource || body.detectedSource || '').toLowerCase();
  const wantsDevbox = source.includes('devbox') || body.useDevboxHeaders === true;
  const devboxGateway = getDevboxClaudePortkeyGateway();
  if (!devboxGateway) return null;
  if (wantsDevbox) return devboxGateway;
  return apiKey && apiKey === devboxGateway.apiKey ? devboxGateway : null;
}

function upsertPortkeyGateway(brainApi, body = {}) {
  let apiKey = String(body.apiKey || body.apiKeyEncrypted || '').trim();
  const devboxGateway = _resolveDevboxPortkeyGateway(body, apiKey);
  if (!apiKey && devboxGateway) apiKey = devboxGateway.apiKey;
  if (!apiKey) throw new Error('Portkey API key required');
  const label = String(body.label || (devboxGateway && body.source ? devboxGateway.label : '')).trim();
  const slug = _slugFromLabel(label);
  const suffix = slug ? `portkey-${slug}` : 'portkey';
  const baseUrl = String((devboxGateway && devboxGateway.baseUrl) || body.baseUrl || body.gatewayUrl || defaultPortkeyBaseUrl('openai')).trim() || defaultPortkeyBaseUrl('openai');
  const bodyHeaders = parseCustomHeaders(body.customHeaders || body.custom_headers) || {};
  const seedHeaders = Object.assign({}, devboxGateway ? devboxGateway.customHeaders : {}, bodyHeaders);
  const customHeaders = JSON.stringify(buildPortkeyHeaders({
    apiKey,
    configId: body.configId,
    virtualKey: body.virtualKey,
    headers: seedHeaders,
  }));
  let removedLegacyRoutes = 0;
  for (const provider of brainApi.listModelProviders?.() || []) {
    const full = brainApi.getModelProviderWithKey?.(provider.id) || provider;
    if (isPortkeyProviderRow(full) && (brainApi.listModelsByProvider(full.id) || []).length === 0) {
      removedLegacyRoutes += brainApi.deleteModelProvider(full.id) || 0;
    }
  }
  const credential = {
    id: `portkey-gateway-${slug || 'default'}`,
    name: `Portkey Gateway${label ? ` (${label})` : ''}`,
    type: 'portkey_gateway',
    baseUrl: _portkeyRuntimeBaseUrl(baseUrl, 'openai'),
    apiKeyEncrypted: apiKey,
    customHeaders,
    enabled: 1,
  };
  brainApi.upsertModelProvider(credential);
  brainApi.setKv?.('model_gateway:portkey:label', label);
  brainApi.setKv?.('model_gateway:portkey:base_url', baseUrl);
  if (devboxGateway) brainApi.setKv?.('model_gateway:portkey:source', devboxGateway.source);
  return {
    ok: true,
    gateway: 'portkey',
    provider: { id: credential.id, type: credential.type, name: credential.name },
    source: devboxGateway ? devboxGateway.source : (body.source || ''),
    removed_legacy_routes: removedLegacyRoutes,
  };
}

async function handleAvailableAgents(req, res) {
  const agents = ['claude', 'codex', 'gemini'];
  const result = {};
  let pending = agents.length;
  let responded = false;

  const safetyTimer = setTimeout(() => {
    if (responded) return;
    responded = true;
    for (const agent of agents) {
      if (!(agent in result)) result[agent] = false;
    }
    jsonResponse(res, 200, result);
  }, 3000);

  for (const agent of agents) {
    execFile('which', [agent], { encoding: 'utf8', timeout: 2000 }, (err) => {
      result[agent] = !err;
      if (--pending === 0 && !responded) {
        responded = true;
        clearTimeout(safetyTimer);
        jsonResponse(res, 200, result);
      }
    });
  }
}

async function detectOllama() {
  return new Promise((resolve) => {
    const req = http.get('http://127.0.0.1:11434/api/tags', { timeout: 2000 }, (res) => {
      const ok = res.statusCode === 200;
      res.resume();
      resolve(ok);
    });
    req.on('error', () => resolve(false));
    req.on('timeout', () => {
      req.destroy();
      resolve(false);
    });
  });
}

async function handleModelAdminApi(req, res, url) {
  const brainApi = getBrain();
  const p = url.pathname;
  const m = req.method;

  if (p === '/api/models/providers' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const warnings = [];
      const modelCountsByProvider = safeModelCountsByProvider(brainApi, warnings);
      const providerRows = brainApi.listModelProviders()
        .map((provider, index) => {
          const full = safeGetProviderWithKey(brainApi, provider, warnings) || provider;
          const isPortkey = isPortkeyProviderRow(full);
          const providerId = String(full.id || provider.id || '');
          const modelCount = modelCountsByProvider.ok
            ? (modelCountsByProvider.counts.get(providerId) || 0)
            : null;
          return { provider, full, isPortkey, modelCount, index };
        })
        .filter(({ full, isPortkey, modelCount }) => {
          if (isPortkeyGatewayCredentialRow(full)) return false;
          if (isPortkey && modelCountsByProvider.ok && modelCount === 0) return false;
          return true;
        })
        .map(({ provider, full, modelCount, index }) => ({
          provider: getProviderWithMeta(brainApi, provider, {
            full,
            modelCount: modelCountsByProvider.ok ? modelCount : undefined,
            warnings,
            modelCatalogStatus: warnings.length ? 'partial' : 'ok',
          }),
          index,
        }));
      providerRows.sort((a, b) => {
        const rank = providerCatalogSortRank(a.provider) - providerCatalogSortRank(b.provider);
        if (rank !== 0) return rank;
        return a.index - b.index;
      });
      const providers = providerRows.map((row) => row.provider);
      const typeCounts = {};
      for (const provider of providers) typeCounts[provider.type] = (typeCounts[provider.type] || 0) + 1;
      for (const provider of providers) provider.instance_count = typeCounts[provider.type];
      return jsonResponse(res, 200, { providers, ...catalogStatusPayload(warnings) });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/gateways' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const warnings = [];
      return jsonResponse(res, 200, { gateways: buildGatewaySummary(brainApi, warnings), ...catalogStatusPayload(warnings) });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/provider-route-policy' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      const type = String(body.type || '').trim().toLowerCase();
      const policy = String(body.policy || 'auto').trim().toLowerCase();
      const warnings = [];
      if (policy === 'portkey' && !getVerifiedPortkeyProviderTypes(brainApi, warnings).includes(type)) {
        if (warnings.length) {
          return jsonResponse(res, 409, {
            error: `${_providerDisplayName(type)} could not be verified by the Portkey gateway because the model catalog is partially unavailable. Repair or resync the model catalog, then try again.`,
            code: 'model_registry_unavailable',
            type,
            ...catalogStatusPayload(warnings),
          });
        }
        return jsonResponse(res, 409, {
          error: `${_providerDisplayName(type)} is not verified by the Portkey gateway yet. Fix the Portkey sync error, then sync models before selecting Portkey.`,
          code: 'portkey_provider_not_verified',
          type,
        });
      }
      const result = brainApi.setProviderRoutePolicy({ type: body.type, policy: body.policy });
      return jsonResponse(res, 200, { ok: true, ...result });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/portkey/sync' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      const result = await syncPortkeyGatewayModels({ brainApi, providerId: body.provider_id || body.providerId || null });
      return jsonResponse(res, result.errors.length ? 207 : 200, { ok: result.errors.length === 0, ...result });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/gateways/portkey' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      return jsonResponse(res, 200, upsertPortkeyGateway(brainApi, body));
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/portkey/apply-all' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const providers = brainApi.listModelProviders()
        .map((provider) => brainApi.getModelProviderWithKey(provider.id) || provider)
        .filter(isPortkeyProviderRow);
      const types = Array.from(new Set(providers.map((provider) => provider.type))).sort();
      const supportedTypes = getVerifiedPortkeyProviderTypes(brainApi);
      const supportedSet = new Set(supportedTypes);
      const skippedTypes = types.filter((type) => !supportedSet.has(type));
      for (const type of supportedTypes) brainApi.setProviderRoutePolicy({ type, policy: 'portkey' });
      for (const type of skippedTypes) {
        if (brainApi.getProviderRoutePolicy?.(type) === 'portkey') {
          brainApi.setProviderRoutePolicy({ type, policy: 'auto' });
        }
      }
      const payload = { ok: supportedTypes.length > 0, gateway: 'portkey', provider_types: supportedTypes, skipped_provider_types: skippedTypes };
      return jsonResponse(res, supportedTypes.length > 0 ? 200 : 409, supportedTypes.length > 0 ? payload : {
        ...payload,
        error: 'No Portkey providers are verified yet. Fix the Portkey sync error, then sync models before applying Portkey.',
        code: 'no_verified_portkey_providers',
      });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/portkey/disable-default' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const providers = brainApi.listModelProviders()
        .map((provider) => brainApi.getModelProviderWithKey(provider.id) || provider)
        .filter(isPortkeyProviderRow);
      const types = Array.from(new Set(providers.map((provider) => provider.type))).sort();
      for (const type of types) brainApi.setProviderRoutePolicy({ type, policy: 'auto' });
      return jsonResponse(res, 200, { ok: true, gateway: 'portkey', provider_types: types });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/gateways/portkey' && m === 'DELETE') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const providers = brainApi.listModelProviders()
        .map((provider) => brainApi.getModelProviderWithKey(provider.id) || provider)
        .filter((provider) => isPortkeyGatewayCredentialRow(provider) || isPortkeyProviderRow(provider));
      const types = Array.from(new Set(providers.filter(isPortkeyProviderRow).map((provider) => provider.type)));
      let deletedProviders = 0;
      let deletedModels = 0;
      for (const provider of providers) {
        deletedModels += brainApi.deleteModelRegistryByProvider(provider.id) || 0;
        deletedProviders += brainApi.deleteModelProvider(provider.id) || 0;
      }
      for (const type of types) brainApi.setProviderRoutePolicy({ type, policy: 'auto' });
      return jsonResponse(res, 200, { ok: true, gateway: 'portkey', deleted_providers: deletedProviders, deleted_models: deletedModels });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/providers' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      brainApi.upsertModelProvider(body);
      return jsonResponse(res, 200, { ok: true, id: body.id });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p.startsWith('/api/models/providers/') && m === 'DELETE') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    const id = decodeURIComponent(p.split('/api/models/providers/')[1] || '');
    if (!id) return jsonResponse(res, 400, { error: 'Missing provider id' });
    try {
      const provider = brainApi.getModelProvider(id);
      if (provider) {
        const sameTypeProviders = brainApi.listModelProviders().filter((item) => item.type === provider.type);
        if (sameTypeProviders.length <= 1) {
          const activeDefault = brainApi.getKv('walle_provider');
          if (activeDefault === provider.type) {
            return jsonResponse(res, 400, { error: 'Cannot delete the last instance of the active default provider type' });
          }
        }
      }
      brainApi.deleteModelRegistryByProvider(id);
      brainApi.deleteModelProvider(id);
      return jsonResponse(res, 200, { ok: true });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/registry' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const providerId = url.searchParams.get('provider_id');
      const warnings = [];
      if (providerId) {
        const modelRead = safeListModelsByProvider(brainApi, providerId, warnings);
        return jsonResponse(res, 200, { models: modelRead.models, ...catalogStatusPayload(warnings) });
      }

      const providers = brainApi.listModelProviders();
      const models = [];
      for (const provider of providers) {
        const modelRead = safeListModelsByProvider(brainApi, provider.id, warnings);
        for (const model of modelRead.models) {
          models.push({
            ...model,
            provider_name: provider.name,
            provider_type: provider.type,
          });
        }
      }
      models.sort((a, b) => String(a.provider_name || '').localeCompare(String(b.provider_name || ''))
        || String(a.display_name || '').localeCompare(String(b.display_name || '')));
      return jsonResponse(res, 200, { models, ...catalogStatusPayload(warnings) });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/coding-catalog' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const warnings = [];
      const providerId = url.searchParams.get('provider_id');
      const includeLive = url.searchParams.get('live') === '1' || url.searchParams.get('live') === 'true';
      const providers = brainApi.listModelProviders()
        .filter((provider) => provider.enabled !== 0 && provider.enabled !== false)
        .filter((provider) => !providerId || provider.id === providerId);
      const providerRows = [];
      const models = [];
      for (const provider of providers) {
        const modelRead = safeListModelsByProvider(brainApi, provider.id, warnings);
        providerRows.push(getProviderWithMeta(brainApi, provider, {
          warnings,
          modelRead,
          modelCatalogStatus: modelRead.ok ? 'ok' : 'partial',
          modelCount: modelRead.models.length,
        }));
        for (const model of modelRead.models) {
          models.push({
            ...model,
            provider_name: provider.name,
            provider_type: provider.type,
          });
        }
      }
      let liveAvailability = null;
      if (includeLive && providers.length > 0) {
        try {
          const { createClient } = require('../llm/client');
          const { listCodingModelAvailability } = require('../llm/coding-availability');
          liveAvailability = await listCodingModelAvailability({
            providers,
            getProviderWithKey: (id) => brainApi.getModelProviderWithKey(id),
            createClient,
          });
        } catch (err) {
          addCatalogWarning(warnings, 'coding_catalog_live_probe', err);
        }
      }
      const { buildSessionModelCatalog } = require('../llm/model-catalog');
      return jsonResponse(res, 200, {
        ...buildSessionModelCatalog({
          providers: providerRows,
          models,
          liveAvailability,
        }),
        ...catalogStatusPayload(warnings),
      });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/coding-availability' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const providerId = url.searchParams.get('provider_id');
      const providers = brainApi.listModelProviders()
        .filter((provider) => provider.enabled !== 0 && provider.enabled !== false)
        .filter((provider) => !providerId || provider.id === providerId);
      const { createClient } = require('../llm/client');
      const { listCodingModelAvailability } = require('../llm/coding-availability');
      return jsonResponse(res, 200, await listCodingModelAvailability({
        providers,
        getProviderWithKey: (id) => brainApi.getModelProviderWithKey(id),
        createClient,
      }));
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/registry' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      brainApi.upsertModelRegistryEntry(body);
      return jsonResponse(res, 200, { ok: true, id: body.id });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/defaults' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      return jsonResponse(res, 200, { defaults: brainApi.listModelDefaults() });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/defaults' && m === 'PUT') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      const result = brainApi.setModelDefault(body.taskType, body.modelRegistryId, body.strategy, body.quorumSize);
      return jsonResponse(res, 200, result);
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/scorecard' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const days = parseScorecardDays(url.searchParams.get('days'), 7);
      const scorecard = brainApi.listAllModels().map((model) => ({
        ...model,
        stats: brainApi.getModelScorecard(model.id, days),
      }));
      let benchmarks = [];
      let benchmarkCoverage = null;
      try { benchmarks = brainApi.getBenchmarkLeaderboardWithDimensions({ days }); } catch {}
      try { benchmarkCoverage = brainApi.getBenchmarkCoverageSummary({ days }); } catch {}
      return jsonResponse(res, 200, { scorecard, benchmarks, benchmarkCoverage });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/usage-ledger' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const filters = {
        sessionId: url.searchParams.get('session_id') || url.searchParams.get('sessionId') || '',
        providerType: url.searchParams.get('provider') || url.searchParams.get('provider_type') || '',
        providerId: url.searchParams.get('provider_id') || '',
        modelId: url.searchParams.get('model') || url.searchParams.get('model_id') || '',
        modelRegistryId: url.searchParams.get('model_registry_id') || '',
        source: url.searchParams.get('source') || '',
        since: url.searchParams.get('since') || '',
        until: url.searchParams.get('until') || '',
        limit: url.searchParams.get('limit') || '',
      };
      const entries = typeof brainApi.listModelUsageLedger === 'function'
        ? brainApi.listModelUsageLedger(filters)
        : [];
      const summary = typeof brainApi.summarizeModelUsageLedger === 'function'
        ? brainApi.summarizeModelUsageLedger(filters)
        : [];
      return jsonResponse(res, 200, { entries, summary });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/test-connection' && m === 'POST') {
    try {
      const body = await readSmallJsonBody(req);
      let apiKey = body.apiKey;
      let baseUrl = body.baseUrl;
      let providerType = body.type;
      let customHeaders = body.customHeaders;
      if (body.instance_id && !apiKey && brainApi) {
        const stored = brainApi.getModelProviderWithKey(body.instance_id);
        if (stored) {
          apiKey = stored.api_key_encrypted;
          baseUrl = baseUrl || stored.base_url;
          providerType = providerType || stored.type;
          customHeaders = customHeaders || stored.custom_headers;
        }
      }
      if (providerType === 'google' && apiKey && apiKey.startsWith('ya29.') && process.env.GOOGLE_AUTH_MODE !== 'oauth') {
        return jsonResponse(res, 400, { error: 'Stored key is a stale Gemini CLI OAuth token (ya29.*). Replace it with an API key from aistudio.google.com/apikey' });
      }
      const { createClient } = require('../llm/client');
      const client = createClient(providerType, {
        apiKey,
        baseUrl,
        customHeaders: parseCustomHeaders(customHeaders),
      });
      if (client.isAvailable) {
        const available = await client.isAvailable();
        if (!available) return jsonResponse(res, 400, { error: 'Provider not available' });
      }
      const models = await client.listModels();
      return jsonResponse(res, 200, { ok: true, models });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/ollama/models' && m === 'GET') {
    try {
      const { createOllamaProvider } = require('../llm/ollama');
      const ollama = createOllamaProvider({});
      const available = await ollama.isAvailable();
      if (!available) return jsonResponse(res, 200, { models: [], available: false });
      return jsonResponse(res, 200, { models: await ollama.listModels(), available: true });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/available-agents' && m === 'GET') {
    return handleAvailableAgents(req, res);
  }

  if (p === '/api/models/health' && m === 'GET') {
    try {
      const h = require('../llm/health').default;
      return jsonResponse(res, 200, h.getSystemHealth());
    } catch {
      return jsonResponse(res, 200, { providers: {}, hasHealthyProvider: true, healthyProviders: [] });
    }
  }

  if (p === '/api/models/shadow-config' && m === 'GET') {
    try {
      const configPath = path.resolve(__dirname, '..', 'wall-e-config.json');
      let shadow = { enabled: false };
      if (fs.existsSync(configPath)) {
        shadow = JSON.parse(fs.readFileSync(configPath, 'utf8')).shadow || shadow;
      }
      let counts = { total: 0, evaluated: 0, pending: 0 };
      if (brainApi) {
        try {
          const all = brainApi.getShadowResults({ limit: 100000 });
          const evaluated = all.filter((row) => row.evaluated_at);
          counts = { total: all.length, evaluated: evaluated.length, pending: all.length - evaluated.length };
        } catch {}
      }
      return jsonResponse(res, 200, { shadow, counts });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/shadow-config' && m === 'PUT') {
    try {
      const configPath = path.resolve(__dirname, '..', 'wall-e-config.json');
      const body = await readSmallJsonBody(req);
      let cfg = {};
      if (fs.existsSync(configPath)) cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
      cfg.shadow = {
        enabled: !!body.enabled,
        sampleRate: Math.max(0, Math.min(1, body.sampleRate ?? 0.3)),
        taskTypes: Array.isArray(body.taskTypes) ? body.taskTypes : ['chat', 'coding', 'qa', 'slack-reply'],
        maxLatencyMs: body.maxLatencyMs || 30000,
        models: Array.isArray(body.models) ? body.models : (cfg.shadow?.models || []),
        evalMethods: Array.isArray(body.evalMethods) ? body.evalMethods : (cfg.shadow?.evalMethods || ['heuristic', 'embedding', 'llm-judge']),
        judgeModel: body.judgeModel || cfg.shadow?.judgeModel || 'claude-haiku-4-5',
        maxJudgesPerDay: body.maxJudgesPerDay != null ? (parseInt(body.maxJudgesPerDay, 10) || 50) : (cfg.shadow?.maxJudgesPerDay || 50),
      };
      fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2), { mode: 0o600 });
      return jsonResponse(res, 200, { ok: true, shadow: cfg.shadow });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p === '/api/models/scorecard/timeline' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const modelId = url.searchParams.get('model_id');
      const days = parseScorecardDays(url.searchParams.get('days'), 30);
      if (!modelId) return jsonResponse(res, 400, { error: 'model_id required' });
      return jsonResponse(res, 200, { timeline: brainApi.getModelEvaluationTimeline(modelId, days) });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/promotion-log' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const limit = parseInt(url.searchParams.get('limit'), 10) || 20;
      return jsonResponse(res, 200, { log: brainApi.getPromotionActivityLog(limit) });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/task-scores' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      return jsonResponse(res, 200, { scores: brainApi.getModelTaskScores(url.searchParams.get('task_type') || undefined) });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/tier-defaults' && m === 'GET') {
    try {
      const { DEFAULT_TIER_MODELS, COMPLEXITY_TO_TIER } = require('../evaluation/tier-selector');
      const envOverrides = {};
      for (const tier of ['fast', 'balanced', 'quality']) {
        const envKey = `WALLE_MODEL_${tier.toUpperCase()}`;
        if (process.env[envKey]) envOverrides[tier] = process.env[envKey];
      }
      return jsonResponse(res, 200, {
        tiers: DEFAULT_TIER_MODELS,
        complexityMap: COMPLEXITY_TO_TIER,
        envOverrides,
        budgetDaily: process.env.WALLE_EVAL_BUDGET_DAILY || null,
      });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/training-reviews' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const filters = {
        verdict: url.searchParams.get('verdict') || undefined,
        model: url.searchParams.get('model') || undefined,
        taskType: url.searchParams.get('task_type') || undefined,
        dateFrom: url.searchParams.get('date_from') || undefined,
        dateTo: url.searchParams.get('date_to') || undefined,
        page: parseInt(url.searchParams.get('page'), 10) || 1,
        pageSize: parseInt(url.searchParams.get('page_size'), 10) || 20,
      };
      return jsonResponse(res, 200, brainApi.getShadowResultsForReview(filters));
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p.startsWith('/api/models/training-reviews/') && p.endsWith('/verdict') && m === 'PUT') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      const parts = p.split('/');
      const id = decodeURIComponent(parts[parts.length - 2]);
      brainApi.updateShadowResultEval(id, body);
      return jsonResponse(res, 200, { ok: true });
    } catch (e) {
      return jsonResponse(res, 400, { error: e.message });
    }
  }

  if (p.startsWith('/api/models/shadow-results/') && !p.endsWith('/reevaluate') && !p.endsWith('/verdict') && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const id = decodeURIComponent(p.split('/').pop());
      const result = brainApi.getShadowResultById(id);
      if (!result) return jsonResponse(res, 404, { error: 'Not found' });
      return jsonResponse(res, 200, { result });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p.startsWith('/api/models/shadow-results/') && p.endsWith('/reevaluate') && m === 'PUT') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const parts = p.split('/');
      const id = decodeURIComponent(parts[parts.length - 2]);
      const result = brainApi.getShadowResultById(id);
      if (!result) return jsonResponse(res, 404, { error: 'Not found' });
      brainApi.getDb().prepare(
        'UPDATE shadow_results SET primary_score = NULL, shadow_score = NULL, eval_method = NULL, judge_model = NULL, judge_reasoning = NULL, evaluated_at = NULL WHERE id = ?'
      ).run(id);
      const { evaluateShadowResult } = require('../training/evaluator');
      await evaluateShadowResult(brainApi.getShadowResultById(id), brainApi);
      return jsonResponse(res, 200, { ok: true, result: brainApi.getShadowResultById(id) });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/scorecard/wins' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const model = url.searchParams.get('model') || undefined;
      const wins = model ? brainApi.getModelWinRatesForModel(model) : brainApi.getModelWinRates();
      return jsonResponse(res, 200, { wins });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/scorecard/examples' && m === 'GET') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const model = url.searchParams.get('model');
      const taskType = url.searchParams.get('task_type');
      if (!model || !taskType) return jsonResponse(res, 400, { error: 'model and task_type required' });
      return jsonResponse(res, 200, brainApi.getBestWorstExamples(model, taskType));
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/detect-keys' && m === 'GET') {
    try {
      const detected = [];
      const envValues = await _readShellEnvValues([
        'ANTHROPIC_API_KEY',
        'OPENAI_API_KEY',
        'GOOGLE_API_KEY',
        'GEMINI_API_KEY',
        'MOONSHOT_API_KEY',
        'PORTKEY_API_KEY',
      ], { ignoreCache: url.searchParams.get('refresh') === '1' });
      const anthropicKey = envValues.get('ANTHROPIC_API_KEY');
      if (anthropicKey) detected.push({ type: 'anthropic', name: 'Anthropic', source: 'ANTHROPIC_API_KEY', apiKeyMasked: anthropicKey.slice(0, 8) + '...' + anthropicKey.slice(-4) });
      const openaiKey = envValues.get('OPENAI_API_KEY');
      if (openaiKey) detected.push({ type: 'openai', name: 'OpenAI', source: 'OPENAI_API_KEY', apiKeyMasked: openaiKey.slice(0, 8) + '...' + openaiKey.slice(-4) });
      const googleKey = envValues.get('GOOGLE_API_KEY') || envValues.get('GEMINI_API_KEY');
      if (googleKey) {
        const source = envValues.get('GOOGLE_API_KEY') ? 'GOOGLE_API_KEY' : 'GEMINI_API_KEY';
        detected.push({ type: 'google', name: 'Google Gemini', source, apiKeyMasked: googleKey.slice(0, 8) + '...' + googleKey.slice(-4) });
      } else {
        try {
          const credsPath = path.join(process.env.HOME, '.gemini', 'oauth_creds.json');
          if (fs.existsSync(credsPath)) {
            const creds = JSON.parse(fs.readFileSync(credsPath, 'utf8'));
            if (creds.access_token) {
              detected.push({ type: 'google', name: 'Google Gemini', source: 'Gemini CLI (~/.gemini)', apiKeyMasked: 'OAuth · ' + creds.access_token.slice(0, 12) + '...' });
            }
          }
        } catch {}
      }
      const moonshotKey = envValues.get('MOONSHOT_API_KEY');
      if (moonshotKey) detected.push({ type: 'moonshot', name: 'Moonshot / Kimi', source: 'MOONSHOT_API_KEY', apiKeyMasked: moonshotKey.slice(0, 8) + '...' + moonshotKey.slice(-4) });
      if (await detectOllama()) {
        detected.push({ type: 'ollama', name: 'Ollama (Local)', source: 'localhost:11434', apiKeyMasked: 'n/a' });
      }
      const gateways = [];
      const devboxPortkey = getDevboxClaudePortkeyGateway();
      if (devboxPortkey) {
        gateways.push({
          type: 'portkey',
          name: 'Portkey gateway',
          source: devboxPortkey.source,
          label: devboxPortkey.label,
          apiKeyMasked: devboxPortkey.apiKeyMasked,
          baseUrl: devboxPortkey.baseUrl,
          canAutoConfigure: true,
          hasProvider: devboxPortkey.hasProvider,
          hasVirtualKey: devboxPortkey.hasVirtualKey,
          hasConfig: devboxPortkey.hasConfig,
          hasMetadata: devboxPortkey.hasMetadata,
        });
      }
      const portkeyKey = envValues.get('PORTKEY_API_KEY');
      if (portkeyKey && (!devboxPortkey || portkeyKey !== devboxPortkey.apiKey)) {
        gateways.push({ type: 'portkey', name: 'Portkey gateway', source: 'PORTKEY_API_KEY', apiKeyMasked: portkeyKey.slice(0, 8) + '...' + portkeyKey.slice(-4) });
      }
      const existingTypes = new Set((brainApi ? brainApi.listModelProviders() : []).map((provider) => provider.type));
      return jsonResponse(res, 200, { detected: detected.filter((item) => !existingTypes.has(item.type)), gateways });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  if (p === '/api/models/auto-setup' && m === 'POST') {
    if (!brainApi) return jsonResponse(res, 500, { error: 'Wall-E brain not available' });
    try {
      const body = await readSmallJsonBody(req);
      let type = String(body.type || '').toLowerCase().replace(/[^a-z0-9_-]/g, '').slice(0, 32);
      if (['kimi', 'kimi-k2', 'moonshot-ai', 'moonshotkimi'].includes(type)) type = 'moonshot';
      if (!type) return jsonResponse(res, 400, { error: 'Missing type' });

      const keyMap = {
        anthropic: () => getShellEnvValue('ANTHROPIC_API_KEY', { ignoreCache: true }),
        openai: () => getShellEnvValue('OPENAI_API_KEY', { ignoreCache: true }),
        google: async () => {
          const envValues = await _readShellEnvValues(['GOOGLE_API_KEY', 'GEMINI_API_KEY'], { ignoreCache: true });
          const envKey = envValues.get('GOOGLE_API_KEY') || envValues.get('GEMINI_API_KEY');
          if (envKey) return envKey;
          try {
            const creds = JSON.parse(fs.readFileSync(path.join(process.env.HOME, '.gemini', 'oauth_creds.json'), 'utf8'));
            return creds.access_token || null;
          } catch {
            return null;
          }
        },
        deepseek: () => getShellEnvValue('DEEPSEEK_API_KEY', { ignoreCache: true }),
        moonshot: () => getShellEnvValue('MOONSHOT_API_KEY', { ignoreCache: true }),
        ollama: () => null,
      };

      const nameMap = { anthropic: 'Anthropic', openai: 'OpenAI', google: 'Google Gemini', deepseek: 'DeepSeek', moonshot: 'Moonshot / Kimi', ollama: 'Ollama (Local)' };
      const apiKey = keyMap[type] ? await keyMap[type]() : null;
      if (!apiKey && type !== 'ollama') return jsonResponse(res, 400, { error: `No API key found in environment for ${type}` });

      const existingProviders = brainApi.listModelProviders().filter((provider) => provider.type === type);
      const defaultInstance = existingProviders.find((provider) => provider.id === `${type}-default` || provider.id === `${type}-auto`);
      const providerId = defaultInstance ? defaultInstance.id : `${type}-default`;

      brainApi.upsertModelProvider({
        id: providerId,
        name: nameMap[type] || type,
        type,
        apiKeyEncrypted: apiKey || null,
        enabled: 1,
      });

      let discoveredModels = [];
      try {
        const { createClient } = require('../llm/client');
        const client = createClient(type, { apiKey: apiKey || undefined });
        if (client.isAvailable) {
          const available = await client.isAvailable();
          if (!available && type !== 'ollama') return jsonResponse(res, 400, { error: 'Provider not reachable' });
        }
        discoveredModels = await client.listModels();
      } catch {}

      for (const model of discoveredModels) {
        brainApi.upsertModelRegistryEntry({
          id: `${providerId}:${model.id}`,
          providerId,
          modelId: model.id,
          displayName: model.name || model.id,
          capabilities: model.capabilities || ['code'],
          costPer1mInput: model.costPer1mInput || null,
          costPer1mOutput: model.costPer1mOutput || null,
          maxContextTokens: model.maxContextTokens || null,
          speedTier: 3,
          enabled: 1,
        });
      }

      return jsonResponse(res, 200, { ok: true, providerId, modelsCount: discoveredModels.length });
    } catch (e) {
      return jsonResponse(res, 500, { error: e.message });
    }
  }

  return false;
}

module.exports = {
  handleModelAdminApi,
  handleLocalModelOwnerWrite,
  _test: {
    _readShellEnvValues,
    _shellEnvLookupScript,
    clearShellEnvCache() { _shellEnvCache.clear(); _shellEnvInflight.clear(); },
    setShellEnvExecFile(fn) { _shellEnvExecFile = typeof fn === 'function' ? fn : execFile; },
  },
};
