import type { DrizzleClient } from '@/server/db/client.js';
import { buildChainedProvider } from '@/server/ai/providers/chained.js';
import type { ChainedLlmProvider } from '@/server/ai/providers/chained.js';
import { getLlmQueue } from '@/server/db/queries/llm-queues.js';
import type { LlmQueueId } from '@/server/db/queries/llm-queues.js';
import type { LlmJobType } from '@/server/ai/llm.js';

export interface AiCredentials {
  apiKey: string;
}

/**
 * Permanent queue misconfiguration (queue row missing, or chain empty). Distinct
 * from a transient DB/provider failure: retrying an unconfigured queue can never
 * succeed, so the runner treats this as terminal + escalates immediately.
 */
export class LlmQueueConfigError extends Error {
  constructor(
    readonly code: 'LLM_QUEUE_NOT_FOUND' | 'LLM_QUEUE_EMPTY',
    readonly queueId: string,
  ) {
    super(`${code}: ${queueId}`);
    this.name = 'LlmQueueConfigError';
  }
}

const JOB_TYPE_TO_QUEUE: Record<LlmJobType, LlmQueueId> = {
  DEAL_MODERATION: 'moderation',
  IMAGE_APPROVAL: 'moderation',
  VENDOR_VIOLATION: 'moderation',
  REVIEW_PRESCORING: 'moderation',
  TRANSLATION: 'translation',
};

export async function resolveQueueForJobType(
  db: DrizzleClient,
  piiKey: string,
  jobType: LlmJobType,
  chainOverride?: Array<{ llmProviderId: string; model: string }> | null,
): Promise<{ provider: ChainedLlmProvider; model: string }> {
  const queueId = JOB_TYPE_TO_QUEUE[jobType];
  if (chainOverride) {
    const firstEntry = chainOverride[0];
    if (!firstEntry) throw new LlmQueueConfigError('LLM_QUEUE_EMPTY', queueId);
    const provider = await buildChainedProvider(db, piiKey, { chain: chainOverride });
    return { provider, model: firstEntry.model };
  }
  const queue = await getLlmQueue(db, queueId);
  if (!queue) throw new LlmQueueConfigError('LLM_QUEUE_NOT_FOUND', queueId);
  if (!queue.chain || queue.chain.length === 0)
    throw new LlmQueueConfigError('LLM_QUEUE_EMPTY', queueId);
  const firstEntry = queue.chain[0];
  if (!firstEntry) throw new LlmQueueConfigError('LLM_QUEUE_EMPTY', queueId);
  const provider = await buildChainedProvider(db, piiKey, { chain: queue.chain });
  return { provider, model: firstEntry.model };
}
