import axios from 'axios';
import liveDashboardConfig from '@/config/dashboard';

// Use the configuration for the ACOT API
const ACOT_BASE_URL = liveDashboardConfig.acot.replace('/api/acot', '');

const acotApi = axios.create({
  baseURL: ACOT_BASE_URL,
  timeout: 30000,
});

// Mirror utils/apiClient's auth plumbing on this private instance:
// inject Bearer token from localStorage and bounce to /login on 401.
// Without this, every acot call 401s at Caddy forward_auth (Phase 6.1).
acotApi.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token && !config.headers.has('Authorization')) {
    config.headers.set('Authorization', `Bearer ${token}`);
  }
  return config;
});

acotApi.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error?.response?.status === 401 && localStorage.getItem('token')) {
      window.dispatchEvent(new Event('auth:logout'));
    }
    return Promise.reject(error);
  },
);

// Request deduplication cache
const requestCache = new Map();

// Periodic cache cleanup (every 5 minutes)
setInterval(() => {
  const now = Date.now();
  const maxAge = 5 * 60 * 1000; // 5 minutes
  
  for (const [key, value] of requestCache.entries()) {
    if (value.timestamp && now - value.timestamp > maxAge) {
      requestCache.delete(key);
    }
  }
  
  if (requestCache.size > 0) {
    console.log(`[ACOT API] Cache cleanup: ${requestCache.size} entries remaining`);
  }
}, 5 * 60 * 1000);

// Retry function for timeout errors
const retryRequest = async (requestFn, maxRetries = 2, delay = 1000) => {
  for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
    try {
      return await requestFn();
    } catch (error) {
      const isTimeout = error.code === 'ECONNABORTED' || error.message.includes('timeout');
      const isLastAttempt = attempt === maxRetries + 1;
      
      if (isTimeout && !isLastAttempt) {
        console.log(`[ACOT API] Timeout on attempt ${attempt}, retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
        delay *= 1.5; // Exponential backoff
        continue;
      }
      
      throw error;
    }
  }
};

// Request deduplication function
const deduplicatedRequest = async (cacheKey, requestFn, cacheDuration = 5000) => {
  // Check if we have a pending request for this key
  if (requestCache.has(cacheKey)) {
    const cached = requestCache.get(cacheKey);
    
    // If it's a pending promise, return it
    if (cached.promise) {
      console.log(`[ACOT API] Deduplicating request: ${cacheKey}`);
      return cached.promise;
    }
    
    // If it's cached data and still fresh, return it
    if (cached.data && Date.now() - cached.timestamp < cacheDuration) {
      console.log(`[ACOT API] Using cached data: ${cacheKey}`);
      return cached.data;
    }
  }
  
  // Create new request
  const promise = requestFn().then(data => {
    // Cache the result
    requestCache.set(cacheKey, {
      data,
      timestamp: Date.now(),
      promise: null
    });
    return data;
  }).catch(error => {
    // Remove from cache on error
    requestCache.delete(cacheKey);
    throw error;
  });
  
  // Cache the promise while it's pending
  requestCache.set(cacheKey, {
    promise,
    timestamp: Date.now(),
    data: null
  });
  
  return promise;
};

// Add request interceptor for logging
acotApi.interceptors.request.use(
  (config) => {
    console.log(`[ACOT API] ${config.method?.toUpperCase()} ${config.url}`, config.params);
    return config;
  },
  (error) => {
    console.error('[ACOT API] Request error:', error);
    return Promise.reject(error);
  }
);

// Add response interceptor for logging
acotApi.interceptors.response.use(
  (response) => {
    console.log(`[ACOT API] Response ${response.status}:`, response.data);
    return response;
  },
  (error) => {
    console.error('[ACOT API] Response error:', error.response?.data || error.message);
    return Promise.reject(error);
  }
);

// Cleanup function to clear cache
const clearCache = () => {
  requestCache.clear();
  console.log('[ACOT API] Request cache cleared');
};

export const acotService = {
  // Get main stats - replaces klaviyo events/stats
  getStats: async (params) => {
    const cacheKey = `stats_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () => 
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/events/stats', { params });
        return response.data;
      })
    );
  },

  // Get detailed stats - replaces klaviyo events/stats/details
  getStatsDetails: async (params) => {
    const cacheKey = `details_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () => 
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/events/stats/details', { params });
        return response.data;
      })
    );
  },

  // Get products data - replaces klaviyo events/products
  getProducts: async (params) => {
    const cacheKey = `products_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () => 
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/events/products', { params });
        return response.data;
      })
    );
  },

  // Get financial performance data
  getFinancials: async (params) => {
    const cacheKey = `financials_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () =>
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/events/financials', { params });
        return response.data;
      })
    );
  },

  // Get projections - replaces klaviyo events/projection
  getProjection: async (params) => {
    const cacheKey = `projection_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () => 
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/events/projection', { params });
        return response.data;
      })
    );
  },

  getDiscountPromos: async (params = {}) => {
    const { startDate, endDate } = params || {};
    const cacheKey = `discount_promos_${startDate || 'none'}_${endDate || 'none'}`;
    return deduplicatedRequest(
      cacheKey,
      () =>
        retryRequest(
          async () => {
            const response = await acotApi.get('/api/acot/discounts/promos', {
              params: {
                ...(startDate ? { startDate } : {}),
                ...(endDate ? { endDate } : {}),
              },
              timeout: 60000,
            });
            return response.data;
          },
          0
        ),
      60 * 1000
    );
  },

  simulateDiscounts: async (payload) => {
    return retryRequest(
      async () => {
        const response = await acotApi.post('/api/acot/discounts/simulate', payload, {
          timeout: 120000,
        });
        return response.data;
      },
      0
    );
  },

  // Get employee metrics data (hours, picking, shipping) - legacy, kept for backwards compatibility
  getEmployeeMetrics: async (params) => {
    const cacheKey = `employee_metrics_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () =>
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/employee-metrics', { params });
        return response.data;
      })
    );
  },

  // Get payroll metrics data (hours, overtime, pay periods)
  getPayrollMetrics: async (params) => {
    const cacheKey = `payroll_metrics_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () =>
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/payroll-metrics', { params });
        return response.data;
      })
    );
  },

  // Get operations metrics data (picking, shipping)
  getOperationsMetrics: async (params) => {
    const cacheKey = `operations_metrics_${JSON.stringify(params)}`;
    return deduplicatedRequest(cacheKey, () =>
      retryRequest(async () => {
        const response = await acotApi.get('/api/acot/operations-metrics', { params });
        return response.data;
      })
    );
  },

  // Utility functions
  clearCache,
};

export default acotService; 
