'use strict';

const {
  SETUP_PROVIDER_TYPES,
  sanitizeSetupProviderType,
} = require('./setup-provider-config');

const ROUTING_PROVIDER_ALIASES = Object.freeze({
  anthropicclaude: 'anthropic',
  googlegemini: 'google',
  gemini: 'google',
  ollamalocal: 'ollama',
  moonshotkimi: 'moonshot',
  kimi: 'moonshot',
});

function normalizeRoutingProviderType(value) {
  const sanitized = sanitizeSetupProviderType(value);
  if (!sanitized) return '';
  if (ROUTING_PROVIDER_ALIASES[sanitized]) return ROUTING_PROVIDER_ALIASES[sanitized];
  if (SETUP_PROVIDER_TYPES.includes(sanitized)) return sanitized;
  const prefix = SETUP_PROVIDER_TYPES.find((type) => sanitized.startsWith(type));
  if (prefix) return prefix;
  if (sanitized.includes('gemini')) return 'google';
  if (sanitized.includes('kimi')) return 'moonshot';
  return sanitized;
}

function currentDefaultProviderType(status = {}, env = process.env) {
  return normalizeRoutingProviderType(
    status.walle_provider
      || status.default_provider
      || status.provider
      || env.WALLE_PROVIDER
      || ''
  );
}

function routingNoticeFromProviderType(notice = {}) {
  return normalizeRoutingProviderType(
    notice.from && (notice.from.type || notice.from.provider || notice.from.provider_type)
  );
}

function providerTaskOverrideScopes(defaultsPayload = {}, providerType = '') {
  const normalizedProvider = normalizeRoutingProviderType(providerType);
  if (!normalizedProvider) return [];
  const defaults = Array.isArray(defaultsPayload.defaults) ? defaultsPayload.defaults : [];
  const scopes = [];
  for (const row of defaults) {
    if (!row || !row.model_registry_id) continue;
    const rowProvider = normalizeRoutingProviderType(row.provider_type || String(row.model_registry_id).split(':')[0]);
    if (rowProvider === normalizedProvider && row.task_type) scopes.push(String(row.task_type));
  }
  return Array.from(new Set(scopes)).sort();
}

function _titleCaseTaskScope(scope) {
  return String(scope || '')
    .split(/[-_\s]+/)
    .filter(Boolean)
    .map((part) => part.slice(0, 1).toUpperCase() + part.slice(1))
    .join(' ');
}

function _providerDisplayName(providerType) {
  const normalized = normalizeRoutingProviderType(providerType);
  if (normalized === 'anthropic') return 'Anthropic';
  if (normalized === 'openai') return 'OpenAI';
  if (normalized === 'google') return 'Google Gemini';
  if (normalized === 'moonshot') return 'Moonshot / Kimi';
  if (normalized === 'ollama') return 'Ollama';
  if (normalized === 'deepseek') return 'DeepSeek';
  return normalized ? normalized.slice(0, 1).toUpperCase() + normalized.slice(1) : 'provider';
}

function _taskOverrideNoticeMessage(notice = {}, providerType = '', scopes = []) {
  const taskLabel = scopes.length === 1
    ? `${_titleCaseTaskScope(scopes[0])} task override`
    : `${scopes.map(_titleCaseTaskScope).join(', ')} task overrides`;
  const target = notice.to && (notice.to.label || notice.to.id);
  const provider = _providerDisplayName(providerType);
  if (target) return `${taskLabel} provider "${provider}" is unreachable — answering via "${target}" until it recovers.`;
  return `${taskLabel} provider "${provider}" is unreachable.`;
}

function sanitizeModelsHealthRoutingNotice(health = {}, status = {}, env = process.env, defaultsPayload = {}) {
  if (!health || typeof health !== 'object') return health;
  const notice = health.routingNotice;
  if (!notice || typeof notice !== 'object') return health;
  if (notice.kind === 'unreachable') return health;

  const noticeProvider = routingNoticeFromProviderType(notice);
  const currentProvider = currentDefaultProviderType(status, env);
  if (!noticeProvider || !currentProvider || noticeProvider === currentProvider) return health;

  const taskScopes = providerTaskOverrideScopes(defaultsPayload, noticeProvider);
  if (taskScopes.length) {
    return {
      ...health,
      routingNotice: {
        ...notice,
        scope: 'task_override',
        task_types: taskScopes,
        message: _taskOverrideNoticeMessage(notice, noticeProvider, taskScopes),
      },
    };
  }

  const sanitized = { ...health };
  delete sanitized.routingNotice;
  sanitized.routingNoticeSuppressed = {
    reason: 'stale_default_provider',
    stale_provider: noticeProvider,
    current_provider: currentProvider,
  };
  return sanitized;
}

module.exports = {
  currentDefaultProviderType,
  normalizeRoutingProviderType,
  providerTaskOverrideScopes,
  routingNoticeFromProviderType,
  sanitizeModelsHealthRoutingNotice,
};
