import axios, { AxiosInstance, AxiosError } from "axios";
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";

export class UpworkClient {
  private static instance: UpworkClient;
  private client: AxiosInstance;
  private apiKey: string;
  private apiSecret: string;
  private accessToken: string;

  constructor() {
    // Get credentials from environment variables
    this.apiKey = process.env.UPWORK_API_KEY || "";
    this.apiSecret = process.env.UPWORK_API_SECRET || "";
    this.accessToken = process.env.UPWORK_ACCESS_TOKEN || "";

    if (!this.apiKey || !this.apiSecret) {
      throw new Error("UPWORK_API_KEY and UPWORK_API_SECRET environment variables are required");
    }

    // Initialize Upwork API client
    this.client = axios.create({
      baseURL: "https://www.upwork.com/api",
      timeout: 30000,
      headers: {
        "Authorization": `Bearer ${this.accessToken}`,
        "Content-Type": "application/json",
        "User-Agent": "ChillMCP-Upwork/1.0.0"
      },
    });
  }

  public getClient(): AxiosInstance {
    return this.client;
  }

  public static getInstance(): UpworkClient {
    if (!UpworkClient.instance) {
      UpworkClient.instance = new UpworkClient();
    }
    return UpworkClient.instance;
  }

  public async get(endpoint: string, params?: any): Promise<any> {
    try {
      const response = await this.client.get(endpoint, { params });
      return response.data;
    } catch (error) {
      throw this.handleError(error);
    }
  }

  public async post(endpoint: string, data?: any): Promise<any> {
    try {
      const response = await this.client.post(endpoint, data);
      return response.data;
    } catch (error) {
      throw this.handleError(error);
    }
  }

  public handleError(error: any): McpError {
    if (axios.isAxiosError(error)) {
      const axiosError = error as AxiosError;
      
      if (axiosError.response) {
        const status = axiosError.response.status;
        const data = axiosError.response.data as any;
        
        switch (status) {
          case 401:
            return new McpError(
              ErrorCode.InvalidRequest,
              "Authentication failed. Please check your API credentials."
            );
          case 403:
            return new McpError(
              ErrorCode.InvalidRequest,
              "Access forbidden. Please check your API permissions."
            );
          case 404:
            return new McpError(
              ErrorCode.InvalidRequest,
              "Resource not found."
            );
          case 429:
            return new McpError(
              ErrorCode.InvalidRequest,
              "Rate limit exceeded. Please try again later."
            );
          default:
            return new McpError(
              ErrorCode.InternalError,
              `Upwork API error: ${data?.message || axiosError.message}`
            );
        }
      }
      
      return new McpError(
        ErrorCode.InternalError,
        `Network error: ${axiosError.message}`
      );
    }
    
    return new McpError(
      ErrorCode.InternalError,
      `Unexpected error: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}