import { Injectable, Logger, NotFoundException, ForbiddenException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { AIGatewayService } from '../ai/ai-gateway.service';

@Injectable()
export class PracticesService {
  private readonly logger = new Logger(PracticesService.name);

  constructor(
    private prisma: PrismaService,
    private ai: AIGatewayService,
  ) {}

  async findAll(query: { category?: string; difficulty?: string; search?: string; skillId?: string }) {
    const where: any = { status: 'PUBLISHED' };

    if (query.category) where.category = query.category;
    if (query.difficulty) where.difficulty = query.difficulty;
    if (query.skillId) where.skillId = query.skillId;
    if (query.search) {
      where.OR = [
        { title: { contains: query.search } },
        { description: { contains: query.search } },
      ];
    }

    const items = await this.prisma.practiceQuestion.findMany({
      where,
      orderBy: { sortOrder: 'asc' },
      select: {
        id: true,
        scenario: true,
        title: true,
        description: true,
        difficulty: true,
        category: true,
        sortOrder: true,
        attemptCount: true,
        createdAt: true,
      },
    });

    return { items, total: items.length };
  }

  async findById(id: number) {
    const question = await this.prisma.practiceQuestion.findUnique({
      where: { id },
    });

    if (!question) throw new NotFoundException('练习题目不存在');
    return question;
  }

  async getCategories() {
    const result = await this.prisma.practiceQuestion.findMany({
      where: { status: 'PUBLISHED' },
      select: { category: true },
      distinct: ['category'],
    });
    return result.map(r => r.category);
  }

  async getDifficulties() {
    const result = await this.prisma.practiceQuestion.findMany({
      where: { status: 'PUBLISHED' },
      select: { difficulty: true },
      distinct: ['difficulty'],
    });
    return result.map(r => r.difficulty);
  }

  async submitAnswer(userId: number, questionId: number, answer: string, duration: number = 0) {
    const question = await this.prisma.practiceQuestion.findUnique({
      where: { id: questionId },
    });

    if (!question) throw new NotFoundException('练习题目不存在');

    const existing = await this.prisma.practiceSubmission.findFirst({
      where: { userId, questionId, status: 'SUBMITTED' },
    });

    if (existing) throw new ForbiddenException('你已经提交过此练习的答案');

    const submission = await this.prisma.practiceSubmission.create({
      data: {
        userId,
        questionId,
        answer,
        duration,
        status: 'SUBMITTED',
      },
    });

    await this.prisma.practiceQuestion.update({
      where: { id: questionId },
      data: { attemptCount: { increment: 1 } },
    });

    try {
      const criteria = question.expectedCriteria;
      const scoringPrompt = this.buildScoringPrompt(question, answer, criteria);
      const aiResult = await this.ai.chat('deepseek-v4-flash', [
        { role: 'system', content: '你是一个专业的 AI 练习评分助手。请严格按照评分标准评估用户的回答，返回 JSON 格式的评分结果。' },
        { role: 'user', content: scoringPrompt },
      ], { temperature: 0.3 });

      const scoreData = this.parseScoreResult(aiResult);

      const updated = await this.prisma.practiceSubmission.update({
        where: { id: submission.id },
        data: {
          score: scoreData.totalScore,
          maxScore: 100,
          feedback: scoreData.feedback,
          criteriaScores: JSON.stringify(scoreData.criteria),
          status: 'SCORED',
          scoredAt: new Date(),
        },
      });

      return updated;
    } catch (err: any) {
      this.logger.error(`评分失败: ${err.message}`);
      return submission;
    }
  }

  async getUserSubmissions(userId: number, page: number = 1, limit: number = 20) {
    const skip = (page - 1) * limit;
    const [items, total] = await Promise.all([
      this.prisma.practiceSubmission.findMany({
        where: { userId },
        skip,
        take: limit,
        orderBy: { submittedAt: 'desc' },
        include: {
          question: {
            select: { id: true, title: true, scenario: true, difficulty: true, category: true },
          },
        },
      }),
      this.prisma.practiceSubmission.count({ where: { userId } }),
    ]);

    return { items, total, page, limit };
  }

  async getSubmissionDetail(userId: number, submissionId: number) {
    const submission = await this.prisma.practiceSubmission.findUnique({
      where: { id: submissionId },
      include: { question: true },
    });

    if (!submission) throw new NotFoundException('提交记录不存在');
    if (submission.userId !== userId) throw new ForbiddenException('无权查看此提交');

    return submission;
  }

  private buildScoringPrompt(question: any, answer: string, criteria: string): string {
    return `请根据以下场景和评分标准，评估用户的回答。

## 练习场景
${question.scenario}

## 练习要求
${question.instructions}

## 用户的回答
${answer}

## 评分标准
${criteria}

## 输出格式（必须返回纯 JSON，不要包含 markdown 代码块）
{
  "criteria": [
    { "name": "评分项名称", "score": 分数, "maxScore": 满分, "reason": "评分理由" }
  ],
  "totalScore": 总分,
  "feedback": "总体反馈和改进建议（50-200字）"
}`;
  }

  private parseScoreResult(aiResult: string): { criteria: any[]; totalScore: number; feedback: string } {
    try {
      const cleaned = aiResult.replace(/```json\s*/g, '').replace(/```\s*/g, '').trim();
      const parsed = JSON.parse(cleaned);
      return {
        criteria: parsed.criteria || [],
        totalScore: Math.min(100, Math.max(0, parsed.totalScore || 0)),
        feedback: parsed.feedback || '评分完成',
      };
    } catch {
      this.logger.warn(`AI 评分结果解析失败，使用默认评分: ${aiResult.slice(0, 100)}`);
      return {
        criteria: [{ name: '综合评分', score: 75, maxScore: 100, reason: 'AI 评分解析失败，已使用默认分数' }],
        totalScore: 75,
        feedback: 'AI 评分系统遇到临时问题，请稍后重新查看评分详情。',
      };
    }
  }
}
