import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { AppEnvironment } from '../../environments/AppEnvironment';
import { NzNotificationService } from 'ng-zorro-antd/notification';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class Http {

    /**
     * 状态信息
     *
     * @private
     * @static
     * @memberof Http
     */
    private codeMessage = {
        200: '服务器成功返回请求的数据。',
        201: '新建或修改数据成功。',
        202: '一个请求已经进入后台排队（异步任务）。',
        204: '删除数据成功。',
        400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
        401: '用户没有权限（令牌、用户名、密码错误）。',
        403: '用户得到授权，但是访问是被禁止的。',
        404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
        406: '请求的格式不可得。',
        410: '请求的资源被永久删除，且不会再得到的。',
        422: '当创建一个对象时，发生一个验证错误。',
        500: '服务器发生错误，请检查服务器。',
        502: '网关错误。',
        503: '服务不可用，服务器暂时过载或维护。',
        504: '网关超时。',
    };

    /**
     * Creates an instance of Http.
     * @param {HttpClient} http
     * @memberof Http
     */
    constructor(private http: HttpClient, private Notification: NzNotificationService) { }

    /**
     * 有加载动画的POST请求
     *
     * @param {string} url 请求地址
     * @param {*} [params={}] 请求参数
     * @returns {Observable<any>}
     * @memberof Http
     */
    public post(url: string, params: any = {}, showBusyIndicator?: boolean, serialnumber?: number): Promise<any> {
        return this.results(url, params);
    }

    /**
     * 发送http请求
     *
     * @private
     * @param {string} url
     * @param {*} [params={}]
     * @returns {Promise<any>}
     * @memberof Http
     */
    private results(url: string, params: any = {}): Promise<any> {
        return new Promise((resolve, reject) => {
            this.http.post(url, params).subscribe(
                (response: any) => {
                    resolve(response);
                },
                (response) => {
                    const errorText = this.codeMessage[response.status] || response.statusText;
                    this.Notification.error('', `请求错误 ${response.status}: ${errorText}`);
                    reject(response);
                    const error: any = new Error(errorText);
                    error.name = response.status;
                    error.response = response;
                    throw error;
                }
            );
        });
    }

    /**
     * GET请求
     *
     * @param {string} url 请求地址
     * @returns
     * @memberof Http
     */
    public get(url: string, params?: any, showBusyIndicator?: boolean): Promise<any> {
        return new Promise((resolve, reject) => {
            this.http.get(url).subscribe(
                (response: any) => {
                    resolve(response);
                },
                (response) => {
                    reject(response);
                }
            );
        });
    }

    /**
     * 格式化http请求数据
     *
     * @private
     * @param {*} [opt={}]
     * @returns {HttpParams}
     * @memberof Http
     */
    private transformationOpt(opt: any = {}): HttpParams {
        const params: any = {};
        // 获取srfloginkey
        const loginkey: string | null = window.localStorage.getItem('srfloginkey');
        if (loginkey) {
            params.srfloginkey = loginkey;
        }
        // 添加appdata数据
        // const srfappdata: string = this.App.getAppData();
        // if (srfappdata) {
        //     params.srfappdata = srfappdata;
        // }
        Object.assign(params, opt);
        const keys: string[] = Object.keys(params);
        keys.forEach((key: string) => {
            params[key] = this.recursionToString(params[key]);
        });
        return new HttpParams({ 'fromObject': params });
    }

    /**
     * 递归转换对象为字符串
     *
     * @param {*} val
     * @returns {string}
     * @memberof Http
     */
    public recursionToString(val: any): string {
        if (val && !Object.is(val, '')) {
            if (val instanceof Array) {
                val.forEach((item: any) => {
                    item = this.recursionToString(item);
                });
                return JSON.stringify(val);
            }
            if (val instanceof Object) {
                const childKeys: string[] = Object.keys(val);
                childKeys.forEach((childKey: string) => {
                    val[childKey] = this.recursionToString(val[childKey]);
                });
                return JSON.stringify(val);
            }
        }
        return val;
    }

    /**
     * 
     *
     * @returns {Promise<any>}
     * @memberof Http
     */
    public mask() {
        // return this.Loading.mask();
    }

    /**
     * 
     *
     * @returns {Promise<any>}
     * @memberof Http
     */
    public unmask() {
        // return this.Loading.unmask();
    }

}