import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from '../../database/prisma.service';

export interface GenerateMissionInput {
  subject: string;
  topic: string;
  ageYears?: number;
  difficultyLevel?: number;
  numQuestions?: number;
}

export interface GeneratedMission {
  title: string;
  description: string;
  estimatedMinutes: number;
  rewardMinutes: number;
  lessons: Array<{
    title: string;
    content: string;
    questions: Array<{
      type: string;
      stem: string;
      explanation: string;
      options: Array<{ text: string; isCorrect: boolean }>;
    }>;
  }>;
}

export interface TutorMessage {
  role: 'user' | 'assistant';
  content: string;
}

@Injectable()
export class AiProviderService {
  private readonly logger = new Logger(AiProviderService.name);
  private readonly provider: string;

  constructor(
    private readonly config: ConfigService,
    private readonly prisma: PrismaService,
  ) {
    this.provider = config.get<string>('ai.provider', 'mock');
    this.logger.log(`AI Provider: ${this.provider}`);
  }

  async generateMission(input: GenerateMissionInput, createdBy: string): Promise<GeneratedMission> {
    const generation = await this.prisma.aiGeneration.create({
      data: {
        provider: this.provider,
        prompt: JSON.stringify(input),
        outputType: 'mission',
        status: 'processing',
        createdBy,
      },
    });

    const start = Date.now();
    let result: GeneratedMission;

    try {
      result = await this.callProvider_generateMission(input);

      await this.prisma.aiGeneration.update({
        where: { id: generation.id },
        data: {
          response: result as any,
          status: 'completed',
          durationMs: Date.now() - start,
        },
      });
    } catch (err: any) {
      await this.prisma.aiGeneration.update({
        where: { id: generation.id },
        data: { status: 'failed', error: err.message },
      });
      throw err;
    }

    return result;
  }

  async tutorHint(
    question: string,
    context: string,
    ageYears: number,
    history: TutorMessage[],
  ): Promise<string> {
    if (this.provider === 'mock') {
      return this.mockTutorHint(question, context);
    }

    if (this.provider === 'anthropic') {
      return this.anthropicTutor(question, context, ageYears, history);
    }

    return this.mockTutorHint(question, context);
  }

  async generateWeeklySummary(childId: string, stats: any): Promise<string> {
    if (this.provider === 'mock') {
      return this.mockWeeklySummary(stats);
    }
    return this.mockWeeklySummary(stats);
  }

  // ─── Implementações dos provedores ───────────────────────────────────────────

  private async callProvider_generateMission(input: GenerateMissionInput): Promise<GeneratedMission> {
    if (this.provider === 'mock') return this.mockMission(input);
    if (this.provider === 'anthropic') return this.anthropicMission(input);
    if (this.provider === 'openai') return this.openaiMission(input);
    return this.mockMission(input);
  }

  private mockMission(input: GenerateMissionInput): GeneratedMission {
    const numQ = input.numQuestions ?? 3;
    return {
      title: `${input.topic} — Nível ${input.difficultyLevel ?? 1}`,
      description: `Explore conceitos de ${input.topic} em ${input.subject}.`,
      estimatedMinutes: 10,
      rewardMinutes: 10,
      lessons: [
        {
          title: `Introdução a ${input.topic}`,
          content: `## ${input.topic}\n\nVamos aprender sobre **${input.topic}**!\n\nEste é um conceito importante de ${input.subject} que usamos no dia a dia.`,
          questions: Array.from({ length: numQ }, (_, i) => ({
            type: 'MULTIPLE_CHOICE',
            stem: `Questão ${i + 1}: Sobre ${input.topic}…`,
            explanation: `A alternativa correta é a primeira porque representa corretamente ${input.topic}.`,
            options: [
              { text: 'Alternativa correta', isCorrect: true },
              { text: 'Alternativa errada A', isCorrect: false },
              { text: 'Alternativa errada B', isCorrect: false },
              { text: 'Alternativa errada C', isCorrect: false },
            ],
          })),
        },
      ],
    };
  }

