import {
  AgentConfigStatus,
  AgentProviderKind,
  AgentProviderStatuses,
  AgentTaskRoute,
  ProviderConfigStatus,
  TASK_PROFILES,
  TaskProfile,
} from '../types/agentSettings';

const DEFAULT_PROVIDER: ProviderConfigStatus = {
  enabled: false,
  configured: false,
  baseUrl: '',
  defaultModel: '',
  hasApiKey: false,
};

const DEFAULT_REMOTE_PROVIDER: ProviderConfigStatus = {
  ...DEFAULT_PROVIDER,
  enabled: true,
};

const DEFAULT_TASK_ROUTE: AgentTaskRoute = {
  provider: 'remote',
  model: '',
};

export const createDefaultAgentConfigStatus = (): AgentConfigStatus => ({
  configured: false,
  providers: {
    remote: { ...DEFAULT_REMOTE_PROVIDER },
    ollama: { ...DEFAULT_PROVIDER },
  },
  taskDefaults: TASK_PROFILES.reduce(
    (routes, profile) => ({
      ...routes,
      [profile]: { ...DEFAULT_TASK_ROUTE },
    }),
    {} as Record<TaskProfile, AgentTaskRoute>,
  ),
  hasSecEdgarUserAgent: false,
  secEdgarUserAgent: '',
});

const isObject = (value: unknown): value is Record<string, unknown> =>
  Boolean(value) && typeof value === 'object';

const isProviderKind = (value: unknown): value is AgentProviderKind =>
  value === 'remote' || value === 'ollama';

const sanitizeProviderConfig = (
  provider: unknown,
  defaults: ProviderConfigStatus,
): ProviderConfigStatus => {
  if (!isObject(provider)) {
    return { ...defaults };
  }

  return {
    enabled:
      typeof provider.enabled === 'boolean' ? provider.enabled : defaults.enabled,
    configured:
      typeof provider.configured === 'boolean'
        ? provider.configured
        : defaults.configured,
    baseUrl:
      typeof provider.baseUrl === 'string' ? provider.baseUrl : defaults.baseUrl,
    defaultModel:
      typeof provider.defaultModel === 'string'
        ? provider.defaultModel
        : defaults.defaultModel,
    hasApiKey:
      typeof provider.hasApiKey === 'boolean'
        ? provider.hasApiKey
        : defaults.hasApiKey,
  };
};

const sanitizeTaskRoute = (route: unknown): AgentTaskRoute => {
  if (!isObject(route)) {
    return { ...DEFAULT_TASK_ROUTE };
  }

  return {
    provider: isProviderKind(route.provider) ? route.provider : 'remote',
    model: typeof route.model === 'string' ? route.model : '',
  };
};

export const sanitizeAgentConfigStatus = (
  status: unknown,
): AgentConfigStatus => {
  const defaults = createDefaultAgentConfigStatus();
  if (!isObject(status)) {
    return defaults;
  }

  const providers = isObject(status.providers) ? status.providers : {};
  const taskDefaults = isObject(status.taskDefaults) ? status.taskDefaults : {};

  return {
    configured:
      typeof status.configured === 'boolean'
        ? status.configured
        : defaults.configured,
    providers: {
      remote: sanitizeProviderConfig(
        providers.remote,
        DEFAULT_REMOTE_PROVIDER,
      ),
      ollama: sanitizeProviderConfig(providers.ollama, DEFAULT_PROVIDER),
    },
    taskDefaults: TASK_PROFILES.reduce(
      (routes, profile) => ({
        ...routes,
        [profile]: sanitizeTaskRoute(taskDefaults[profile]),
      }),
      {} as Record<TaskProfile, AgentTaskRoute>,
    ),
    hasSecEdgarUserAgent:
      typeof status.hasSecEdgarUserAgent === 'boolean'
        ? status.hasSecEdgarUserAgent
        : defaults.hasSecEdgarUserAgent,
    secEdgarUserAgent:
      typeof status.secEdgarUserAgent === 'string'
        ? status.secEdgarUserAgent
        : defaults.secEdgarUserAgent,
  };
};

const isProviderConfigStatus = (
  provider: unknown,
): provider is ProviderConfigStatus => {
  if (!isObject(provider)) {
    return false;
  }

  return (
    typeof provider.enabled === 'boolean' &&
    typeof provider.configured === 'boolean' &&
    typeof provider.baseUrl === 'string' &&
    typeof provider.defaultModel === 'string' &&
    typeof provider.hasApiKey === 'boolean'
  );
};

const isAgentProviderStatuses = (
  providers: unknown,
): providers is AgentProviderStatuses => {
  if (!isObject(providers)) {
    return false;
  }

  return (
    isProviderConfigStatus(providers.remote) &&
    isProviderConfigStatus(providers.ollama)
  );
};

const isTaskRoute = (route: unknown): route is AgentTaskRoute => {
  if (!isObject(route)) {
    return false;
  }

  return isProviderKind(route.provider) && typeof route.model === 'string';
};

export function assertAgentConfigStatus(
  status: unknown,
): asserts status is AgentConfigStatus {
  if (!isObject(status)) {
    throw new Error('Invalid AgentConfigStatus: expected object');
  }

  if (typeof status.configured !== 'boolean') {
    throw new Error('Invalid AgentConfigStatus: configured must be a boolean');
  }

  if (!isAgentProviderStatuses(status.providers)) {
    throw new Error('Invalid AgentConfigStatus: providers are malformed');
  }

  if (!isObject(status.taskDefaults)) {
    throw new Error('Invalid AgentConfigStatus: taskDefaults must be an object');
  }

  for (const profile of TASK_PROFILES) {
    if (!isTaskRoute(status.taskDefaults[profile])) {
      throw new Error(
        `Invalid AgentConfigStatus: taskDefaults.${profile} is malformed`,
      );
    }
  }

  if (typeof status.hasSecEdgarUserAgent !== 'boolean') {
    throw new Error(
      'Invalid AgentConfigStatus: hasSecEdgarUserAgent must be a boolean',
    );
  }

  if (typeof status.secEdgarUserAgent !== 'string') {
    throw new Error(
      'Invalid AgentConfigStatus: secEdgarUserAgent must be a string',
    );
  }
}
