import type { CliProviderId, TeamProviderId } from '@shared/types';

const PROVIDER_MODEL_PROBE_TIMEOUT_MS = 60_000;
const PROVIDER_MODEL_PROBE_CODEX_TIMEOUT_MS = 60_000;
const PROVIDER_MODEL_PROBE_GEMINI_TIMEOUT_MS = 15_000;
const PROVIDER_MODEL_PROBE_PROMPT = 'Output only the single word PONG.';

type SupportedProviderId = CliProviderId | TeamProviderId;

function resolveProbeProviderId(providerId: SupportedProviderId | undefined): SupportedProviderId {
  return providerId === 'codex' || providerId === 'gemini' ? providerId : 'anthropic';
}

export function getProviderModelProbePrompt(): string {
  return PROVIDER_MODEL_PROBE_PROMPT;
}

export function getProviderModelProbeExpectedOutput(): string {
  return 'PONG';
}

export function isProviderModelProbeSuccessOutput(output: string): boolean {
  return new RegExp(`\\b${getProviderModelProbeExpectedOutput()}\\b`, 'i').test(output.trim());
}

export function classifyProviderModelProbeFailure(message: string): 'unavailable' | 'unknown' {
  const lower = message.toLowerCase();

  if (
    lower.includes('model is not supported') ||
    lower.includes('model not supported') ||
    lower.includes('unsupported model') ||
    lower.includes('model is not available') ||
    lower.includes('model not available') ||
    lower.includes('model unavailable') ||
    lower.includes('model not found') ||
    lower.includes('unknown model') ||
    lower.includes('invalid model')
  ) {
    return 'unavailable';
  }

  return 'unknown';
}

export function isProviderModelProbeTimeoutMessage(message: string): boolean {
  const lower = message.toLowerCase();
  return (
    lower.includes('timeout running:') ||
    lower.includes('timed out') ||
    lower.includes('etimedout') ||
    lower.includes('did not complete')
  );
}

export function normalizeProviderModelProbeFailureReason(message: string): string {
  const trimmed = message.trim();
  if (!trimmed) {
    return 'Model verification failed';
  }

  if (
    /The '[^']+' model is not supported when using Codex with a ChatGPT account\./i.test(trimmed)
  ) {
    return 'Not available on this Codex native runtime';
  }
  if (/The requested model is not available for your account\./i.test(trimmed)) {
    return 'Not available for this account';
  }
  if (isProviderModelProbeTimeoutMessage(trimmed)) {
    return 'Model verification timed out';
  }

  return trimmed;
}

export function buildProviderModelProbeArgs(modelId: string): string[] {
  return [
    '-p',
    getProviderModelProbePrompt(),
    '--output-format',
    'text',
    '--model',
    modelId,
    '--max-turns',
    '1',
    '--no-session-persistence',
  ];
}

export function getProviderModelProbeTimeoutMs(
  providerId: SupportedProviderId | undefined
): number {
  switch (resolveProbeProviderId(providerId)) {
    case 'codex':
      return PROVIDER_MODEL_PROBE_CODEX_TIMEOUT_MS;
    case 'gemini':
      return PROVIDER_MODEL_PROBE_GEMINI_TIMEOUT_MS;
    case 'anthropic':
    default:
      return PROVIDER_MODEL_PROBE_TIMEOUT_MS;
  }
}

export function getProviderPreflightModel(providerId: TeamProviderId | undefined): string {
  switch (resolveProbeProviderId(providerId)) {
    case 'codex':
      return 'gpt-5.4-mini';
    case 'gemini':
      return 'gemini-2.5-flash-lite';
    case 'anthropic':
    default:
      return 'haiku';
  }
}

export function buildProviderPreflightPingArgs(providerId: TeamProviderId | undefined): string[] {
  return buildProviderModelProbeArgs(getProviderPreflightModel(providerId));
}
