import axios, { AxiosResponse } from 'axios';
import { PartnerPayloadResult } from './partner-payload-adapters';

export interface DispatchPartnerPayloadResult {
  routeId: string;
  partner: string;
  supported: boolean;
  dispatched: boolean;
  endpoint: string;
  statusCode?: number;
  data?: unknown;
  error?: string;
}

function resolveHeaders(payload: PartnerPayloadResult): Record<string, string> {
  const headers = { ...payload.headers };

  if (payload.partner === '1inch' && process.env.ONE_INCH_API_KEY) {
    headers.Authorization = `Bearer ${process.env.ONE_INCH_API_KEY}`;
  }

  if (payload.partner === '0x' && process.env.ZEROX_API_KEY) {
    headers['0x-api-key'] = process.env.ZEROX_API_KEY;
  }

  if (payload.partner === 'LiFi' && process.env.LIFI_API_KEY) {
    headers['x-lifi-api-key'] = process.env.LIFI_API_KEY;
  }

  return headers;
}

function missingCredentialReason(payload: PartnerPayloadResult): string | null {
  if (payload.partner === '1inch' && !process.env.ONE_INCH_API_KEY) {
    return 'ONE_INCH_API_KEY is not set';
  }
  if (payload.partner === '0x' && !process.env.ZEROX_API_KEY) {
    return 'ZEROX_API_KEY is not set';
  }
  return null;
}

export async function dispatchPartnerPayload(
  payload: PartnerPayloadResult
): Promise<DispatchPartnerPayloadResult> {
  if (!payload.supported) {
    return {
      routeId: payload.routeId,
      partner: payload.partner,
      supported: false,
      dispatched: false,
      endpoint: payload.endpoint,
      error: payload.reason || 'Payload is not supported',
    };
  }

  const credentialError = missingCredentialReason(payload);
  if (credentialError) {
    return {
      routeId: payload.routeId,
      partner: payload.partner,
      supported: true,
      dispatched: false,
      endpoint: payload.endpoint,
      error: credentialError,
    };
  }

  try {
    const response: AxiosResponse = await axios.get(payload.endpoint, {
      params: payload.query,
      headers: resolveHeaders(payload),
      timeout: 20_000,
    });

    return {
      routeId: payload.routeId,
      partner: payload.partner,
      supported: true,
      dispatched: true,
      endpoint: payload.endpoint,
      statusCode: response.status,
      data: response.data,
    };
  } catch (error: unknown) {
    if (axios.isAxiosError(error)) {
      return {
        routeId: payload.routeId,
        partner: payload.partner,
        supported: true,
        dispatched: false,
        endpoint: payload.endpoint,
        statusCode: error.response?.status,
        data: error.response?.data,
        error: error.message,
      };
    }

    return {
      routeId: payload.routeId,
      partner: payload.partner,
      supported: true,
      dispatched: false,
      endpoint: payload.endpoint,
      error: error instanceof Error ? error.message : 'Unknown dispatch error',
    };
  }
}

