import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { PrismaService } from '../../database/prisma.service';
import { MissionStatus, MissionType } from '@prisma/client';

@Injectable()
export class MissionsService {
  constructor(private readonly prisma: PrismaService) {}

  async listPublished(childId?: string, subjectId?: string) {
    const missions = await this.prisma.mission.findMany({
      where: {
        status: MissionStatus.PUBLISHED,
        ...(subjectId && { subjectId }),
      },
      include: {
        subject: true,
        assignments: childId
          ? { where: { childId }, select: { status: true, completedAt: true } }
          : false,
      },
      orderBy: [{ difficultyLevel: 'asc' }, { createdAt: 'desc' }],
    });

    return missions;
  }

  async getMission(id: string) {
    const mission = await this.prisma.mission.findUnique({
      where: { id },
      include: {
        subject: true,
        lessons: {
          include: {
            questions: {
              include: {
                options: { orderBy: { sortOrder: 'asc' } },
                skills: { include: { skill: true } },
              },
              orderBy: { sortOrder: 'asc' },
            },
          },
          orderBy: { sortOrder: 'asc' },
        },
      },
    });

    if (!mission) throw new NotFoundException('Missão não encontrada');
    return mission;
  }

  async assignMission(childId: string, missionId: string, assignedBy: string) {
    const mission = await this.prisma.mission.findUnique({ where: { id: missionId } });
    if (!mission || mission.status !== MissionStatus.PUBLISHED) {
      throw new NotFoundException('Missão não encontrada ou não publicada');
    }

    // Verificar se já tem assignment ativo
    const existing = await this.prisma.missionAssignment.findFirst({
      where: {
        childId,
        missionId,
        status: { in: ['PENDING', 'IN_PROGRESS'] },
      },
    });

    if (existing) {
      throw new BadRequestException('Esta missão já está atribuída');
    }

    const expiresAt = new Date();
    expiresAt.setDate(expiresAt.getDate() + 7);

    return this.prisma.missionAssignment.create({
      data: {
        childId,
        missionId,
        expiresAt,
        assignedBy,
      },
      include: { mission: true },
    });
  }

  async getChildAssignments(childId: string) {
    return this.prisma.missionAssignment.findMany({
      where: { childId },
      include: {
        mission: { include: { subject: true } },
        attempts: { orderBy: { startedAt: 'desc' }, take: 1 },
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  async getSubjects() {
    return this.prisma.subject.findMany({
      where: { isActive: true },
      include: { skills: { where: { parentId: null } } },
      orderBy: { sortOrder: 'asc' },
    });
  }

  async getSkillProgress(childId: string) {
    return this.prisma.skillProgress.findMany({
      where: { childId },
      include: { skill: { include: { subject: true } } },
      orderBy: { domainPercent: 'desc' },
    });
  }
}
