import {isEmptyUtils, isNotEmptyUtils, subString} from "./utils";
import fetchQiniu from './fetch-qiniu.js';
import { getQiniuToken1, uploadVideo, uploadImg } from './index'
import fetch from "./fetch";

let fileApiUrl = getQiniuToken1()
//该对象有一个 unsubscribe 方法取消订阅，同时终止上传行为。
let subscription = null;

//上传返回结果
let result = {
    key: null,//文件保存在空间中的资源名
    path: null,//保存到db的路径(不带域名)
    fullPath: null,//文件网络路径(文件url)
    size: null,//资源尺寸，单位为字节
    name: null,//原始文件名
    ext: null//上传资源的后缀名，通过自动检测的mimeType 或者原文件的后缀来获取
};

//上传状态
// var status = false;

//FIXME 请注意vue里面不要使用全局变量
let domain = uploadVideo()  // 视频

let domain1 = uploadImg()  // 图片

let errorCode = new Map([
    [298,'部分操作执行成功'],
    [400,'请求报文格式错误'],
    [401,'认证授权失败'],
    [403,'权限不足，拒绝访问。'],
    [404,'资源不存在'],
    [405,'请求方式错误'],
    [406,'上传的数据 CRC32 校验错误'],
    [413,'请求资源大小大于指定的最大值'],
    [419,'用户账号被冻结'],
    [478,'镜像回源失败'],
    [502,'错误网关'],
    [503,'服务端不可用'],
    [504,'服务端操作超时'],
    [573,'单个资源访问频率过高'],
    [579,'上传成功但是回调失败'],
    [599,'服务端操作失败'],
    [608,'资源内容被修改'],
    [612,'指定资源不存在或已被删除'],
    [614,'目标资源已存在'],
    [630,'已创建的空间数量达到上限，无法创建新空间。'],
    [631,'指定空间不存在'],
    [640,'调用列举资源(list)接口时，指定非法的marker参数。'],
    [701,'在断点续上传过程中，后续上传接收地址不正确或ctx信息已过期。']
]);

let qiniuErrorCheck = function (code) {
    errorCode.forEach(function (value, key, map) {
        if (code === key){
            console.error(key+':'+value)
        }
    })
}

//用来限制上传文件类型，为 null 时表示不对文件类型限制；限制类型放到数组里： ["image/png", "image/jpeg", "image/gif"]
let mimeTypeArray = null;

export const createFilePath = (file, fileName) => {
    if (isEmptyUtils(file)) {
        return null;
    }
    let arr = fileName.split('_');
    if(arr.length != 4){
        alert('上传视频文件名格式不正确');
        return null;
    }
    let arr4 = arr[3].split('.');

    //文件全路径(文件路径 + 文件名) 扩展名​/年/月/日/
    let filePath = arr[0] + "/" + arr[1] + "/" + arr[2] + "_" + arr4[0] + '.'+arr4[1];
    console.log(filePath);
    return filePath;
};

/**
 * 获取七牛上传凭证
 *
 * @return {Promise} token 七牛上传凭证
 * */
const doQiniuAction1 = (fileType) => {
    console.log('send---'+fileApiUrl);
    return new Promise(function (resolve, reject) {
       // if(isEmptyUtils(localStorage.getItem('qiniuToken'))){
            fetchQiniu(fileApiUrl, {"fileType": fileType}, 'GET').then(function (result) {
                let token = null;
                if (isNotEmptyUtils(result) && result.code == "000000") {
                    token = result.data.qiniuToken;
                    resolve(token);
                    console.log('七牛临时授权成功');
                    localStorage.setItem('qiniuToken',token);
                } else {
                    reject(result);
                    console.error('七牛临时授权失败:', result);
                }
            }).catch(function (error) {
                reject();
                console.error('七牛临时授权失败:', error);
            });
        // }else{
        //     console.log('从localStorage获取token:'+localStorage.getItem('qiniuToken'))
        //     resolve(localStorage.getItem('qiniuToken'));
        // }
    });
};

/**
 *
 * @param self
 * @param file
 * @param filePath
 * @param previewId
 * @param progressId
 * @returns {Promise}
 */
