/**
 * Use Case: DeleteMediaUseCase
 *
 * Handles the business logic for deleting media files.
 */

import type { IMediaRepository } from '../../domain/repositories/IMediaRepository';
import type { MediaStoragePort } from '../ports/MediaStoragePort';
import type { Logger, UseCaseOutputPort } from '@core/shared/application';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

export interface DeleteMediaInput {
  mediaId: string;
}

export interface DeleteMediaResult {
  mediaId: string;
  deleted: boolean;
}

export type DeleteMediaErrorCode = 'MEDIA_NOT_FOUND' | 'REPOSITORY_ERROR';

export type DeleteMediaApplicationError = ApplicationErrorCode<
  DeleteMediaErrorCode,
  { message: string }
>;

export class DeleteMediaUseCase {
  constructor(
    private readonly mediaRepo: IMediaRepository,
    private readonly mediaStorage: MediaStoragePort,
    private readonly output: UseCaseOutputPort<DeleteMediaResult>,
    private readonly logger: Logger,
  ) {}

  async execute(input: DeleteMediaInput): Promise<Result<void, DeleteMediaApplicationError>> {
    this.logger.info('[DeleteMediaUseCase] Deleting media', {
      mediaId: input.mediaId,
    });

    try {
      const media = await this.mediaRepo.findById(input.mediaId);

      if (!media) {
        return Result.err<void, DeleteMediaApplicationError>({
          code: 'MEDIA_NOT_FOUND',
          details: { message: 'Media not found' },
        });
      }

      await this.mediaStorage.deleteMedia(media.url.value);
      await this.mediaRepo.delete(input.mediaId);

      this.output.present({
        mediaId: input.mediaId,
        deleted: true,
      });

      this.logger.info('[DeleteMediaUseCase] Media deleted successfully', {
        mediaId: input.mediaId,
      });

      return Result.ok(undefined);
    } catch (error) {
      const err = error instanceof Error ? error : new Error(String(error));

      this.logger.error('[DeleteMediaUseCase] Error deleting media', err, {
        mediaId: input.mediaId,
      });

      return Result.err<void, DeleteMediaApplicationError>({
        code: 'REPOSITORY_ERROR',
        details: { message: err.message || 'Unexpected repository error' },
      });
    }
  }
}