import get from 'lodash/get'
import './index.scss'
import imageLoad from './imageLoad'
import Modal,{Confirm} from '@core/component/modal';
import Message from '@core/component/message';
import {fetch} from '@core/component/httpClient';
import Loading from '@core/component/loading';
import BaseTool from '@core/util/baseTool';
import DateUtil from '@core/util/dateUtil';
import { mattingLayoutTpl } from './tpl'
import Domain from '@core/util/domain'
const DefaultConfig = {
    tpl: mattingLayoutTpl,
    mattingUrl: `${Domain.node}/api/image/matting.json`,
    compressUrl: `${Domain.node}/api/image/compressImageDownload.json`,
    uploadBase64Image: Domain.material + '/shopImg/uploadByStr',
    getToken: Domain.material + '/token/getToken',
    maxImageSize: 1000 * 1024, 
    onlySureBtn: false,
    mattingImage: '', 
    mattingColor: '', 
    ensureBtnText: '使用',
    cancelBtnText: '取消',
    ensureCallback: null,
    cancelCallback: null,
}
class ImageMatting {
    constructor(options) {
        this.loading = null
        this._getConfig(options)
    }
    _getConfig(options) {
        $.extend(true, this, DefaultConfig, options || {})
    }
    
    showLoading(loadingText) {
        this.loading = new Loading({
            zIndex: BaseTool.getLoadingIndex(),
            text: loadingText,
        })
        this.loading.show()
    }
    
    hideLoading() {
        if (this.loading) {
            this.loading.dispose()
            this.loading = null
        }
    }
    
    removeProtocol(url) {
        if (url.match(/^http:|^https:/i) !== null) {
            url = url.replace(/^http:|^https:/i, '')
        }
        return url
    }
    open(opt) {
        let _this = this
        let _checkImgUrl = opt.url.match(/jfs\/[^>]*/)
        this._getConfig(opt)
        if (_checkImgUrl && _checkImgUrl.length) {
            console.log('opt.url:', opt.url)
            fetch({
                url: _this.mattingUrl,
                showLoading: '正在抠图中，请稍候...',
                method: 'post',
                timeout: 15000,
                data: {
                    urls: [this.removeProtocol(opt.url)],
                },
            })
                .then((result) => {
                    if (result.success) {
                        _this.openMattingDialog(opt, result.data)
                    }
                })
                .catch((result) => {
                    Message.error(result.message || '抠图失败，请稍后再试')
                })
        } else {
            Message.error('该图片地址不符合抠图规则，建议下载后重新上传！')
        }
    }
    
    openMattingDialog(opt, data) {
        const _this = this
        const mattingUrl = get(data, '[0].matting', '')
        _this.mattingImage = mattingUrl
            ? `//img30.360buyimg.com/sku/${mattingUrl}`
            : ''
        _this.mattingPicDialog = new Modal({
            title: '抠图结果',
            type: Modal.ModalType.TYPE_FULL_SCREEN,
            className: 'zb-image-matting-dialog',
            content: template.render(_this.tpl, {
                imageUrl: opt.url,
                imageMattingUrl: _this.mattingImage,
            }),
            footer: {
                show: true,
                suctionBottom: true,
                okLabel: _this.ensureBtnText,
                cancelLabel: _this.cancelBtnText,
            },
            onDomReady: function ($dialog) {
                _this._event($dialog)
            },
            onClose: (closeType) => {
                if (closeType === Modal.CloseType.TYPE_OK) {
                    _this._ensureCallback()
                }
            },
        })
    }
    _event($dialog) {
        let _this = this
        $dialog.on('click.matting', '.J_mattingSelectType', function () {
            let _selectMattingColor = $(this).val()
            _this.mattingColor = _selectMattingColor
            if (_selectMattingColor != '-1') {
                $dialog
                    .find('.J_mattingImgShow')
                    .css('background', _selectMattingColor)
                _this._playCanvas(_selectMattingColor, _this.mattingImage)
            } else {
                $dialog
                    .find('.J_mattingImgShow img')
                    .attr('src', _this.mattingImage)
                $dialog.find('.J_mattingImgShow')[0].style = ''
            }
        })
    }
    _ensureCallback() {
        let _this = this
        if (_this.mattingColor && _this.mattingColor != '-1') {
            _this._upLoadBaee64Image(
                {
                    base64: _this.canvasDataUrl, 
                },
                (result) => {
                    _this._callEnsureCallback(result)
                },
            )
        } else {
            $.get(`${_this.mattingImage}!imginfo`)
                .done(function (data) {
                    if (data && data.fileSize) {
                        let thisImgSize = data.fileSize
                        if (thisImgSize > _this.maxImageSize) {
                            _this._getImagesCompressDataToUrl(
                                _this.mattingImage,
                                (imageData) => {
                                    _this._callEnsureCallback(imageData)
                                },
                            )
                        } else {
                            _this._callEnsureCallback({
                                url: _this.mattingImage,
                                width: data.width,
                                height: data.height,
                            })
                        }
                    }
                })
                .fail(function (error) {
                    imageLoad(_this.mattingImage, (w, h) => {
                        _this._callEnsureCallback({
                            url: _this.mattingImage,
                            width: w,
                            height: h,
                        })
                    })
                })
        }
    }
    _callEnsureCallback(data) {
        typeof this.ensureCallback == 'function' &&
            this.ensureCallback.call(this.mattingPicDialog, data)
    }
    
