import {isEmptyUtils, isNotEmptyUtils, subString} from './utils';
import fetchQiniu from './fetch-qiniu.js';
import { getQiniuToken1, uploadVideo, uploadImg } from './index';
const qiniu = require('qiniu-js');

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

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

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

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

const domain1 = uploadImg(); // 图片

const 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信息已过期。']
]);

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

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

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

    // 文件全路径(文件路径 + 文件名) 扩展名​/年/月/日/
    const 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();
        }

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

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

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

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

            /*
             * qiniu.upload 返回一个 observable 对象用来控制上传行为，observable 对像通过 subscribe 方法可以被 observer 所订阅，
             * 订阅同时会开始触发上传，同时返回一个 subscription 对象，该对象有一个 unsubscribe 方法取消订阅，同时终止上传行为。
             * */
            const 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
             * */
            const next = function (res) {
                // res值{"total":{"loaded":18184,"size":18185,"percent":99.99450096233159}}

                // 获取百分比进度
                const progress = res.total.percent.toFixed(2);
                self.uploadProgress = Number(progress);
                console.log('Progress1: ' + progress);
            };

            /**
             * 接收上传完成后的后端返回信息，res 参数为一个 object， 为上传成功后后端返回的信息
             * ，具体返回结构取决于后端sdk的配置，可参考上传策略(https://developer.qiniu.com/kodo/manual/1206/put-policy)
             * */
            const 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;

                    resolve(result);
 
                    self.qiniuUploadStatus = false;

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

                        // 显示图片
                        const $img = $('<img>').attr('src', address);
                        const 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，错误信息，包含错误码，当后端返回提示信息时也会有相应的错误信息。
             * */
            const 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 + '/' + 'admin/im/' + 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();
        }
        const key = filePath ? filePath : getFilePath(file);

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

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

            /*
             * qiniu.upload 返回一个 observable 对象用来控制上传行为，observable 对像通过 subscribe 方法可以被 observer 所订阅，
             * 订阅同时会开始触发上传，同时返回一个 subscription 对象，该对象有一个 unsubscribe 方法取消订阅，同时终止上传行为。
             * */
            const 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
             * */
            const next = function (res) {
                // res值{"total":{"loaded":18184,"size":18185,"percent":99.99450096233159}}

                // 获取百分比进度
                const 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)
             * */
            const 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，错误信息，包含错误码，当后端返回提示信息时也会有相应的错误信息。
             * */
            const 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();
};
