import axios from 'axios';
import authHeader from './auth.header';

// Configure global axios defaults
axios.defaults.withCredentials = true;

// Main Flask API
const api = axios.create({
  baseURL: import.meta.env.VITE_BASE_URL,
  withCredentials: true,
});

// Authorize.net FastAPI
const authorizeApi = axios.create({
  baseURL: import.meta.env.VITE_AUTHORIZE_URL,
  withCredentials: true,
});

// Automatic Delivery System
const autoApi = axios.create({
  baseURL: import.meta.env.VITE_AUTO_URL,
  withCredentials: true,
});

// Service/Maintenance System
const serviceApi = axios.create({
  baseURL: import.meta.env.VITE_SERVICE_URL,
  withCredentials: true,
});

// Scraper Service
const scraperApi = axios.create({
  baseURL: import.meta.env.VITE_SCRAPER_URL,
  withCredentials: true,
});

// Request interceptor - add auth token
function addAuthHeader(config: { headers: { Authorization?: string } }) {
  const token = localStorage.getItem('auth_token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  // Also merge in session-based auth headers
  const sessionAuth = authHeader();
  if ('Authorization' in sessionAuth) {
    config.headers.Authorization = sessionAuth.Authorization;
  }
  return config;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
api.interceptors.request.use(addAuthHeader as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
authorizeApi.interceptors.request.use(addAuthHeader as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
autoApi.interceptors.request.use(addAuthHeader as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
serviceApi.interceptors.request.use(addAuthHeader as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
scraperApi.interceptors.request.use(addAuthHeader as any);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
axios.interceptors.request.use(addAuthHeader as any);

// Response interceptor - unwrap standardized API responses
// Backend returns: { ok: true, customer: {...} } or { ok: true, deliveries: [...] }
// This spreads nested object properties into response.data so both patterns work:
// - response.data.ok → true
// - response.data.customer → {...} (the nested object)
// - response.data.id, response.data.name → spread from nested object
function unwrapResponse(response: { data: Record<string, unknown> }) {
  const data = response.data;

  // Only process standardized responses with 'ok' field
  if (data && typeof data === 'object' && 'ok' in data && data.ok === true) {
    const dataKeys = Object.keys(data).filter(key => key !== 'ok');

    // If there's exactly one data key, merge its properties for backwards compatibility
    if (dataKeys.length === 1) {
      const key = dataKeys[0];
      const nestedData = data[key];

      // For objects: spread properties so response.data.id works
      if (nestedData && typeof nestedData === 'object' && !Array.isArray(nestedData)) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        response.data = { ok: true, [key]: nestedData, ...nestedData as any };
      }
    }
  }

  return response;
}

// Response error handler - handle 401 errors
function handleResponseError(error: unknown) {
  const err = error as { response?: { status?: number } };
  if (err?.response?.status === 401) {
    localStorage.removeItem('auth_token');
  }
  return Promise.reject(error);
}

api.interceptors.response.use(unwrapResponse, handleResponseError);
authorizeApi.interceptors.response.use(unwrapResponse, handleResponseError);
autoApi.interceptors.response.use(unwrapResponse, handleResponseError);
serviceApi.interceptors.response.use(unwrapResponse, handleResponseError);
scraperApi.interceptors.response.use(unwrapResponse, handleResponseError);
axios.interceptors.response.use(unwrapResponse, handleResponseError);

export { api, authorizeApi, autoApi, serviceApi, scraperApi };
export default api;
