import WebApi from '../ajax/webapi';
import Exception from '../exception';

class Request extends WebApi {
  constructor(config: TspFrameworkRequestConfig) {
    super(config.apiHost, { dbName: config.dbName, tableName: config.tableName || 'api' });

    this.config = config;
    this.timeoutStr = config.timeoutStr || '网络请求超时';
    this.send = this.send.bind(this);
  }

  private config: TspFrameworkRequestConfig;
  /**
   * 超时的提示文字
   */
  private timeoutStr: string;
  /**
   * ajaxurl格式化
   */
  private ajaxUrlFormat(params: ApiSendParams): string {
    let apiUrl;
    if (params.api.indexOf('://') >= 0) {
      apiUrl = params.api;
    } else {
      apiUrl = this.config.apiHost + params.api;
    }

    return apiUrl;
  }

  /**
   * 超时的回调
   */
  private timeoutCallback(e: Error, params: ApiSendParams, defaultCallbackEnable: boolean = true): void {
    const timeoutStr = params.timeoutStr ? params.timeoutStr : this.timeoutStr;
    if (timeoutStr !== 'none' && defaultCallbackEnable && this.config.timeoutCallback) {
      this.config.timeoutCallback(timeoutStr);
    }
    if (params.timeoutCallback) {
      params.timeoutCallback();
      Exception.send({
        errorType: 3,
        details: JSON.stringify(params.params),
        url: this.ajaxUrlFormat(params),
        content: `type: ${params.type || 'POST'}`
      });
    }
  }

  /**
   * 请求成功后的回调
   */
  private successCallback(result: object, status: boolean, params: ApiSendParams): void {
    try {
      if (params.success) {
        params.success(result, status);
      }
    } catch (e) {
      Exception.catchSend(e);
    }
  }

  /**
   * 请求接口
   */
  public send(params: ApiSendParams): void {
    this.post({
      api: params.api,
      type: params.type,
      timeout: params.timeout ? params.timeout : 0,
      params: params.params ? params.params : {},
      contentType: params.contentType,
      customHeader: params.customHeader || this.config.customHeader,
      timeoutCallback: (e) => {
        if (this.timeoutCallback) {
          this.timeoutCallback(e, params);
        }
      },
      success: (result: any, status) => this.successCallback(result, status, params),
      complete: params.complete,
      isCache: params.isCache,
      cacheReadSuccess: params.cacheReadSuccess
    });
  }
}

export default Request;