import { Injectable, Logger } from '@nestjs/common';
import { ReferralRewardRepository } from '../../infrastructure/repositories/referral-reward.repository';
import { ReferralStatRepository } from '../../infrastructure/repositories/referral-stat.repository';

export interface PendingCreditsResult {
  pendingCents: number;
  rewards: Array<{
    id: string;
    amountCents: number;
    triggerType: string;
    sourceInvoiceId: string | null;
    createdAt: Date;
  }>;
}

/**
 * Called by billing-service BEFORE generating an invoice to check available credits.
 * After applying, billing-service should call markCreditsApplied.
 */
@Injectable()
export class GetPendingCreditsUseCase {
  private readonly logger = new Logger(GetPendingCreditsUseCase.name);

  constructor(
    private readonly rewardRepo: ReferralRewardRepository,
    private readonly statRepo: ReferralStatRepository,
  ) {}

  async getPending(tenantId: string): Promise<PendingCreditsResult> {
    const rewards = await this.rewardRepo.findPendingByTenant(tenantId);
    const pendingCents = rewards.reduce((sum, r) => sum + r.amountCents, 0);
    return {
      pendingCents,
      rewards: rewards.map((r) => ({
        id: r.id,
        amountCents: r.amountCents,
        triggerType: r.triggerType,
        sourceInvoiceId: r.sourceInvoiceId,
        createdAt: r.createdAt,
      })),
    };
  }

  /**
   * Called by billing-service AFTER an invoice is issued,
   * to mark the credits as applied.
   */
  async markApplied(tenantId: string, invoiceId: string, appliedCents: number): Promise<void> {
    const rewards = await this.rewardRepo.findPendingByTenant(tenantId);
    let remaining = appliedCents;

    for (const reward of rewards) {
      if (remaining <= 0) break;
      await this.rewardRepo.markApplied(reward.id, invoiceId);
      remaining -= reward.amountCents;
    }

    await this.statRepo.markCreditApplied(tenantId, appliedCents);
    this.logger.log(`Applied ${appliedCents} cents credits for tenant ${tenantId} on invoice ${invoiceId}`);
  }
}
