import axios, { AxiosError } from 'axios';
import { env } from '../../config/env';
import { logger } from '../../config/logger';
import { AppError } from '../../utils/AppError';

export type AiRole = 'system' | 'user' | 'assistant' | 'tool';

export interface AiMessage {
  role: AiRole;
  content: string;
}

interface OllamaResponse {
  message?: {
    role: string;
    content: string;
  };
}

export class OllamaClient {
  async chat(messages: AiMessage[]): Promise<string> {
    const startedAt = Date.now();

    try {
      logger.info({ model: env.OLLAMA_MODEL, messages }, 'Sending prompt to Ollama');
      const response = await axios.post<OllamaResponse>(
        env.OLLAMA_URL,
        {
          model: env.OLLAMA_MODEL,
          messages,
          stream: false,
        },
        {
          timeout: env.OLLAMA_TIMEOUT_MS,
          headers: {
            'Content-Type': 'application/json',
          },
        },
      );

      const content = response.data.message?.content;
      if (!content) {
        throw new AppError('Ollama returned an empty message.', 502, 'OLLAMA_EMPTY_RESPONSE', response.data);
      }

      logger.info({ durationMs: Date.now() - startedAt }, 'Ollama response received');
      return content;
    } catch (error) {
      if (error instanceof AppError) {
        throw error;
      }

      if (error instanceof AxiosError) {
        throw new AppError('Failed to communicate with Ollama.', 503, 'OLLAMA_UNAVAILABLE', {
          code: error.code,
          timeoutMs: env.OLLAMA_TIMEOUT_MS,
          status: error.response?.status,
          data: error.response?.data,
        });
      }

      throw error;
    }
  }
}
