import { LeaguesApiClient } from "@/lib/api/leagues/LeaguesApiClient";
import { DriversApiClient } from "@/lib/api/drivers/DriversApiClient";
import type { LeagueConfigFormModel } from "@/lib/types/LeagueConfigFormModel";
import type { LeagueScoringPresetDTO } from "@/lib/types/generated/LeagueScoringPresetDTO";
import { LeagueSettingsViewModel } from "@/lib/view-models/LeagueSettingsViewModel";
import { DriverSummaryViewModel } from "@/lib/view-models/DriverSummaryViewModel";

/**
 * League Settings Service
 *
 * Orchestrates league settings operations by coordinating API calls and view model creation.
 * All dependencies are injected via constructor.
 */
export class LeagueSettingsService {
  constructor(
    private readonly leaguesApiClient: LeaguesApiClient,
    private readonly driversApiClient: DriversApiClient
  ) {}

  /**
   * Get league settings with view model transformation
   */
  async getLeagueSettings(leagueId: string): Promise<LeagueSettingsViewModel | null> {
    try {
      // Get league basic info (includes ownerId in DTO)
      const allLeagues = await this.leaguesApiClient.getAllWithCapacity();
      const leagueDto = allLeagues.leagues.find(l => l.id === leagueId);
      if (!leagueDto) return null;

      const league = {
        id: leagueDto.id,
        name: leagueDto.name,
        ownerId: leagueDto.ownerId,
        createdAt: leagueDto.createdAt || new Date().toISOString(),
      };

      // Get config
      const configDto = await this.leaguesApiClient.getLeagueConfig(leagueId);
      const config: LeagueConfigFormModel = (configDto.form ?? undefined) as unknown as LeagueConfigFormModel;

      // Get presets
      const presetsDto = await this.leaguesApiClient.getScoringPresets();
      const presets: LeagueScoringPresetDTO[] = presetsDto.presets;

      // Get leaderboard once so we can hydrate rating / rank for owner + members
      const leaderboardDto = await this.driversApiClient.getLeaderboard();
      const leaderboardByDriverId = new Map(
        leaderboardDto.drivers.map(driver => [driver.id, driver])
      );

      // Get owner
      const ownerDriver = await this.driversApiClient.getDriver(league.ownerId);
      let owner: DriverSummaryViewModel | null = null;
      if (ownerDriver) {
        const ownerStats = leaderboardByDriverId.get(ownerDriver.id);
        owner = new DriverSummaryViewModel({
          driver: ownerDriver,
          rating: ownerStats?.rating ?? null,
          rank: ownerStats?.rank ?? null,
        });
      }

      // Get members
      const membershipsDto = await this.leaguesApiClient.getMemberships(leagueId);
      const members: DriverSummaryViewModel[] = [];
      for (const member of membershipsDto.members) {
        if (member.driverId !== league.ownerId && member.role !== 'owner') {
          const driver = await this.driversApiClient.getDriver(member.driverId);
          if (driver) {
            const memberStats = leaderboardByDriverId.get(driver.id);
            members.push(new DriverSummaryViewModel({
              driver,
              rating: memberStats?.rating ?? null,
              rank: memberStats?.rank ?? null,
            }));
          }
        }
      }

      return new LeagueSettingsViewModel({
        league,
        config,
        presets,
        owner,
        members,
      });
    } catch (error) {
      console.error('Failed to load league settings:', error);
      return null;
    }
  }

  /**
   * Transfer league ownership
   */
  async transferOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<boolean> {
    try {
      const result = await this.leaguesApiClient.transferOwnership(leagueId, currentOwnerId, newOwnerId);
      return result.success;
    } catch (error) {
      console.error('Failed to transfer ownership:', error);
      throw error;
    }
  }
}