/**
 * Application Use Case: SubmitProtestDefenseUseCase
 *
 * Allows the accused driver to submit their defense statement for a protest.
 */

import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { IProtestRepository } from '../../domain/repositories/IProtestRepository';

export interface SubmitProtestDefenseCommand {
  protestId: string;
  driverId: string;
  statement: string;
  videoUrl?: string;
}

type SubmitProtestDefenseErrorCode = 'PROTEST_NOT_FOUND' | 'NOT_ACCUSED_DRIVER' | 'DEFENSE_CANNOT_BE_SUBMITTED';

export class SubmitProtestDefenseUseCase {
  constructor(
    private readonly protestRepository: IProtestRepository,
  ) {}

  async execute(command: SubmitProtestDefenseCommand): Promise<Result<{ protestId: string }, ApplicationErrorCode<SubmitProtestDefenseErrorCode>>> {
    // Get the protest
    const protest = await this.protestRepository.findById(command.protestId);
    if (!protest) {
      return Result.err({ code: 'PROTEST_NOT_FOUND' });
    }

    // Verify the submitter is the accused driver
    if (protest.accusedDriverId !== command.driverId) {
      return Result.err({ code: 'NOT_ACCUSED_DRIVER' });
    }

    // Check if defense can be submitted
    if (!protest.canSubmitDefense()) {
      return Result.err({ code: 'DEFENSE_CANNOT_BE_SUBMITTED' });
    }

    // Submit defense
    const updatedProtest = protest.submitDefense(command.statement, command.videoUrl);
    await this.protestRepository.update(updatedProtest);

    return Result.ok({ protestId: protest.id });
  }
}