import { Injectable } from "@nestjs/common";
import { Cron } from "@nestjs/schedule";
import { InjectModel } from "@nestjs/mongoose";
import { Model } from "mongoose";
import { AlertsService } from "src/alerts/alerts.service";
import { AlertType } from "src/alerts/alert.types";
import { Invoice } from "../schema/invoice.schema";
import { InvoiceStatus } from "src/common/constant/enum.constant";
// import { EmailService } from "src/email/email.service";
@Injectable()
export class InvoiceCronService {
  constructor(
    @InjectModel(Invoice.name)
    private readonly invoiceModel: Model<Invoice>,
    private readonly alertsService: AlertsService,
    // private readonly emailService: EmailService,
  ) {}

  /**
   * Runs every day at 9 AM
   */
  @Cron("* 9 * * *")
  async handleInvoiceDueAndOverdue() {
    const todayStart = new Date();
    todayStart.setHours(0, 0, 0, 0);

    const todayEnd = new Date();
    todayEnd.setHours(23, 59, 59, 999);

    await this.sendDueInvoices(todayStart, todayEnd);
    await this.sendOverdueInvoices(todayStart);
  }

  /**
   * Invoice Due Today
   */
  private async sendDueInvoices(todayStart: Date, todayEnd: Date) {
    const invoices = await this.invoiceModel
      .find({
        isPaid: false,
        dueAlertSent: { $ne: true },
        dueDate: {
          $gte: todayStart,
          $lte: todayEnd,
        },
      })
    
    for (const invoice of invoices) {
      await this.alertsService.sendAlert(
        invoice.userId.toString(),
        AlertType.INVOICE_DUE,
        "Invoice due today",
        `Invoice #${invoice.invoiceNo} is due today`,
        {
          invoiceId: invoice._id.toString(),
        },
      );

      // await this.emailService.sendInvoiceDueTodayEmailToCustomer({clientName});

      await this.invoiceModel.updateOne(
        { _id: invoice._id },
        { $set: { dueAlertSent: true } },
      );
    }
  }

  /**
   * Invoice Overdue
   */
  private async sendOverdueInvoices(todayStart: Date) {
    const invoices = await this.invoiceModel.find({
      isPaid: false,
      overdueAlertSent: { $ne: true },
      dueDate: { $lt: todayStart },
    });

    for (const invoice of invoices) {
      await this.alertsService.sendAlert(
        invoice.userId.toString(),
        AlertType.INVOICE_OVERDUE,
        "Invoice overdue",
        `Invoice #${invoice.invoiceNo} is overdue`,
        {
          invoiceId: invoice._id.toString(),
        },
      );

      await this.invoiceModel.updateOne(
        { _id: invoice._id },
        { $set: { overdueAlertSent: true } },
      );
    }
  }

  @Cron("* * * * *")
  async updateInvoiceStatuses() {
    const now = new Date();

    const invoices = await this.invoiceModel.find({
      where: {
        status: {
          $in: [
            InvoiceStatus.SENT,
            // InvoiceStatus.UNPAID,
            // InvoiceStatus.OVERDUE,
          ],
        },
      },
    });
    for (const invoice of invoices) {
      let nextStatus: InvoiceStatus | null = null;

      if (now < invoice.dueDate) {
        nextStatus = InvoiceStatus.SENT;
      } else if (now >= invoice.dueDate) {
        // nextStatus = InvoiceStatus.UNPAID;
      }

      // If already UNPAID for long → OVERDUE
      // if (invoice.status === InvoiceStatus.UNPAID && now > invoice.dueDate) {
      //   nextStatus = InvoiceStatus.OVERDUE;
      // }

      if (nextStatus && nextStatus !== invoice.status) {
        await this.invoiceModel.updateOne(
          { _id: invoice._id },
          { $set: { status: nextStatus } },
        );
      }
    }
  }
}
