import type { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

export interface CommandResultDTO {
  success: boolean;
  errorCode?: string;
  message?: string;
}

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

export class CommandResultPresenter {
  private model: CommandResultDTO | null = null;

  reset(): void {
    this.model = null;
  }

  present(result: Result<unknown, CommandApplicationError>): void {
    if (result.isErr()) {
      const error = result.unwrapErr();
      this.model = {
        success: false,
        errorCode: error.code,
        message: error.details?.message,
      };
      return;
    }

    this.model = { success: true };
  }

  presentSuccess(message?: string): void {
    this.model = {
      success: true,
      ...(message !== undefined && { message }),
    };
  }

  presentFailure(errorCode: string, message?: string): void {
    this.model = {
      success: false,
      errorCode,
      ...(message !== undefined && { message }),
    };
  }

  getResponseModel(): CommandResultDTO | null {
    return this.model;
  }

  get responseModel(): CommandResultDTO {
    if (!this.model) {
      throw new Error('Presenter not presented');
    }

    return this.model;
  }

  get viewModel(): CommandResultDTO {
    return this.responseModel;
  }
}
