import { getDb } from './db.js';
import { logger } from './logger.js';
import { Credential, Tenant } from './types.js';

export type RuntimeProvider = 'claude' | 'codex' | 'pi';

export function normalizeProvider(
  provider?: string | null,
): RuntimeProvider {
  if (!provider) {
    const row = getDb().prepare("SELECT value FROM router_state WHERE key = 'default_provider'").get() as { value: string } | undefined;
    return (row?.value as RuntimeProvider) || 'claude';
  }
  if (provider === 'codex') return 'codex';
  if (provider === 'pi') return 'pi';
  return 'claude';
}

export function getTenantProvider(tenant?: Tenant): RuntimeProvider {
  return normalizeProvider(tenant?.provider);
}

export function getDefaultModelForProvider(
  provider: RuntimeProvider,
  tenant?: Tenant,
): string {
  if (tenant?.model) return tenant.model;

  try {
    const row = getDb()
      .prepare("SELECT value FROM router_state WHERE key = 'default_model'")
      .get() as { value: string } | undefined;
    if (row?.value) {
      const model = row.value;
      if (provider === 'codex' && model.includes('gpt')) return model;
      if ((provider === 'claude' || provider === 'pi') && model.includes('claude')) return model;
    }
  } catch (err) {
    logger.error({ err }, 'Failed to fetch default_model from DB');
  }

  const fallback = provider === 'codex' ? 'gpt-5.2' : 'claude-sonnet-4-6'; // pi also defaults to claude-sonnet-4-6
  return fallback;
}

export function getRuntimeSessionDir(
  provider: RuntimeProvider,
): string {
  if (provider === 'codex') return '.codex';
  if (provider === 'pi') return '.pi';
  return '.claude';
}

export function getRuntimeCredentialEnvKeys(
  provider: RuntimeProvider,
  piBackend?: string,
): string[] {
  if (provider === 'codex') {
    return ['OPENAI_API_KEY', 'OPENAI_BASE_URL', 'CODEX_AUTH_JSON'];
  }
  if (provider === 'pi') {
    const backend = piBackend || 'anthropic';
    // All pi sessions can use PI_AUTH_JSON (pi's own auth.json) in addition to provider-specific env vars
    const base = ['PI_AUTH_JSON'];
    const openaiGroup = ['openai', 'openai-codex', 'azure-openai-responses', 'github-copilot', 'opencode', 'opencode-go', 'openrouter', 'vercel-ai-gateway'];
    const googleGroup = ['google', 'google-vertex', 'google-antigravity', 'google-gemini-cli'];
    if (openaiGroup.includes(backend)) return [...base, 'OPENAI_API_KEY', 'OPENAI_BASE_URL'];
    if (googleGroup.includes(backend)) return [...base, 'GEMINI_API_KEY'];
    if (backend === 'groq') return [...base, 'GROQ_API_KEY'];
    if (backend === 'mistral') return [...base, 'MISTRAL_API_KEY'];
    if (backend === 'xai') return [...base, 'XAI_API_KEY'];
    if (backend === 'amazon-bedrock') return [...base, 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION'];
    return [...base, 'CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY', 'ANTHROPIC_BASE_URL', 'ANTHROPIC_AUTH_TOKEN'];
  }
  return [
    'CLAUDE_CODE_OAUTH_TOKEN',
    'ANTHROPIC_API_KEY',
    'ANTHROPIC_BASE_URL',
    'ANTHROPIC_AUTH_TOKEN',
  ];
}


export function getTenantPiBackend(tenant?: Tenant): string {
  if (tenant?.pi_backend) return tenant.pi_backend;
  try {
    const row = getDb()
      .prepare("SELECT value FROM router_state WHERE key = 'default_pi_backend'")
      .get() as { value: string } | undefined;
    if (row?.value) return row.value;
  } catch { /* ignore */ }
  return 'anthropic';
}

export function getPiCredentialPoolProvider(piBackend: string): RuntimeProvider {
  // OAuth-based backends: need a pi auth.json credential
  const piOAuthProviders = ['google-gemini-cli', 'google-antigravity', 'github-copilot', 'openai-codex'];
  if (piOAuthProviders.includes(piBackend)) return 'pi';
  // OpenAI API key group
  const openaiProviders = ['openai', 'azure-openai-responses', 'opencode', 'opencode-go', 'openrouter', 'vercel-ai-gateway'];
  if (openaiProviders.includes(piBackend)) return 'codex';
  // Everything else (anthropic, google, groq, mistral, xai, bedrock, etc.) uses claude credential slot
  return 'claude';
}

export function getCredentialProvider(
  credential?: Credential,
): RuntimeProvider {
  return normalizeProvider(credential?.provider);
}