export const qiniuUpload = (self, file, filePath, previewId, progressId) => {

    // var deferred = $q.defer();

    return new Promise(function (resolve, reject) {

        if (isEmptyUtils(file) || isEmptyUtils(filePath)) {
            console.error('七牛上传失败:非法参数');
            reject();
        }

        let key = filePath ? filePath : getFilePath(file);

        //修改状态为上传
        self.qiniuUploadStatus = true;


        // let token = "BRVB4TpxVFA5Wo6lIpfltmWKOltzGar46tvC3BlR:UHn0LDElwjP4jEZTXdq_1qV6_hw=:eyJzY29wZSI6InBpY2EtdGVzdCIsInJldHVybkJvZHkiOiJ7XCJrZXlcIjpcIiQoa2V5KVwiLFwiaGFzaFwiOlwiJChldGFnKVwiLFwiYnVja2V0XCI6XCIkKGJ1Y2tldClcIixcImZzaXplXCI6JChmc2l6ZSksXCJmbmFtZVwiOiQoZm5hbWUpLFwiZXh0XCI6JChleHQpfSIsImRlYWRsaW5lIjoxNTI5NDk0MTc1fQ==";
        doQiniuAction().then(function (token) {
            let putExtra = {
                fname: file.name, //原文件名
                params: {}, //用来放置自定义变量
                mimeType: mimeTypeArray || null //null || array，用来限制上传文件类型，为 null 时表示不对文件类型限制；限制类型放到数组里： ["image/png", "image/jpeg", "image/gif"]
            };

            let config = {
                useCdnDomain: true, //表示是否使用 cdn 加速域名，为布尔值，true 表示使用，默认为 false。
                region: null //选择上传域名区域；当为 null 或 undefined 时，自动分析上传域名区域
            };

            /*
             * qiniu.upload 返回一个 observable 对象用来控制上传行为，observable 对像通过 subscribe 方法可以被 observer 所订阅，
             * 订阅同时会开始触发上传，同时返回一个 subscription 对象，该对象有一个 unsubscribe 方法取消订阅，同时终止上传行为。
             * */
            let observable = qiniu.upload(file, key, token, putExtra, config);

            /**
             * 接收上传进度信息，res 参数是一个带有 total 字段的 object，包含loaded、total、percent三个属性，提供上传进
             * total.loaded: number，已上传大小，单位为字节。
             * total.total: number，本次上传的总量控制信息，单位为字节，注意这里的 total 跟文件大小并不一致。
             * total.percent: number，当前上传进度，范围：0～100
             * */
            let next = function (res) {
                //res值{"total":{"loaded":18184,"size":18185,"percent":99.99450096233159}}

                //获取百分比进度
                let progress = res.total.percent.toFixed(2);
                self.uploadProgress = Number(progress);
                console.log('Progress1: ' + progress);
                //如果有进度条
                /*if (isNotEmptyUtils(progressId)) {
                    let obj = $("#" + progressId);
                    //开始上传时,显示进度条
                    if (isNotEmptyUtils(obj.parent())) {
                        //修改状态为上传
                        // status = true;
                        self.qiniuUploadStatus = true;
                        obj.parent().removeClass("hidden");
                        obj.fadeIn("fast");
                    }
                    obj.css("width", progress + '%');
                    obj.text(progress + '%');
                    //上传完成,2秒后淡出进度条
                    if (progress === "100.00") {
                        //修改状态为非上传
                        // status = false;
                        self.qiniuUploadStatus = true;
                        obj.fadeOut(2000);
                    }
                }*/
            };

            /**
             * 接收上传完成后的后端返回信息，res 参数为一个 object， 为上传成功后后端返回的信息
             * ，具体返回结构取决于后端sdk的配置，可参考上传策略(https://developer.qiniu.com/kodo/manual/1206/put-policy)
             * */
            let complete = function (res) {
                console.log("七牛上传完成");
                setTimeout(function(){
                    result.key = res.key;
                    result.path = '/' + res.key;
                    result.fullPath = domain + '/' + res.key + '?v=' + new Date().getTime();
                    result.size = res.fsize;
                    result.name = res.fname ;
                    result.ext = res.ext;

                    // deferred.resolve(result);
                    resolve(result);
                    // self.model.qCloudUrl = result.fullPath;
                    // $("#introVideoLecture").attr("src", self.model.qCloudUrl);
                    //修改状态为非上传
                    // status = false;
                    self.qiniuUploadStatus = false;

                    if (isNotEmptyUtils(previewId)) {
                        let address = domain + result.path;
                        console.log('文件路径: ' + address);

                        //显示图片
                        let $img = $('<img>').attr("src", address);
                        let obj = $("#" + previewId);
                        obj.empty().append($img);
                        obj.css('max-width', '100%');
                    }

                },2000);

            };

            /**
             * 上传错误后触发，当不是 xhr 请求错误时，会把当前错误产生原因直接抛出，诸如 JSON 解析异常等；当产生 xhr 请求错误时，参数 err 为一个包含 code、message、isRequestError 三个属性的 object：
             * err.isRequestError: 用于区分是否 xhr 请求错误；当 xhr 请求出现错误并且后端通过 HTTP 状态码返回了错误信息时，该参数为 true；否则为 undefined 。
             * err.reqId: string，xhr请求错误的 X-Reqid。
             * err.code: number，请求错误状态码，只有在 err.isRequestError 为 true 的时候才有效，可查阅码值对应说明。
             * err.message: string，错误信息，包含错误码，当后端返回提示信息时也会有相应的错误信息。
             * */
            let error = function (err) {
                //修改状态为非上传
                // status = false;
                self.qiniuUploadStatus = false
                localStorage.removeItem('qiniuToken');
                console.log("七牛上传失败,详细信息请参考:https://developer.qiniu.com/kodo/api/3928/error-responses");
                //输出简略错误信息
                if (err.isRequestError){
                    qiniuErrorCheck(err.code)
                }else {
                    console.error(err);
                }

                /*modalClick("提示", "上传失败！", "确定", function () {
                    $('#model-modify').modal('hide');
                }, "", null);*/
                // deferred.reject(new Error('七牛上传失败'));
                // return deferred.promise;
                return reject(new Error('七牛上传失败'));
            };

            // 上传开始
            subscription = observable.subscribe(next, error, complete);


            });

        // return deferred.promise;


    });
};

