import {
  Injectable,
  NotFoundException,
  BadRequestException,
  Logger,
} from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { PrismaService } from '../../database/prisma.service';
import { RewardEngine } from '../time-wallet/reward-engine.service';
import { RequestStatus, TransactionType } from '@prisma/client';

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

  constructor(
    private readonly prisma: PrismaService,
    private readonly rewardEngine: RewardEngine,
    private readonly events: EventEmitter2,
  ) {}

  async createRequest(
    childId: string,
    requestedMin: number,
    reasonCode?: string,
    reason?: string,
  ) {
    // Verificar limite: máximo 3 pedidos pendentes
    const pendingCount = await this.prisma.timeRequest.count({
      where: { childId, status: RequestStatus.PENDING },
    });
    if (pendingCount >= 3) {
      throw new BadRequestException('Máximo de pedidos pendentes atingido');
    }

    const expiresAt = new Date();
    expiresAt.setHours(expiresAt.getHours() + 2);

    const request = await this.prisma.timeRequest.create({
      data: { childId, requestedMin, reasonCode, reason, expiresAt },
    });

    // Emitir evento para notificação em tempo real
    this.events.emit('time-request.created', { request, childId });
    this.logger.log(`[TimeRequest] Nova solicitação: ${childId} → ${requestedMin}min`);

    return request;
  }

  async respondToRequest(
    requestId: string,
    guardianId: string,
    action: 'approved' | 'denied',
    responseMin?: number,
    message?: string,
  ) {
    const request = await this.prisma.timeRequest.findUnique({
      where: { id: requestId },
      include: { child: true },
    });

    if (!request) throw new NotFoundException('Solicitação não encontrada');
    if (request.status !== RequestStatus.PENDING) {
      throw new BadRequestException('Solicitação já respondida');
    }

    if (action === 'approved') {
      const approvedMin = responseMin ?? request.requestedMin;

      await this.prisma.timeRequest.update({
        where: { id: requestId },
        data: {
          status: RequestStatus.APPROVED,
          responseMin: approvedMin,
          respondedBy: guardianId,
          respondedAt: new Date(),
          message,
        },
      });

      // Creditar tempo
      await this.rewardEngine.credit({
        childId: request.childId,
        minutes: approvedMin,
        type: TransactionType.PARENT_BONUS,
        description: `Tempo extra aprovado pelo responsável`,
        referenceId: requestId,
        idempotencyKey: `request-approved-${requestId}`,
        metadata: { guardianId, requestId, originalRequest: request.requestedMin },
      });

      this.events.emit('time-request.approved', { requestId, childId: request.childId, minutes: approvedMin });
    } else {
      await this.prisma.timeRequest.update({
        where: { id: requestId },
        data: {
          status: RequestStatus.DENIED,
          respondedBy: guardianId,
          respondedAt: new Date(),
          message,
        },
      });

      this.events.emit('time-request.denied', { requestId, childId: request.childId });
    }

    return this.prisma.timeRequest.findUnique({ where: { id: requestId } });
  }

  async getChildRequests(childId: string) {
    return this.prisma.timeRequest.findMany({
      where: { childId },
      orderBy: { createdAt: 'desc' },
      take: 20,
    });
  }

  async getPendingRequestsForGuardian(guardianUserId: string) {
    // Buscar todos os filhos do guardião
    const guardian = await this.prisma.guardian.findFirst({
      where: { familyMember: { userId: guardianUserId } },
      include: { managedChildren: { include: { child: true } } },
    });

    if (!guardian) return [];

    const childIds = guardian.managedChildren.map((c) => c.childId);

    return this.prisma.timeRequest.findMany({
      where: { childId: { in: childIds }, status: RequestStatus.PENDING },
      include: {
        child: { include: { familyMember: { include: { user: true } } } },
      },
      orderBy: { createdAt: 'desc' },
    });
  }
}