    _openReduceQuality(imgFullUrl, toUploadImage, callback) {
        const _this = this
        new Confirm({
            content: '该图片大于1M最大限制，需要进行降质压缩转换？',
            title: '如果图片为透明背景，将转换为白色背景',
            onClose: function (flag) {
                if (flag == Modal.CloseType.TYPE_OK) {
                    _this._playCanvas(
                        '#fff',
                        imgFullUrl,
                        (canvasData) => {
                            if (toUploadImage) {
                                _this._upLoadBaee64Image(
                                    {
                                        base64: canvasData,
                                    },
                                    (data) => {
                                        $.isFunction(callback) && callback(data)
                                    },
                                )
                            } else {
                                $.isFunction(callback) && callback(canvasData)
                            }
                        },
                        '该图片超过1M，正在降质压缩转换，请稍候...',
                    )
                }
            },
        })
    }
    
    _getImagesCompressDataToUrl(url, callback, toUploadImage = true) {
        let _this = this
        fetch({
            showLoading: '该图片超过1M，正在压缩图，请稍候...',
            url: this.compressUrl,
            timeout: '25000',
            contentType: 'application/json;charset=utf-8',
            data: JSON.stringify({
                imgList: [url],
                toUploadImage: true,
            }),
            errorHandler: () => {},
        })
            .then((result) => {
                if (result.code == 0) {
                    let imageSize = result.data.imgSize
                    if (imageSize > _this.maxImageSize) {
                        _this._openReduceQuality(
                            result.data.imgFullUrl,
                            toUploadImage,
                            callback,
                        )
                    } else {
                        _this._getImageUrlToBlobData(
                            result.data.imgFullUrl,
                            (blobData) => {
                                _this._blobDataToBase64(
                                    blobData,
                                    function (baes64Data) {
                                        if (toUploadImage) {
                                            _this._upLoadBaee64Image(
                                                {
                                                    base64: baes64Data,
                                                },
                                                (data) => {
                                                    $.isFunction(callback) &&
                                                        callback(data)
                                                },
                                            )
                                        } else {
                                            $.isFunction(callback) &&
                                                callback(baes64Data)
                                        }
                                    },
                                )
                            },
                        )
                    }
                } else {
                    _this._openReduceQuality(url, toUploadImage, callback)
                }
            })
            .catch(() => {
                _this._openReduceQuality(url, toUploadImage, callback)
            })
    }
    
    _blobDataToBase64(imgBlob, callback) {
        let createFileReader = new FileReader()
        createFileReader.onload = function (e) {
            let base64Data = e.target.result
            $.isFunction(callback) && callback(base64Data || null)
        }
        createFileReader.readAsDataURL(imgBlob)
    }
    
    _getImageUrlToBlobData(url, successCallback, failBack) {
        let xhr = new XMLHttpRequest()
        xhr.open('get', url, true)
        xhr.responseType = 'blob'
        xhr.onload = function () {
            if (this.readyState == 4 && this.status == 200) {
                let thisImgBlob = this.response
                $.isFunction(successCallback) && successCallback(thisImgBlob)
            }
        }
        xhr.onerror = function (e) {
            $.isFunction(failBack) && failBack(e)
            console.log('请求图片失败', e)
        }
        xhr.send()
    }
    