  private async anthropicMission(input: GenerateMissionInput): Promise<GeneratedMission> {
    const apiKey = this.config.get<string>('ai.anthropicApiKey');
    if (!apiKey) throw new Error('ANTHROPIC_API_KEY não configurado');

    const prompt = this.buildMissionPrompt(input);

    const response = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey,
        'anthropic-version': '2023-06-01',
      },
      body: JSON.stringify({
        model: 'claude-3-5-haiku-20241022',
        max_tokens: 4096,
        messages: [{ role: 'user', content: prompt }],
      }),
    });

    const data = await response.json() as any;
    const text = data.content?.[0]?.text ?? '';

    try {
      const cleaned = text.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim();
      return JSON.parse(cleaned) as GeneratedMission;
    } catch {
      this.logger.error('Falha ao parsear resposta da IA', text);
      return this.mockMission(input);
    }
  }

  private async openaiMission(input: GenerateMissionInput): Promise<GeneratedMission> {
    const apiKey = this.config.get<string>('ai.openaiApiKey');
    if (!apiKey) throw new Error('OPENAI_API_KEY não configurado');

    const prompt = this.buildMissionPrompt(input);

    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model: 'gpt-4o-mini',
        messages: [
          { role: 'system', content: 'Você é um especialista em educação infantil. Responda APENAS com JSON válido.' },
          { role: 'user', content: prompt },
        ],
        response_format: { type: 'json_object' },
      }),
    });

    const data = await response.json() as any;
    const text = data.choices?.[0]?.message?.content ?? '{}';

    try {
      return JSON.parse(text) as GeneratedMission;
    } catch {
      return this.mockMission(input);
    }
  }

  private buildMissionPrompt(input: GenerateMissionInput): string {
    return `Crie uma missão educacional para crianças de ${input.ageYears ?? 10} anos sobre "${input.topic}" em "${input.subject}".

Retorne APENAS um JSON válido com esta estrutura exata:
{
  "title": "string",
  "description": "string (1-2 frases)",
  "estimatedMinutes": number,
  "rewardMinutes": number,
  "lessons": [{
    "title": "string",
    "content": "string (markdown, explicação do conteúdo)",
    "questions": [{
      "type": "MULTIPLE_CHOICE",
      "stem": "string (pergunta)",
      "explanation": "string (explicação da resposta correta)",
      "options": [
        {"text": "string", "isCorrect": true},
        {"text": "string", "isCorrect": false},
        {"text": "string", "isCorrect": false},
        {"text": "string", "isCorrect": false}
      ]
    }]
  }]
}

Crie ${input.numQuestions ?? 3} questões. Nível de dificuldade: ${input.difficultyLevel ?? 1}/5.
Use linguagem adequada para a faixa etária. Não forneça a resposta diretamente na pergunta.`;
  }

  private async anthropicTutor(
    question: string,
    context: string,
    ageYears: number,
    history: TutorMessage[],
  ): Promise<string> {
    const apiKey = this.config.get<string>('ai.anthropicApiKey');
    if (!apiKey) return this.mockTutorHint(question, context);

    const systemPrompt = `Você é um tutor educacional para crianças de ${ageYears} anos.
Regras:
- Use linguagem simples e encorajadora
- Dê DICAS, não a resposta direta
- Faça perguntas de volta para guiar o raciocínio
- Fique restrito ao conteúdo educacional
- Respostas curtas (máx 3 frases)
- Contexto da questão: ${context}`;

    const messages = [
      ...history.map((m) => ({ role: m.role, content: m.content })),
      { role: 'user' as const, content: question },
    ];

    const response = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey,
        'anthropic-version': '2023-06-01',
      },
      body: JSON.stringify({
        model: 'claude-3-5-haiku-20241022',
        max_tokens: 300,
        system: systemPrompt,
        messages,
      }),
    });

    const data = await response.json() as any;
    return data.content?.[0]?.text ?? this.mockTutorHint(question, context);
  }

  private mockTutorHint(question: string, context: string): string {
    const hints = [
      'Pense bem na pergunta! Você já viu algo parecido antes?',
      'Tente eliminar as alternativas que você tem certeza que estão erradas.',
      'Releia o conteúdo com atenção — a resposta está lá!',
      'Que tal pensar em exemplos do dia a dia para ajudar?',
      'Você está no caminho certo! Pense passo a passo.',
    ];
    return hints[Math.floor(Math.random() * hints.length)];
  }

  private mockWeeklySummary(stats: any): string {
    const name = stats.childName ?? 'A criança';
    const entertainment = stats.entertainmentMinutes ?? 0;
    const study = stats.studyMinutes ?? 0;
    const missions = stats.missionsCompleted ?? 0;
    return `${name} utilizou ${entertainment} minutos de entretenimento esta semana e completou ${missions} missão(ões) educacional(is), acumulando ${study} minutos de estudo. Continue incentivando atividades educacionais para desbloquear mais tempo livre!`;
  }
}
