/**
 * MSC (Mediterranean Shipping Company) Connector
 *
 * Implements CarrierConnectorPort for MSC API integration
 */

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import {
  CarrierConnectorPort,
  CarrierRateSearchInput,
  CarrierAvailabilityInput,
} from '@domain/ports/out/carrier-connector.port';
import { RateQuote } from '@domain/entities/rate-quote.entity';
import { BaseCarrierConnector, CarrierConfig } from '../base-carrier.connector';
import { MSCRequestMapper } from './msc.mapper';

@Injectable()
export class MSCConnectorAdapter extends BaseCarrierConnector implements CarrierConnectorPort {
  private readonly apiUrl: string;
  private readonly apiKey: string;

  constructor(
    private readonly configService: ConfigService,
    private readonly requestMapper: MSCRequestMapper
  ) {
    const config: CarrierConfig = {
      name: 'MSC',
      code: 'MSCU',
      baseUrl: configService.get<string>('MSC_API_URL', 'https://api.msc.com/v1'),
      timeout: 5000,
      maxRetries: 3,
      circuitBreakerThreshold: 50,
      circuitBreakerTimeout: 30000,
    };
    super(config);
    this.apiUrl = config.baseUrl;
    this.apiKey = this.configService.get<string>('MSC_API_KEY', '');
  }

  async searchRates(input: CarrierRateSearchInput): Promise<RateQuote[]> {
    this.logger.log(`Searching MSC rates: ${input.origin} -> ${input.destination}`);

    try {
      // Map internal format to MSC API format
      const mscRequest = this.requestMapper.toMSCRequest(input);

      // Make API call with circuit breaker
      const response = await this.makeRequest({
        url: `${this.apiUrl}/rates/search`,
        method: 'POST',
        data: mscRequest,
        headers: {
          'X-API-Key': this.apiKey,
          'Content-Type': 'application/json',
        },
      });

      // Map MSC response to domain entities
      const rateQuotes = this.requestMapper.fromMSCResponse(response.data, input);

      this.logger.log(`Found ${rateQuotes.length} MSC rates`);
      return rateQuotes;
    } catch (error: any) {
      this.logger.error(`MSC API error: ${error?.message || 'Unknown error'}`);

      // Handle specific MSC error codes
      if (error?.response?.status === 404) {
        this.logger.warn('No MSC rates found for this route');
        return [];
      }

      if (error?.response?.status === 429) {
        this.logger.error('MSC rate limit exceeded');
        throw new Error('MSC_RATE_LIMIT_EXCEEDED');
      }

      // Return empty array on error (fail gracefully)
      return [];
    }
  }

  async checkAvailability(input: CarrierAvailabilityInput): Promise<number> {
    try {
      const response = await this.makeRequest({
        url: `${this.apiUrl}/availability/check`,
        method: 'POST',
        data: {
          origin: input.origin,
          destination: input.destination,
          departure_date: input.departureDate,
          container_type: input.containerType,
          quantity: input.quantity,
        },
        headers: {
          'X-API-Key': this.apiKey,
        },
      });

      return (response.data as any).available_slots || 0;
    } catch (error: any) {
      this.logger.error(`MSC availability check error: ${error?.message || 'Unknown error'}`);
      return 0;
    }
  }
}