/**
 * 获取时间戳
 * @param {Date} [date]日期对象,为空时,返回当前时间戳
 * @return {String} timeStamp时间戳 格式:yyyyMMddhhmmssS
 */
const timeStamp = (date) => {
    if (isEmptyUtils(date)) {
        return new Date().format('yyyyMMddhhmmssS');
    }

    return date.format('yyyyMMddhhmmssS');
}
/**
 * 获取全局唯一标识符（GUID，Globally Unique Identifier）
 * @return {String} guid
 */
const guid = () => {
    /**
     * @return {String}
     */
    function S4() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }

    return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
};
/**
 * 文件重命名--七牛图片 2018 11
 * @param {File} [file] 上传文件对象
 * @param {String} [fileName] 指定文件名
 * @param {String} [folder] 指定文件夹
 * @return {String} fileName
 */
export const getFilePath = (file,fileName,folder) => {
    if (isEmptyUtils(file)) {
        return null;
    }
    //文件类型
    var ext = file.type;
    //后缀名
    var suffix = file.name.substring(file.name.lastIndexOf(".") + 1);
    //若为空则从name中获取---对wps格式的文件获取不到file.type
    if (isEmptyUtils(ext)) {
        ext = suffix;
    }
    //获取当前日期对象
    var date = new Date();
    if (isEmptyUtils(fileName)) {
        //重命名后的文件名
        fileName = timeStamp(date) + "-" + subString(guid(), 8) + "." + suffix;
    }

    //文件全路径(文件路径 + 文件名) 扩展名​/年/月/日/
    // var filePath = ext + "/" + date.format('yyyy/MM/dd') + "/" + (isEmptyUtils(folder) ? "" : (folder + "/")) + fileName;
    //var filePath = ext + "/" + "common/" + file.name.split('.')[0] + '-' + timeStamp(date) + "." + suffix;
    var filePath = ext + "/" + "protal/project/" + timeStamp(date) + "." + suffix;
    console.log('filePath==============',filePath);
    return filePath;

}

/**
 *七牛上传图片、视频、文件 2018 11 hws
 * @param self
 * @param file
 * @param filePath
 * @param previewId
 * @param progressId
 * @param fileType 1--图片和文件   空为视频
 * @returns {Promise}
 */
