import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { PrismaService } from '../common/prisma.service';
import { payableBalance, logEmail } from '../common/core';

/**
 * Auto-payout scheduler. Once a day it checks each merchant that enabled
 * scheduling; on their chosen day-of-month it creates a REQUESTED payout for
 * every affiliate whose payable balance clears the minimum — so the merchant
 * just processes a ready queue (no missed payments).
 */
@Injectable()
export class PayoutSchedulerService {
  private readonly log = new Logger('PayoutScheduler');

  constructor(private prisma: PrismaService) {}

  // Every day at 02:00 (server time).
  @Cron('0 2 * * *')
  async run(): Promise<void> {
    const today = new Date().getDate();
    const merchants = await this.prisma.merchant.findMany({
      where: { payoutScheduleEnabled: true, payoutScheduleDay: today },
    });
    for (const m of merchants) {
      const affiliates = await this.prisma.affiliate.findMany({
        where: { merchantId: m.id, status: 'ACTIVE', balance: { gt: 0 } },
      });
      let created = 0;
      for (const a of affiliates) {
        // Don't stack requests — skip if one is already pending.
        const pending = await this.prisma.payout.findFirst({
          where: { affiliateId: a.id, status: 'REQUESTED' },
        });
        if (pending) continue;
        const { payable } = await payableBalance(this.prisma, a, m.commissionHoldDays);
        if (payable < Number(m.minPayout)) continue;
        await this.prisma.payout.create({
          data: { merchantId: m.id, affiliateId: a.id, amount: payable, status: 'REQUESTED' },
        });
        await logEmail(this.prisma, m.id, a.email, 'payout', `Payout of ₹${payable} scheduled`);
        created++;
      }
      if (created) this.log.log(`scheduled ${created} payout(s) for ${m.shop}`);
    }
  }
}
