/**
 * In-Memory Implementation: InMemoryMembershipFeeRepository
 */

import type { Logger } from '@core/shared/application/Logger';
import type { IMembershipFeeRepository, IMemberPaymentRepository } from '@core/payments/domain/repositories/IMembershipFeeRepository';
import type { MembershipFee } from '@core/payments/domain/entities/MembershipFee';
import type { MemberPayment } from '@core/payments/domain/entities/MemberPayment';

const membershipFees: Map<string, MembershipFee> = new Map();
const memberPayments: Map<string, MemberPayment> = new Map();

export class InMemoryMembershipFeeRepository implements IMembershipFeeRepository {
  constructor(private readonly logger: Logger) {}

  async findById(id: string): Promise<MembershipFee | null> {
    this.logger.debug('[InMemoryMembershipFeeRepository] findById', { id });
    return membershipFees.get(id) || null;
  }

  async findByLeagueId(leagueId: string): Promise<MembershipFee | null> {
    this.logger.debug('[InMemoryMembershipFeeRepository] findByLeagueId', { leagueId });
    return Array.from(membershipFees.values()).find(f => f.leagueId === leagueId) || null;
  }

  async create(fee: MembershipFee): Promise<MembershipFee> {
    this.logger.debug('[InMemoryMembershipFeeRepository] create', { fee });
    membershipFees.set(fee.id, fee);
    return fee;
  }

  async update(fee: MembershipFee): Promise<MembershipFee> {
    this.logger.debug('[InMemoryMembershipFeeRepository] update', { fee });
    membershipFees.set(fee.id, fee);
    return fee;
  }
}

export class InMemoryMemberPaymentRepository implements IMemberPaymentRepository {
  constructor(private readonly logger: Logger) {}

  async findById(id: string): Promise<MemberPayment | null> {
    this.logger.debug('[InMemoryMemberPaymentRepository] findById', { id });
    return memberPayments.get(id) || null;
  }

  async findByFeeIdAndDriverId(feeId: string, driverId: string): Promise<MemberPayment | null> {
    this.logger.debug('[InMemoryMemberPaymentRepository] findByFeeIdAndDriverId', { feeId, driverId });
    return Array.from(memberPayments.values()).find(
      p => p.feeId === feeId && p.driverId === driverId
    ) || null;
  }

  async findByLeagueIdAndDriverId(leagueId: string, driverId: string, membershipFeeRepo: IMembershipFeeRepository): Promise<MemberPayment[]> {
    this.logger.debug('[InMemoryMemberPaymentRepository] findByLeagueIdAndDriverId', { leagueId, driverId });
    const results: MemberPayment[] = [];
    for (const payment of memberPayments.values()) {
      const fee = await membershipFeeRepo.findById(payment.feeId);
      if (fee && fee.leagueId === leagueId && payment.driverId === driverId) {
        results.push(payment);
      }
    }
    return results;
  }

  async create(payment: MemberPayment): Promise<MemberPayment> {
    this.logger.debug('[InMemoryMemberPaymentRepository] create', { payment });
    memberPayments.set(payment.id, payment);
    return payment;
  }

  async update(payment: MemberPayment): Promise<MemberPayment> {
    this.logger.debug('[InMemoryMemberPaymentRepository] update', { payment });
    memberPayments.set(payment.id, payment);
    return payment;
  }
}