import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {Injector} from '@angular/core';
import {MsgService} from '../msg/msg.service';
import {environment} from '../../../environments/environment';
import {FrameService} from '../frame/frame.service';
import {DomSanitizer} from '@angular/platform-browser';
import {timeout} from 'rxjs/operators';

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');

  public static http: HttpClient;
  public static injector: Injector;
  public static sanitizer: DomSanitizer;


  public static request(url: string, data: {}, callback?: Function, param?: {}) {
    // 统一记上sessionId
    if (data === undefined) {
      data = {};
    }
    if (param === undefined) {
      param = {};
    }


    data['FrameSessionId'] = FrameService.FrameSessionId;
    for (const key in data) {
      if (data[key] === 'undefined' ||  data[key] === undefined || data[key] === null) {
        delete data[key];
      }
    }

    const RequestWithLoading = param === undefined ? false : param['RequestWithLoading'];
    if (RequestWithLoading) {
      MsgService.showLoading();
    }


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

  public static requestEntity(url: string, data: {}, callback?: Function, param?: {}) {
    const obj = Object.assign({}, param, {RequestType: 'Entity'});
    return AjaxService.request(url, data, callback, obj);
  }

  public static requestArray(url: string, data: {}, callback?: Function, param?: {}) {
    const obj = Object.assign({}, param, {RequestType: 'Array'});
    return AjaxService.request(url, data, callback, obj);
  }

  public static requestMap(url: string, data: {}, callback?: Function, param?: {}) {
    const obj = Object.assign({}, param, {RequestType: 'Map'});
    return AjaxService.request(url, data, callback, obj);
  }

  public static requestPage(url: string, data: {}, callback?: Function, param?: {}) {
    const obj = Object.assign({}, param, {RequestType: 'Page'});
    return AjaxService.request(url, data, callback, obj);
  }


  // ajax下载
  public static ajaxDownload(url: string, param?: any) {
    let html = '<form action="' + environment.uploadRoot + url + '" method="post" target="_blank">';
    for (const name in param) {
      if (typeof (param[name]) !== 'function' && name !== '$$hashKey') {
        const value = param[name];
        if (value !== null && value !== undefined) {
          html = html + '<input type="hidden" name="' + name + '" value="' + value + '"/>';
        }

      }
    }
    html = html + '</form>';
    $(html).appendTo('body').submit().remove();
  }
}
