import { ILeagueMembershipRepository } from '@core/racing/domain/repositories/ILeagueMembershipRepository';
import { LeagueMembership, JoinRequest } from '@core/racing/domain/entities/LeagueMembership';
import { Logger } from '@core/shared/application';

export class InMemoryLeagueMembershipRepository implements ILeagueMembershipRepository {
  private memberships: Map<string, LeagueMembership> = new Map(); // Key: `${leagueId}:${driverId}`
  private joinRequests: Map<string, JoinRequest> = new Map(); // Key: requestId

  constructor(private readonly logger: Logger) {
    this.logger.info('InMemoryLeagueMembershipRepository initialized.');
  }

  async getMembership(leagueId: string, driverId: string): Promise<LeagueMembership | null> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Getting membership for league ${leagueId}, driver ${driverId}.`);
    const key = `${leagueId}:${driverId}`;
    const membership = this.memberships.get(key) ?? null;
    if (membership) {
      this.logger.info(`Found membership for league ${leagueId}, driver ${driverId}.`);
    } else {
      this.logger.warn(`No membership found for league ${leagueId}, driver ${driverId}.`);
    }
    return Promise.resolve(membership);
  }

  async findActiveByLeagueIdAndDriverId(leagueId: string, driverId: string): Promise<LeagueMembership | null> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Finding active membership for league ${leagueId}, driver ${driverId}.`);
    const membership = await this.getMembership(leagueId, driverId);
    return Promise.resolve(membership && membership.status === 'active' ? membership : null);
  }

  async findAllByLeagueId(leagueId: string): Promise<LeagueMembership[]> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Finding all memberships for league ${leagueId}.`);
    const filteredMemberships = Array.from(this.memberships.values()).filter(mem => mem.leagueId === leagueId);
    this.logger.info(`Found ${filteredMemberships.length} memberships for league ${leagueId}.`);
    return Promise.resolve(filteredMemberships);
  }

  async findAllByDriverId(driverId: string): Promise<LeagueMembership[]> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Finding all memberships for driver ${driverId}.`);
    const memberships = Array.from(this.memberships.values()).filter(mem => mem.driverId === driverId);
    this.logger.info(`Found ${memberships.length} memberships for driver ${driverId}.`);
    return Promise.resolve(memberships);
  }

  async getLeagueMembers(leagueId: string): Promise<LeagueMembership[]> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Getting active members for league ${leagueId}.`);
    const members = Array.from(this.memberships.values()).filter(mem => mem.leagueId === leagueId && mem.status === 'active');
    this.logger.info(`Found ${members.length} active members for league ${leagueId}.`);
    return Promise.resolve(members);
  }

  async getJoinRequests(leagueId: string): Promise<JoinRequest[]> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Getting join requests for league ${leagueId}.`);
    const requests = Array.from(this.joinRequests.values()).filter(req => req.leagueId === leagueId);
    this.logger.info(`Found ${requests.length} join requests for league ${leagueId}.`);
    return Promise.resolve(requests);
  }

  async saveMembership(membership: LeagueMembership): Promise<LeagueMembership> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Saving membership for ${membership.id}.`);
    const key = `${membership.leagueId}:${membership.driverId}`;
    this.memberships.set(key, membership);
    this.logger.info(`Membership ${membership.id} saved successfully.`);
    return Promise.resolve(membership);
  }

  async removeMembership(leagueId: string, driverId: string): Promise<void> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Removing membership for league ${leagueId}, driver ${driverId}.`);
    const key = `${leagueId}:${driverId}`;
    if (this.memberships.delete(key)) {
      this.logger.info(`Membership for league ${leagueId}, driver ${driverId} removed successfully.`);
    } else {
      this.logger.warn(`Membership for league ${leagueId}, driver ${driverId} not found for removal.`);
    }
    return Promise.resolve();
  }

  async saveJoinRequest(request: JoinRequest): Promise<JoinRequest> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Saving join request for ${request.id}.`);
    this.joinRequests.set(request.id, request);
    this.logger.info(`Join request ${request.id} saved successfully.`);
    return Promise.resolve(request);
  }

  async removeJoinRequest(requestId: string): Promise<void> {
    this.logger.debug(`[InMemoryLeagueMembershipRepository] Removing join request: ${requestId}.`);
    if (this.joinRequests.delete(requestId)) {
      this.logger.info(`Join request ${requestId} removed successfully.`);
    } else {
      this.logger.warn(`Join request ${requestId} not found for removal.`);
    }
    return Promise.resolve();
  }
}
