import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { Logger } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { ReminderStatus } from '@prisma/client';

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

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

  async findAll(tenantId: string, status?: ReminderStatus) {
    const where: any = { tenantId };
    if (status) where.status = status;

    return this.prisma.reminder.findMany({
      where,
      orderBy: { nextMaintenanceDate: 'asc' },
      include: {
        client: { select: { id: true, name: true, phone: true, whatsapp: true } },
        order: { select: { number: true, serviceType: true } },
      },
    });
  }

  async getOverdue(tenantId: string) {
    return this.prisma.reminder.findMany({
      where: { tenantId, status: 'OVERDUE' },
      include: { client: { select: { id: true, name: true, phone: true, whatsapp: true } } },
      orderBy: { nextMaintenanceDate: 'asc' },
    });
  }

  async getToday(tenantId: string) {
    const start = new Date(); start.setHours(0, 0, 0, 0);
    const end = new Date(); end.setHours(23, 59, 59, 999);

    return this.prisma.reminder.findMany({
      where: { tenantId, status: 'PENDING', nextMaintenanceDate: { gte: start, lte: end } },
      include: { client: { select: { id: true, name: true, phone: true, whatsapp: true } } },
    });
  }

  async markDone(tenantId: string, id: string) {
    return this.prisma.reminder.update({
      where: { id },
      data: { status: 'DONE', resolvedAt: new Date() },
    });
  }

  @Cron(CronExpression.EVERY_DAY_AT_8AM)
  async processOverdueReminders() {
    this.logger.log('Processing overdue reminders...');

    const now = new Date();
    const updated = await this.prisma.reminder.updateMany({
      where: { status: 'PENDING', nextMaintenanceDate: { lt: now } },
      data: { status: 'OVERDUE' },
    });

    this.logger.log(`Marked ${updated.count} reminders as overdue`);

    const tenants = await this.prisma.reminder
      .findMany({ where: { status: 'OVERDUE' }, select: { tenantId: true }, distinct: ['tenantId'] });

    for (const { tenantId } of tenants) {
      const count = await this.prisma.reminder.count({ where: { tenantId, status: 'OVERDUE' } });
      if (count > 0) {
        await this.prisma.notification.create({
          data: {
            tenantId,
            title: 'Manutenções Vencidas',
            message: `Você tem ${count} cliente(s) com manutenção atrasada`,
            type: 'ALERT',
            data: { count },
          },
        });
        this.events.emit('notification.created', { tenantId });
      }
    }
  }
}
