
import axios from 'axios';

export class ImgurlBase64{
    /**
     * 单例变量声明
     *
     * @memberof ImgurlBase64
     */
    private static imgurlBase64: ImgurlBase64;

    /**
     * 图片缓存(加载中)
     *
     * @type {Map<string,any>}
     * @memberof ImgurlBase64
     */
     public static imgCache: Map<string, any> = new Map();

     /**
      * 图片缓存(已完成)
      *
      * @type {Map<string,any>}
      * @memberof ImgurlBase64
      */
     public static imgCached: Map<string, any> = new Map();

    /**
     * 获取 ImgurlBase64 单例对象
     *
     * @memberof ImgurlBase64
     */
     public static getInstance() {
        if (!this.imgurlBase64) {
            this.imgurlBase64 = new ImgurlBase64();
        }
        return this.imgurlBase64;
    }

    /**
     * 手动获取图片
     * 
     * 
     * @param url 图片url路径
     * @returns 
     */
    public async getImgURLOfBase64(url: string) {
        return new Promise((resolve, reject) => {
            let img = '/';
            // 富文本CV上传图片与鼠标移出抛值冲突问题,上传成功回调还没执行时就抛值
            var reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i;
            if (reg.test(url)) {
                return resolve(url);
            }
            // 缓存中有从缓存中拿
            if (ImgurlBase64.imgCached.get(url)) {
                let img = ImgurlBase64.imgCached.get(url);
                resolve(img);
            }
            const callback: Function = (url: string, promise: Promise<any>) => {
                promise.then((response: any) => {
                    if (response && response.status === 200 && response.data) {
                        // 获取文件名
                        const disposition = response.headers['content-disposition'];
                        const filename = disposition.split('filename=')[1];
                        let type = 'image/png';
                        if (filename && filename.indexOf('.') > 0) {
                            const start = filename.lastIndexOf('.');
                            const expandedName = filename.substring(start + 1);
                            if (expandedName.match(/(bmp|jpg|jpeg|png|tif|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF|webp)/gi) != null) {
                                type = 'image/' + expandedName;
                            } else {
                                resolve(img);
                            }
                        }
                        let blob = new Blob([response.data],{type: type});
                        this.blobToBase64(blob).then((res) => {
                            // 转化后的base64
                            img = `${res}`;
                            // 缓存图片
                            ImgurlBase64.imgCached.set(url, img);
                            resolve(img);
                        })
                    } else {
                        resolve(img);
                    }
                }).catch((result: any) => {
                    return resolve(img);
                })
            }
            // 加载中
            if (ImgurlBase64.imgCache.get(url)) {
                callback(url, ImgurlBase64.imgCache.get(url));
            } else {
                let _url = url;
                if (!Object.is('/', _url.substring(0,1))) {
                    _url = '/'+_url;
                }
                let result:Promise<any> = axios({method: 'get', url: _url, responseType: 'blob'});
                ImgurlBase64.imgCache.set(url, result);
                callback(url, result);
            }
        });
    }

    /**
     * 将blob转为base64
     * 
     * 
     * @param blob blob对象
     * @returns 
     */
    public blobToBase64(blob: any) {
        return new Promise((resolve, reject) => {
            const fileReader = new FileReader();
            fileReader.onload = (e: any) => {
                resolve(e.target.result);
            };
            // readAsDataURL
            fileReader.readAsDataURL(blob);
            fileReader.onerror = () => {
                reject(new Error('blobToBase64 error'));
            };
        });
    }
}