import axios from "axios";
import { Buffer } from "buffer";
import { BaseService } from "../base/BaseService.js";
import { AircallDataManager } from "./AircallDataManager.js";

export class AircallService extends BaseService {
  constructor(config) {
    super(config);
    this.baseUrl = "https://api.aircall.io/v1";
    console.log('Initializing Aircall service with credentials:', {
      apiId: config.apiId ? 'present' : 'missing',
      apiToken: config.apiToken ? 'present' : 'missing'
    });
    this.auth = Buffer.from(`${config.apiId}:${config.apiToken}`).toString(
      "base64"
    );
    this.dataManager = new AircallDataManager(
      this.mongodb,
      this.redis,
      this.timeManager
    );

    if (!config.apiId || !config.apiToken) {
      throw new Error("Aircall API credentials are required");
    }
  }

  async getMetrics(timeRange) {
    const dateRange = await this.timeManager.getDateRange(timeRange);
    console.log('Fetching metrics for date range:', {
      start: dateRange.start.toISOString(),
      end: dateRange.end.toISOString()
    });

    return this.dataManager.getData(dateRange, async (range) => {
      const calls = await this.fetchAllCalls(range.start, range.end);
      console.log('Fetched calls:', {
        count: calls.length,
        sample: calls.length > 0 ? calls[0] : null
      });
      return calls;
    });
  }

  async fetchAllCalls(start, end) {
    try {
      let allCalls = [];
      let currentPage = 1;
      let hasMore = true;
      let totalPages = null;

      while (hasMore) {
        const response = await this.makeRequest("/calls", {
          from: Math.floor(start.getTime() / 1000),
          to: Math.floor(end.getTime() / 1000),
          order: "asc",
          page: currentPage,
          per_page: 50,
        });

        console.log('API Response:', {
          page: currentPage,
          totalPages: response.meta.total_pages,
          callsCount: response.calls?.length,
          params: {
            from: Math.floor(start.getTime() / 1000),
            to: Math.floor(end.getTime() / 1000)
          }
        });

        if (!response.calls) {
          throw new Error("Invalid API response format");
        }

        allCalls = [...allCalls, ...response.calls];
        hasMore = response.meta.next_page_link !== null;
        totalPages = response.meta.total_pages;
        currentPage++;

        if (hasMore) {
          // Rate limiting pause
          await new Promise((resolve) => setTimeout(resolve, 1));
        }
      }

      return allCalls;
    } catch (error) {
      console.error("Error fetching all calls:", error);
      throw error;
    }
  }

  async makeRequest(endpoint, params = {}) {
    try {
      console.log('Making API request:', {
        endpoint,
        params
      });
      const response = await axios.get(`${this.baseUrl}${endpoint}`, {
        headers: {
          Authorization: `Basic ${this.auth}`,
          "Content-Type": "application/json",
        },
        params,
      });
      return response.data;
    } catch (error) {
      if (error.response?.status === 429) {
        console.log("Rate limit reached, waiting before retry...");
        await new Promise((resolve) => setTimeout(resolve, 5000));
        return this.makeRequest(endpoint, params);
      }

      this.handleApiError(error, `Error making request to ${endpoint}`);
    }
  }

  validateApiResponse(response, context = "") {
    if (!response || typeof response !== "object") {
      throw new Error(`${context}: Invalid API response format`);
    }

    if (response.error) {
      throw new Error(`${context}: ${response.error}`);
    }

    return true;
  }

  getPaginationInfo(meta) {
    return {
      currentPage: meta.current_page,
      totalPages: meta.total_pages,
      hasNextPage: meta.next_page_link !== null,
      totalRecords: meta.total,
    };
  }
} 