    _upLoadBaee64Image(opt = { base64: '' }, successBack, failBack) {
        const _getImageType = opt.base64.match(/data:image\/(.+);base64/)
        const _base64ImageType = _getImageType ? _getImageType[1] : 'png'
        const fileName = `${DateUtil.formatDate(
            null,
            'YYYYMMDDhhmmss',
        )}抠图图片.${_base64ImageType}`
        opt.name = fileName
        this.upLoadToPicCenter(0, opt)
            .then((result) => {
                if (result.code == 0 && result.data) {
                    const imgData = result.data
                    typeof successBack == 'function' &&
                        successBack({
                            name: fileName,
                            url: imgData.url,
                            width: imgData.width,
                            height: imgData.height,
                        })
                } else {
                    console.log(result)
                    Message.error(result.desc || '图片上传，请稍后再试')
                    typeof failBack == 'function' && failBack(result)
                }
            })
            .catch((result) => {
                console.log(result)
                Message.error(result.desc || '图片上传，请稍后再试')
                typeof failBack == 'function' && failBack(result)
            })
    }
    
    upLoadToPicCenter(zTreeSelectId, picInfo) {
        const self = this
        return new Promise((resolve, reject) => {
            let submitData = {
                fileName: picInfo.name,
                cateId: zTreeSelectId,
            }
            if (picInfo.base64.indexOf('data:image') === 0) {
                submitData.imageBytes = picInfo.base64.replace(
                    /^data:image\/\w+;base64\,/,
                    '',
                ) 
            }
            if (!/\.(png|jpeg|jpg)/.test(picInfo.name)) {
                let getImgType = picInfo.base64.match(
                        /^data:image\/(\w+);base64\,/,
                    ),
                    setImgType = getImgType[1] || 'jpg'
                setImgType == 'jpeg' && (setImgType = 'jpg')
                submitData.fileName = `${submitData.fileName}.${setImgType}`
            }
            fetch({
                showLoading: '正在上传图片，请稍候...',
                url: self.getToken,
                method: 'post',
                dataType: 'json',
                contentType: 'application/json;charset=utf-8',
                xhrFields: {
                    withCredentials: true,
                },
            })
                .then((result) => {
                    fetch({
                        showLoading: '正在上传图片，请稍候...',
                        url: self.uploadBase64Image,
                        method: 'post',
                        headers: {
                            materialtoken: result.data,
                        },
                        dataType: 'json',
                        contentType: 'application/json;charset=utf-8',
                        xhrFields: {
                            withCredentials: true,
                        },
                        data: JSON.stringify(submitData),
                    })
                        .then((data) => {
                            resolve(data)
                        })
                        .catch((e) => {
                            reject(e)
                        })
                })
                .catch((e) => {
                    reject(e)
                })
        })
    }
    
    _playCanvas(color, url, callback = null, showTip = null) {
        let _this = this
        _this.showLoading(showTip)
        let thisCanvas = document.createElement('canvas')
        this.loadImg = new Image()
        this.loadImg.crossOrigin = 'anonymous' 
        this.loadImg.src = url
        this.loadImg.onload = function () {
            thisCanvas.width = this.width
            thisCanvas.height = this.height
            let cxt = thisCanvas.getContext('2d')
            thisCanvas.getContext('2d').fillStyle = color
            thisCanvas.getContext('2d').fillRect(0, 0, this.width, this.height)
            cxt.drawImage(this, 0, 0, this.width, this.height)
            let tempBase64 = '',
                t = 1
            do {
                tempBase64 = thisCanvas.toDataURL('image/jpeg', t)
                t = t - 0.05
            } while (tempBase64.length > _this.maxImageSize)
            console.log('画布kb大小----' + tempBase64.length / 1024)
            _this.hideLoading()
            if (callback && $.isFunction(callback)) {
                callback(tempBase64)
            } else {
                _this.canvasDataUrl = tempBase64
                _this.mattingPicDialog.$dialog
                    .find('.J_mattingImgShow img')
                    .attr('src', _this.canvasDataUrl)
                _this.mattingPicDialog.$dialog.find(
                    '.J_mattingImgShow',
                )[0].style = ''
            }
        }
    }
}
let createImageMattingInstance = new ImageMatting()
export default createImageMattingInstance