import type { Logger } from '@core/shared/application';
import { Result } from '@core/shared/application/Result';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { League } from '../../domain/entities/League';
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository';

export type GetLeagueAdminPermissionsInput = {
  leagueId: string;
  performerDriverId: string;
};

export type LeagueAdminPermissions = {
  canManageSchedule: boolean;
  canManageMembers: boolean;
  canManageSponsorships: boolean;
  canManageScoring: boolean;
};

export type GetLeagueAdminPermissionsResult = {
  league: League;
  permissions: LeagueAdminPermissions;
};

export type GetLeagueAdminPermissionsErrorCode =
  | 'LEAGUE_NOT_FOUND'
  | 'USER_NOT_MEMBER'
  | 'REPOSITORY_ERROR';

export class GetLeagueAdminPermissionsUseCase {
  constructor(
    private readonly leagueRepository: ILeagueRepository,
    private readonly leagueMembershipRepository: ILeagueMembershipRepository,
    private readonly logger: Logger,
    private readonly output: UseCaseOutputPort<GetLeagueAdminPermissionsResult>,
  ) {}

  async execute(
    input: GetLeagueAdminPermissionsInput,
  ): Promise<Result<void, ApplicationErrorCode<GetLeagueAdminPermissionsErrorCode, { message: string }>>> {
    const { leagueId, performerDriverId } = input;

    try {
      const league = await this.leagueRepository.findById(leagueId);
      if (!league) {
        this.logger.warn('League not found when checking admin permissions', { leagueId, performerDriverId });
        return Result.err({
          code: 'LEAGUE_NOT_FOUND',
          details: { message: 'League not found' },
        });
      }

      const membership = await this.leagueMembershipRepository.getMembership(leagueId, performerDriverId);
      if (!membership || membership.status.toString() !== 'active' || (membership.role.toString() !== 'owner' && membership.role.toString() !== 'admin')) {
        this.logger.warn('User is not a member or not authorized for league admin permissions', {
          leagueId,
          performerDriverId,
        });
        return Result.err({
          code: 'USER_NOT_MEMBER',
          details: { message: 'User is not a member of this league' },
        });
      }

      const permissions: LeagueAdminPermissions = {
        canManageSchedule: true,
        canManageMembers: true,
        canManageSponsorships: true,
        canManageScoring: true,
      };

      const result: GetLeagueAdminPermissionsResult = {
        league,
        permissions,
      };

      this.output.present(result);

      return Result.ok(undefined);
    } catch (error) {
      const err = error instanceof Error ? error : new Error('Unknown error');
      this.logger.error('Failed to load league admin permissions', err);
      return Result.err({
        code: 'REPOSITORY_ERROR',
        details: { message: err.message ?? 'Failed to load league admin permissions' },
      });
    }
  }
}
