/**
 * Application Use Case: CreateTeamUseCase
 *
 * Creates a new team.
 */
import type { Logger } from '@core/shared/domain/Logger';
import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import { v4 as uuidv4 } from 'uuid';
import { Team } from '../../domain/entities/Team';
import { TeamMembershipRepository } from '../../domain/repositories/TeamMembershipRepository';
import { TeamRepository } from '../../domain/repositories/TeamRepository';
import type {
    TeamMembership,
    TeamMembershipStatus,
    TeamRole,
} from '../../domain/types/TeamMembership';

export interface CreateTeamInput {
  name: string;
  tag: string;
  description: string;
  ownerId: string;
  leagues: string[];
}

export interface CreateTeamResult {
  team: Team;
}

export type CreateTeamErrorCode =
  | 'VALIDATION_ERROR'
  | 'LEAGUE_NOT_FOUND'
  | 'REPOSITORY_ERROR';

export class CreateTeamUseCase {
  constructor(private readonly teamRepository: TeamRepository,
    private readonly membershipRepository: TeamMembershipRepository,
    private readonly logger: Logger) {}

  async execute(
    input: CreateTeamInput,
  ): Promise<
    Result<CreateTeamResult, ApplicationErrorCode<CreateTeamErrorCode, { message: string }>>
  > {
    this.logger.debug('Executing CreateTeamUseCase', { input });
    const { name, tag, description, ownerId, leagues } = input;

    const existingMembership =
      await this.membershipRepository.getActiveMembershipForDriver(ownerId);
    if (existingMembership) {
      this.logger.warn(
        'Validation failed: Driver already belongs to a team',
        { ownerId },
      );
      return Result.err({
        code: 'VALIDATION_ERROR',
        details: { message: 'Driver already belongs to a team' },
      });
    }

    this.logger.info('Command validated successfully.');
    try {
      const teamId = uuidv4();
      this.logger.debug(`Generated teamId: ${teamId}`);

      const team = Team.create({
        id: teamId,
        name,
        tag,
        description,
        ownerId,
        leagues,
      });

      const createdTeam = await this.teamRepository.create(team);
      this.logger.info(
        `Team ${createdTeam.name} (${createdTeam.id}) created successfully.`,
      );

      const membership: TeamMembership = {
        teamId: createdTeam.id,
        driverId: ownerId,
        role: 'owner' as TeamRole,
        status: 'active' as TeamMembershipStatus,
        joinedAt: new Date(),
      };

      await this.membershipRepository.saveMembership(membership);
      this.logger.debug('Team membership created successfully.');

      const result: CreateTeamResult = { team: createdTeam };
      this.logger.debug('CreateTeamUseCase completed successfully.', { result });
      return Result.ok(result);
    } catch (error) {
      return Result.err({
        code: 'REPOSITORY_ERROR',
        details: {
          message: error instanceof Error ? error.message : 'Unknown error',
        },
      });
    }
  }
}