import type { ITeamMembershipRepository } from '../../domain/repositories/ITeamMembershipRepository';
import type { LeaveTeamCommandDTO } from '../dtos/LeaveTeamCommandDTO';
import type { AsyncUseCase, Logger } from '@core/shared/application';
import { Result as SharedResult } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

type LeaveTeamErrorCode = 'NOT_MEMBER' | 'OWNER_CANNOT_LEAVE' | 'REPOSITORY_ERROR';

type LeaveTeamApplicationError = ApplicationErrorCode<LeaveTeamErrorCode, { message: string }>;

export class LeaveTeamUseCase implements AsyncUseCase<LeaveTeamCommandDTO, void, LeaveTeamErrorCode> {
  constructor(
    private readonly membershipRepository: ITeamMembershipRepository,
    private readonly logger: Logger,
  ) {}

  async execute(command: LeaveTeamCommandDTO): Promise<SharedResult<void, LeaveTeamApplicationError>> {
    this.logger.debug('Attempting to leave team', { command });
    const { teamId, driverId } = command;

    try {
      const membership = await this.membershipRepository.getMembership(teamId, driverId);
      if (!membership) {
        this.logger.warn('Driver is not a member of this team', { driverId, teamId });
        return SharedResult.err({ code: 'NOT_MEMBER', details: { message: 'Not a member of this team' } });
      }

      if (membership.role === 'owner') {
        this.logger.warn('Team owner cannot leave', { driverId, teamId });
        return SharedResult.err({
          code: 'OWNER_CANNOT_LEAVE',
          details: { message: 'Team owner cannot leave. Transfer ownership or disband team first.' }
        });
      }

      await this.membershipRepository.removeMembership(teamId, driverId);
      this.logger.info('Driver successfully left team', { driverId, teamId });
      return SharedResult.ok(undefined);
    } catch (error) {
      this.logger.error('Failed to leave team due to an unexpected error', error instanceof Error ? error : new Error('Unknown error'));
      return SharedResult.err({ code: 'REPOSITORY_ERROR', details: { message: error instanceof Error ? error.message : 'Unknown error' } });
    }
  }
}