export const doUpload = (self, file, filePath, previewId, progressId, fileType) => {
    return new Promise(function (resolve, reject) {
        if (isEmptyUtils(file) || isEmptyUtils(filePath)) {
            console.error('七牛上传失败:非法参数');
            reject();
        }
        let key = filePath ? filePath : getFilePath(file);

        //修改状态为上传
        self.qiniuUploadStatus = true;
        doQiniuAction1(fileType).then(function (token) {
            let putExtra = {
                fname: file.name, //原文件名
                params: {}, //用来放置自定义变量
                mimeType: mimeTypeArray || null //null || array，用来限制上传文件类型，为 null 时表示不对文件类型限制；限制类型放到数组里： ["image/png", "image/jpeg", "image/gif"]
            };

            let config = {
                useCdnDomain: true, //表示是否使用 cdn 加速域名，为布尔值，true 表示使用，默认为 false。
                region: null //选择上传域名区域；当为 null 或 undefined 时，自动分析上传域名区域
            };

            /*
             * qiniu.upload 返回一个 observable 对象用来控制上传行为，observable 对像通过 subscribe 方法可以被 observer 所订阅，
             * 订阅同时会开始触发上传，同时返回一个 subscription 对象，该对象有一个 unsubscribe 方法取消订阅，同时终止上传行为。
             * */
            let observable = qiniu.upload(file, key, token, putExtra, config);

            /**
             * 接收上传进度信息，res 参数是一个带有 total 字段的 object，包含loaded、total、percent三个属性，提供上传进
             * total.loaded: number，已上传大小，单位为字节。
             * total.total: number，本次上传的总量控制信息，单位为字节，注意这里的 total 跟文件大小并不一致。
             * total.percent: number，当前上传进度，范围：0～100
             * */
            let next = function (res) {
                //res值{"total":{"loaded":18184,"size":18185,"percent":99.99450096233159}}

                //获取百分比进度
                let progress = res.total.percent.toFixed(2);
                self.uploadProgress = Number(progress);

                if(progressId == 'uploadProgress1') {
                    self.uploadProgress1 = Number(progress);
                }
                if(progressId == 'uploadProgress2') {
                    self.uploadProgress2 = Number(progress);
                }
                console.log('Progress2: ' + progress);
            };

            /**
             * 接收上传完成后的后端返回信息，res 参数为一个 object， 为上传成功后后端返回的信息
             * ，具体返回结构取决于后端sdk的配置，可参考上传策略(https://developer.qiniu.com/kodo/manual/1206/put-policy)
             * */
            let complete = function (res) {
                console.log("七牛上传完成");
                setTimeout(function(){
                    result.key = res.key;
                    result.path = '/' + res.key;
                    if(!fileType) { // 图片  文件
                        console.log('---domain-------',domain)
                        result.fullPath = domain + '/' + res.key;
                    }else{  // 视频
                        console.log('----domain1------',domain1)
                        result.fullPath = domain1 + '/' + res.key;
                    }
                    result.size = res.fsize;
                    result.name = res.fname ;
                    result.ext = res.ext;
                    resolve(result);
                    self.qiniuUploadStatus = false;
                },500);
            };

            /**
             * 上传错误后触发，当不是 xhr 请求错误时，会把当前错误产生原因直接抛出，诸如 JSON 解析异常等；当产生 xhr 请求错误时，参数 err 为一个包含 code、message、isRequestError 三个属性的 object：
             * err.isRequestError: 用于区分是否 xhr 请求错误；当 xhr 请求出现错误并且后端通过 HTTP 状态码返回了错误信息时，该参数为 true；否则为 undefined 。
             * err.reqId: string，xhr请求错误的 X-Reqid。
             * err.code: number，请求错误状态码，只有在 err.isRequestError 为 true 的时候才有效，可查阅码值对应说明。
             * err.message: string，错误信息，包含错误码，当后端返回提示信息时也会有相应的错误信息。
             * */
            let error = function (err) {
                //修改状态为非上传
                // status = false;
                self.qiniuUploadStatus = false
                localStorage.removeItem('qiniuToken');
                console.log("七牛上传失败,详细信息请参考:https://developer.qiniu.com/kodo/api/3928/error-responses");
                //输出简略错误信息
                if (err.isRequestError){
                    qiniuErrorCheck(err.code)
                }else {
                    console.error(err);
                }
                return reject(new Error('七牛上传失败'));
            };

            // 上传开始
            subscription = observable.subscribe(next, error, complete);


            });
            // 保存到全局对象
            window.QNSubscription = subscription;
    });
};
// 取消上传
export const unsubscribe = () => {
  subscription.unsubscribe();
}
