import { Injectable } from '@nestjs/common';
import { ReferralRelationshipRepository } from '../../infrastructure/repositories/referral-relationship.repository';
import { ReferralRewardRepository } from '../../infrastructure/repositories/referral-reward.repository';
import { ReferralRelationship } from '../../domain/entities/referral-relationship.entity';
import { ReferralReward } from '../../domain/entities/referral-reward.entity';

export interface ReferralItemDto {
  id: string;
  referredTenantId: string;
  referralCode: string;
  status: string;
  level: number;
  registeredAt: Date;
  activatedAt: Date | null;
}

export interface RewardItemDto {
  id: string;
  amountCents: number;
  amountFormatted: string;
  rewardType: string;
  triggerType: string;
  status: string;
  sourceInvoiceId: string | null;
  recurringMonth: number | null;
  createdAt: Date;
  appliedAt: Date | null;
}

@Injectable()
export class GetReferralListUseCase {
  constructor(
    private readonly relationshipRepo: ReferralRelationshipRepository,
    private readonly rewardRepo: ReferralRewardRepository,
  ) {}

  async getReferrals(
    tenantId: string,
    limit = 20,
    offset = 0,
  ): Promise<{ items: ReferralItemDto[]; total: number }> {
    const { items, total } = await this.relationshipRepo.findAllByReferrerTenantId(
      tenantId,
      limit,
      offset,
    );
    return {
      items: items.map(this.mapReferral),
      total,
    };
  }

  async getRewards(
    tenantId: string,
    status?: 'PENDING' | 'APPLIED' | 'EXPIRED',
    limit = 20,
    offset = 0,
  ): Promise<{ items: RewardItemDto[]; total: number }> {
    const { items, total } = await this.rewardRepo.findAllByTenant(
      tenantId,
      status,
      limit,
      offset,
    );
    return {
      items: items.map(this.mapReward),
      total,
    };
  }

  private mapReferral(r: ReferralRelationship): ReferralItemDto {
    return {
      id: r.id,
      referredTenantId: r.referredTenantId,
      referralCode: r.referralCode,
      status: r.status,
      level: r.level,
      registeredAt: r.registeredAt,
      activatedAt: r.activatedAt,
    };
  }

  private mapReward(r: ReferralReward): RewardItemDto {
    const dollars = (r.amountCents / 100).toFixed(2);
    return {
      id: r.id,
      amountCents: r.amountCents,
      amountFormatted: `$${dollars}`,
      rewardType: r.rewardType,
      triggerType: r.triggerType,
      status: r.status,
      sourceInvoiceId: r.sourceInvoiceId,
      recurringMonth: r.recurringMonth,
      createdAt: r.createdAt,
      appliedAt: r.appliedAt,
    };
  }
}
