import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { ReferralReward, RewardStatus, RewardType, TriggerType } from '../../domain/entities/referral-reward.entity';

@Injectable()
export class ReferralRewardRepository {
  private readonly repo: Repository<ReferralReward>;

  constructor(private readonly dataSource: DataSource) {
    this.repo = this.dataSource.getRepository(ReferralReward);
  }

  async findPendingByTenant(beneficiaryTenantId: string): Promise<ReferralReward[]> {
    return this.repo.find({
      where: { beneficiaryTenantId, status: 'PENDING' },
      order: { createdAt: 'ASC' },
    });
  }

  async findAllByTenant(
    beneficiaryTenantId: string,
    status?: RewardStatus,
    limit = 20,
    offset = 0,
  ): Promise<{ items: ReferralReward[]; total: number }> {
    const where: any = { beneficiaryTenantId };
    if (status) where.status = status;
    const [items, total] = await this.repo.findAndCount({
      where,
      order: { createdAt: 'DESC' },
      take: limit,
      skip: offset,
    });
    return { items, total };
  }

  async findAll(
    status?: RewardStatus,
    limit = 50,
    offset = 0,
  ): Promise<{ items: ReferralReward[]; total: number }> {
    const where = status ? { status } : {};
    const [items, total] = await this.repo.findAndCount({
      where,
      order: { createdAt: 'DESC' },
      take: limit,
      skip: offset,
    });
    return { items, total };
  }

  async create(params: {
    beneficiaryTenantId: string;
    referralRelationshipId: string;
    rewardType: RewardType;
    triggerType: TriggerType;
    amountCents: number;
    sourceInvoiceId?: string;
    recurringMonth?: number;
  }): Promise<ReferralReward> {
    const entity = this.repo.create({
      ...params,
      status: 'PENDING',
    });
    return this.repo.save(entity);
  }

  async markApplied(id: string, invoiceId: string): Promise<void> {
    await this.repo.update(id, {
      status: 'APPLIED',
      invoiceId,
      appliedAt: new Date(),
    });
  }

  async countRecurringByRelationship(referralRelationshipId: string): Promise<number> {
    return this.repo.count({
      where: { referralRelationshipId, triggerType: 'RECURRING' },
    });
  }

  async sumPendingCents(beneficiaryTenantId: string): Promise<number> {
    const result = await this.repo
      .createQueryBuilder('r')
      .select('COALESCE(SUM(r.amount_cents), 0)', 'total')
      .where('r.beneficiary_tenant_id = :id AND r.status = :status', {
        id: beneficiaryTenantId,
        status: 'PENDING',
      })
      .getRawOne();
    return parseInt(result?.total ?? '0', 10);
  }
}
