import { gatewayProfileCapabilities, type GatewayProfileCapabilities } from '@sammo-ts/common';
import type { GatewayOrchestratorHandle } from '../orchestrator/gatewayOrchestrator.js';
import type {
    GatewayProfileRecord,
    GatewayProfileRepository,
    GatewayProfileStatus,
} from '../orchestrator/profileRepository.js';
import { orderGatewayProfiles, resolveGatewayProfileKoreanName } from '../profileOrder.js';

export type LobbyMapSnapshot = {
    updatedAt: string | null;
    summary?: string | null;
};

export type LobbyGeneralStatus = {
    exists: boolean;
    cityId: number | null;
    cityName: string | null;
    updatedAt: string | null;
};

export type LobbyProfileStatus = {
    profileName: string;
    profile: string;
    instanceKey: string;
    currentScenario: string | null;
    /** @deprecated Rollback-compatible mirror of currentScenario. */
    scenario: string;
    status: GatewayProfileStatus;
    lifecycle: GatewayProfileCapabilities & {
        dataInitialized: boolean;
    };
    apiPort: number;
    runtime: {
        apiRunning: boolean;
        daemonRunning: boolean;
        auctionRunning: boolean;
        battleSimRunning: boolean;
        tournamentRunning: boolean;
    };
    korName: string;
    color: string;
};

export interface GatewayProfileStatusService {
    listLobbyProfiles(input: { userId?: string } | undefined): Promise<LobbyProfileStatus[]>;
}

// 로비에서 사용할 프로필 상태를 메모리에서 반환하는 구현체.
export class InMemoryProfileStatusService implements GatewayProfileStatusService {
    private profiles: LobbyProfileStatus[];

    constructor(initial: LobbyProfileStatus[] = []) {
        this.profiles = [...initial];
    }

    async listLobbyProfiles(): Promise<LobbyProfileStatus[]> {
        return orderGatewayProfiles(this.profiles);
    }

    setProfiles(profiles: LobbyProfileStatus[]): void {
        this.profiles = [...profiles];
    }
}

// 프로필 저장소/오케스트레이터를 이용해 로비 상태를 구성하는 기본 구현체.
export class RepositoryProfileStatusService implements GatewayProfileStatusService {
    constructor(
        private readonly profiles: GatewayProfileRepository,
        private readonly orchestrator: GatewayOrchestratorHandle
    ) {}

    async listLobbyProfiles(): Promise<LobbyProfileStatus[]> {
        const rows = orderGatewayProfiles(await this.profiles.listProfiles());
        const runtimeStates = await this.orchestrator.listRuntimeStates(rows.map((profile) => profile.profileName));
        const runtimeMap = new Map(runtimeStates.map((state) => [state.profileName, state]));
        return rows.map((row) => this.mapProfile(row, runtimeMap));
    }

    private mapProfile(
        row: GatewayProfileRecord,
        runtimeMap: Map<
            string,
            {
                apiRunning: boolean;
                daemonRunning: boolean;
                auctionRunning: boolean;
                battleSimRunning: boolean;
                tournamentRunning: boolean;
            }
        >
    ): LobbyProfileStatus {
        const meta = row.meta;
        return {
            profileName: row.profileName,
            profile: row.profile,
            instanceKey: row.instanceKey,
            currentScenario: row.currentScenario,
            scenario: row.scenario,
            status: row.status,
            lifecycle: {
                ...gatewayProfileCapabilities(row.status),
                dataInitialized: row.currentScenario !== null,
            },
            apiPort: row.apiPort,
            runtime: runtimeMap.get(row.profileName) ?? {
                apiRunning: false,
                daemonRunning: false,
                auctionRunning: false,
                battleSimRunning: false,
                tournamentRunning: false,
            },
            korName: resolveGatewayProfileKoreanName(row.profile, meta.korName),
            color: (meta.color as string | undefined) ?? '#ffffff',
        };
    }
}
