import type { GetLeagueRosterJoinRequestsResult } from '@core/racing/application/use-cases/GetLeagueRosterJoinRequestsUseCase';
import type { GetLeagueRosterMembersResult } from '@core/racing/application/use-cases/GetLeagueRosterMembersUseCase';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { Injectable } from '@nestjs/common';
import type { DriverDTO } from '../../driver/dtos/DriverDTO';
import type { LeagueRosterJoinRequestDTO } from '../dtos/LeagueRosterJoinRequestDTO';
import type { LeagueRosterMemberDTO } from '../dtos/LeagueRosterMemberDTO';

@Injectable()
export class GetLeagueRosterMembersPresenter implements UseCaseOutputPort<GetLeagueRosterMembersResult> {
  private viewModel: LeagueRosterMemberDTO[] | null = null;

  reset(): void {
    this.viewModel = null;
  }

  present(result: GetLeagueRosterMembersResult): void {
    this.viewModel = result.members.map(({ membership, driver }) => ({
      driverId: membership.driverId.toString(),
      driver: this.mapDriver(driver),
      role: membership.role.toString() as 'owner' | 'admin' | 'steward' | 'member',
      joinedAt: membership.joinedAt.toDate().toISOString(),
    }));
  }

  getViewModel(): LeagueRosterMemberDTO[] | null {
    return this.viewModel;
  }

  private mapDriver(driver: GetLeagueRosterMembersResult['members'][number]['driver']): DriverDTO {
    return {
      id: driver.id,
      iracingId: driver.iracingId.toString(),
      name: driver.name.toString(),
      country: driver.country.toString(),
      joinedAt: driver.joinedAt.toDate().toISOString(),
      ...(driver.bio ? { bio: driver.bio.toString() } : {}),
    };
  }
}

@Injectable()
export class GetLeagueRosterJoinRequestsPresenter implements UseCaseOutputPort<GetLeagueRosterJoinRequestsResult> {
  private viewModel: LeagueRosterJoinRequestDTO[] | null = null;

  reset(): void {
    this.viewModel = null;
  }

  present(result: GetLeagueRosterJoinRequestsResult): void {
    this.viewModel = result.joinRequests.map(req => ({
      id: req.id,
      leagueId: req.leagueId,
      driverId: req.driverId,
      requestedAt: req.requestedAt.toISOString(),
      ...(req.message ? { message: req.message } : {}),
      driver: {
        id: req.driver.id,
        name: req.driver.name.toString(),
      },
    }));
  }

  getViewModel(): LeagueRosterJoinRequestDTO[] | null {
    return this.viewModel;
  }
}