import axios, { AxiosInstance, AxiosError } from 'axios';
import { createHash } from 'crypto';
import { FeieApiConfig, FeiePrinterInfo, FeiePrintRequest, FeiePrintResponse, FeiePrinterStatusResponse, FeieOrderStatusResponse, FeieAddPrinterResponse, FeieDeletePrinterResponse } from '../types/feie.types';

export class FeieApiService {
  private client: AxiosInstance;
  private config: FeieApiConfig;
  private maxRetries: number;

  constructor(config: FeieApiConfig) {
    // 确保baseUrl有默认值
    const defaultBaseUrl = 'https://api.feieyun.cn/Api/Open/';

    this.config = {
      baseUrl: defaultBaseUrl,
      timeout: 10000,
      maxRetries: 3,
      ...config
    };

    this.maxRetries = this.config.maxRetries || 3;

    this.client = axios.create({
      baseURL: this.config.baseUrl,
      timeout: this.config.timeout,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    });
  }

  /**
   * 生成飞鹅API签名
   */
  private generateSignature(timestamp: number): string {
    const content = `${this.config.user}${this.config.ukey}${timestamp}`;
    return createHash('sha1').update(content).digest('hex');
  }

  /**
   * 执行API请求，支持重试
   */
  private async executeRequest<T>(endpoint: string, params: Record<string, any>): Promise<T> {
    const timestamp = Math.floor(Date.now() / 1000);
    const signature = this.generateSignature(timestamp);

    const requestParams = {
      user: this.config.user,
      stime: timestamp,
      sig: signature,
      ...params
    };

    let lastError: Error | null = null;

    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      try {
        const response = await this.client.post(endpoint, requestParams);

        if (response.data.ret !== 0) {
          throw new Error(`飞鹅API错误: ${response.data.msg} (ret: ${response.data.ret})`);
        }

        return response.data;
      } catch (error) {
        lastError = error as Error;

        if (attempt < this.maxRetries) {
          // 等待指数退避
          const delay = Math.pow(2, attempt) * 1000;
          await new Promise(resolve => setTimeout(resolve, delay));
          continue;
        }
      }
    }

    throw lastError || new Error('飞鹅API请求失败');
  }

  /**
   * 添加打印机
   */
  async addPrinter(printerInfo: FeiePrinterInfo): Promise<FeieAddPrinterResponse> {
    const { sn, key, name = '' } = printerInfo;
    const snlist = `${sn}#${key}#${name}`;

    return this.executeRequest<FeieAddPrinterResponse>('Open_printerAddlist', {
      printerContent: snlist
    });
  }

  /**
   * 删除打印机
   */
  async deletePrinter(sn: string): Promise<FeieDeletePrinterResponse> {
    const snlist = sn;

    return this.executeRequest<FeieDeletePrinterResponse>('Open_printerDelList', {
      snlist
    });
  }

  /**
   * 查询打印机状态
   */
  async queryPrinterStatus(sn: string): Promise<FeiePrinterStatusResponse> {
    const snlist = sn;

    return this.executeRequest<FeiePrinterStatusResponse>('Open_queryPrinterStatus', {
      snlist
    });
  }

  /**
   * 打印小票
   */
  async printReceipt(printRequest: FeiePrintRequest): Promise<FeiePrintResponse> {
    const { sn, content, times = 1 } = printRequest;

    return this.executeRequest<FeiePrintResponse>('Open_printMsg', {
      sn,
      content,
      times
    });
  }

  /**
   * 查询订单打印状态
   */
  async queryOrderStatus(orderId: string): Promise<FeieOrderStatusResponse> {
    return this.executeRequest<FeieOrderStatusResponse>('Open_queryOrderState', {
      orderid: orderId
    });
  }

  /**
   * 根据时间查询订单
   */
  async queryOrdersByDate(date: string, page: number = 1): Promise<any> {
    return this.executeRequest<any>('Open_queryOrderInfoByDate', {
      date,
      page
    });
  }

  /**
   * 批量查询打印机状态
   */
  async batchQueryPrinterStatus(snList: string[]): Promise<FeiePrinterStatusResponse> {
    const snlist = snList.join('-');

    return this.executeRequest<FeiePrinterStatusResponse>('Open_queryPrinterStatus', {
      snlist
    });
  }

  /**
   * 获取打印机在线状态
   */
  async getPrinterOnlineStatus(sn: string): Promise<boolean> {
    try {
      const response = await this.queryPrinterStatus(sn);

      if (response.data && response.data.length > 0) {
        const printerStatus = response.data[0];
        return printerStatus.online === 1;
      }

      return false;
    } catch (error) {
      console.error('获取打印机在线状态失败:', error);
      return false;
    }
  }

  /**
   * 验证打印机配置
   */
  async validatePrinterConfig(sn: string, key: string): Promise<boolean> {
    try {
      // 临时创建一个配置来测试打印机
      const tempConfig: FeieApiConfig = {
        baseUrl: this.config.baseUrl,
        user: this.config.user,
        ukey: this.config.ukey
      };

      const tempService = new FeieApiService(tempConfig);
      const response = await tempService.queryPrinterStatus(sn);

      return response.ret === 0;
    } catch (error) {
      return false;
    }
  }
}