import {HttpHeaders, HttpParams} from "@angular/common/http";
import {VarService} from "./var.service";
import {MsgService} from "./msg.service";
import {environment} from "../../../environments/environment";
import {timeout} from "rxjs/operators";
import {FrameService} from "./frame.service";

/***************************
 * 提供 Ajax 静态服务
 */
export class AjaxService {
  /**************************
   * 所有的请求通用头部
   */
  private static HEADERS = new HttpHeaders()
    .set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8')
    .set('Accept', 'application/json, text/javascript, */*; q=0.01')
    .set('X-Requested-With', 'XMLHttpRequest');

  /************************
   * Ajax请求
   */
  public static request(url: string, data = {}, callback: Function = () => {
  }, param = {}) {
    // 统一记上sessionId
    data['FrameSessionId'] = VarService.SESSION_ID;
    for (const key in data) {
      // 判断属性里是否有 undefined 的，有直接移除
      if (data[key] === 'undefined' || data[key] === undefined || data[key] === null) {
        delete data[key];
      } 
      /**
      else if (Array.isArray(data[key])) {
        // 处理数组，如果是数组，判断数组类型
        if (data[key].length === 0)
          delete data[key];
        else {
          const tmp = data[key][0];
          if (typeof tmp !== 'string' && typeof tmp === 'number') {
            // 复杂数组，统一用json格式提交
            data[key] = JSON.stringify(data[key]);
          }
        }
      }
      */
    }
    // 是否显示操作等待界面
    if (param['RequestWithLoading']) {
      MsgService.showLoading();
    }


    VarService.HTTP_CLIENT.post(environment.webRoot + url, new HttpParams({
      fromObject: data
    }), {headers: AjaxService.HEADERS}).pipe(timeout(FrameService.ParamMap['AjaxTimeout'] | 60000))
      .subscribe(
        (response: any) => {
          // 根据不同参数，返回不同的对象
          if (response.success) {
            let responseObj = response;
            const requestType = param['RequestType'];
            if (requestType === 'Entity') {
              responseObj = response.entity;
            } else if (requestType === 'Array') {
              responseObj = response.array;
            } else if (requestType === 'Page') {
              responseObj = response.page;
            } else if (requestType === 'Map') {
              responseObj = response.map;
            }
            if (callback) {
              callback.call(undefined, responseObj);
            }
          } else {
            if (response['login'] === false) {
              MsgService.errorAlert(response.errorMsg, () => {
                window.location.href = './assets/login/login.html';
              });
              return;
            }
            const msgType = param['MsgType'] || 'Toaster';
            const msgFlag = param['MsgFlag'] || true;
            const errorCallback = param['ErrorCallback'];
            // 业务错误
            // 是否需要提示错误信息
            if (errorCallback) {
              errorCallback.call(undefined, response);
            }
            if (msgFlag) {
              if (msgType === 'Toaster') {
                MsgService.errorToastr(response.errorMsg);
              } else if (msgType === 'Swal') {
                MsgService.errorAlert(response.errorMsg);
              } else if (msgType === 'Alert') {
                alert(response.errorMsg);
              }
            }
          }
        }, () => {
          if (param['RequestWithLoading']) {
            MsgService.hideLoading();
          }
          const errorCallback = param['ErrorCallback'];
          // 业务错误
          // 是否需要提示错误信息
          if (errorCallback) {
            errorCallback.call(undefined);
          }
          // 未能正常请求，包括路径不存在 404错误，等其他非业务错误
          MsgService.errorAlert('网络错误，请稍后重试！');
        }, () => {
          if (param['RequestWithLoading']) {
            MsgService.hideLoading();
          }
        });
  }

  /**************************
   * ajax 获取一个对象
   */
  public static requestEntity(url: string, data = {}, callback: Function = () => {
  }, param = {}) {
    const obj = Object.assign({}, param, {RequestType: 'Entity'});
    return AjaxService.request(url, data, callback, obj);
  }

  /**************************
   * ajax 获取一个数组
   */
  public static requestArray(url: string, data = {}, callback: Function = () => {
  }, param = {}) {
    const obj = Object.assign({}, param, {RequestType: 'Array'});
    return AjaxService.request(url, data, callback, obj);
  }

  /**************************
   * ajax 获取一个map对象
   */
  public static requestMap(url: string, data = {}, callback: Function = () => {
  }, param = {}) {
    const obj = Object.assign({}, param, {RequestType: 'Map'});
    return AjaxService.request(url, data, callback, obj);
  }

  /**************************
   * ajax 获取一个page对象
   */
  public static requestPage(url: string, data = {}, callback: Function = () => {
  }, param = {}) {
    const obj = Object.assign({}, param, {RequestType: 'Page'});
    return AjaxService.request(url, data, callback, obj);
  }


  /***************************
   * 通用ajax请求
   * @param url
   * @param data
   * @param param
   * @param options
   */
  public static ajaxRequest(url: string, data: {}, param?: { successMsg?: string, successMsgType?: string, confirmMsg?: string, callback?: Function, showMsg?: boolean }, options?: { RequestWithLoading?: boolean }) {
    if (options === undefined)
      options = {};
    if (options.RequestWithLoading === undefined)
      options.RequestWithLoading = true;
    const confirmMsg = param ? param.confirmMsg : undefined;
    const showMsg = param ? param.showMsg : true;

    const fn = () => {
      AjaxService.request(url, data, (response) => {
        const successMsg = param ? (param.successMsg ? param.successMsg : '操作成功') : '操作成功';
        if (successMsg && showMsg) {
          const successMsgType = param ? (param.successMsgType ? param.successMsgType : 'Toaster') : 'Toaster';
          if (successMsgType === 'Toaster') {
            MsgService.successToastr(successMsg);
          } else if (successMsgType === 'Swal') {
            MsgService.successAlert(successMsg);
          } else {
            alert(successMsg);
          }
        }
        const callback = param ? param.callback : undefined;
        if (callback) {
          callback.call(undefined, response);
        }
      }, options);
    };

    if (confirmMsg) {
      MsgService.confirmAlert(confirmMsg, fn);
    } else {
      fn.call(undefined);
    }

  }

}
