import { Result } from '@gridpilot/shared/application/Result';
import type { Logger } from '@core/shared/application';
import type { CheckoutServicePort } from '../ports/CheckoutServicePort';
import type { CheckoutConfirmationPort } from '../ports/CheckoutConfirmationPort';
import { CheckoutStateEnum } from '../../domain/value-objects/CheckoutState';


interface SessionMetadata {
  sessionName: string;
  trackId: string;
  carIds: string[];
}

export class ConfirmCheckoutUseCase {
  private static readonly DEFAULT_TIMEOUT_MS = 30000;

  constructor(
    private readonly checkoutService: CheckoutServicePort,
    private readonly confirmationPort: CheckoutConfirmationPort,
    private readonly logger: Logger,
  ) {}

  async execute(sessionMetadata?: SessionMetadata): Promise<Result<void>> {
    this.logger.debug('Executing ConfirmCheckoutUseCase', { sessionMetadata });

    const infoResult = await this.checkoutService.extractCheckoutInfo();
    
    if (infoResult.isErr()) {
      this.logger.error('Failed to extract checkout info', infoResult.unwrapErr());
      return Result.err(infoResult.unwrapErr());
    }

    const info = infoResult.unwrap();
    this.logger.info('Extracted checkout info', { state: info.state.getValue(), price: info.price });


    if (info.state.getValue() === CheckoutStateEnum.INSUFFICIENT_FUNDS) {
      this.logger.error('Insufficient funds to complete checkout');
      return Result.err(new Error('Insufficient funds to complete checkout'));
    }

    if (!info.price) {
      this.logger.error('Could not extract price from checkout page');
      return Result.err(new Error('Could not extract price from checkout page'));
    }

    this.logger.debug('Requesting checkout confirmation', { price: info.price, state: info.state.getValue(), sessionMetadata });

    // Request confirmation via port with full checkout context
    const confirmationResult = await this.confirmationPort.requestCheckoutConfirmation({
      price: info.price,
      state: info.state,
      sessionMetadata: sessionMetadata || {
        sessionName: 'Unknown Session',
        trackId: 'unknown',
        carIds: [],
      },
      timeoutMs: ConfirmCheckoutUseCase.DEFAULT_TIMEOUT_MS,
    });

    if (confirmationResult.isErr()) {
      this.logger.error('Checkout confirmation failed', confirmationResult.unwrapErr());
      return Result.err(confirmationResult.unwrapErr());
    }

    const confirmation = confirmationResult.unwrap();
    this.logger.info('Checkout confirmation received', { confirmation });

    if (confirmation.isCancelled()) {
      this.logger.error('Checkout cancelled by user');
      return Result.err(new Error('Checkout cancelled by user'));
    }

    if (confirmation.isTimeout()) {
      this.logger.error('Checkout confirmation timeout');
      return Result.err(new Error('Checkout confirmation timeout'));
    }

    this.logger.info('Proceeding with checkout');
    const checkoutResult = await this.checkoutService.proceedWithCheckout();

    if (checkoutResult.isOk()) {
      this.logger.info('Checkout process completed successfully.');
    } else {
      this.logger.error('Checkout process failed', checkoutResult.unwrapErr());
    }
    return checkoutResult;
  }
}