/**
 * 购物车选择尺寸、颜色和数量面板
 * @author: feng.chen<feng.chen@yoho.cn>
 * @date: 2017/3/2
 * 示例:
 * let chosePanel = require('chose-panel-new');
 * chosePanel.show({
 *      data: {},               // 商品数据
 *      buttonText: '加入购物车', // 自定义底部按钮文字
 *      disableNum: true        // 禁用编辑数量
 * }).then((sku) => {
 *      //点击确认按钮回调,返回sku对象,各自业务在此处实现,该组件不做选择后的处理
 *      //...
 * }, () => {
 *      //关闭选择框回调
 * });
 * choselPanel.close(); //关闭选择框
 */
let $ = require('yoho-jquery'),
    tip = require('plugin/tip'),
    innerScroll = require('plugin/inner-scroll');

let panelT = require('common/chose-panel-new.hbs');

let $yohoPage = $('.yoho-page'),
    $chosePanel = $('.chose-panel'),
    $choseArea,
    $goodNum,
    $btnMinus,
    $thumbImg,
    $choseBtnSure,
    $noChoose,
    $chooseInfo;

class ChosePanel {
    constructor() {
        if (!window.cookie) {
            require('common');
        }
        this.C_ID = window._ChannelVary[window.cookie('_Channel')];
        this._regEvents();
    }
    show(opt) {
        if (!opt) {
            $('.chose-panel').show();
            return new Promise((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            });
        }
        Object.assign(this, opt);
        if (!this.data) {
            throw new Error('未赋值');
        }
        if (this.data) {
            this._setModes();
            this.maxBuyNum = this.data.cartInfo.limit || 0; // 0表示不限制购买
            this.skus = this.data.cartInfo.skus || [];
            this.props = this.data.cartInfo.props || [];
            this.buyNum = this._defaultBuyNum();
            this.minBuyNum = (this.modes.discount && this.data.discountBuy.num) || 1;
            this.setting = {
                disableNum: this.disableNum,
                noChoseText: `请选择${this.props.map(prop => prop.name).join('、')}`,
                buttonText: this.buttonText || this._getButtonText(),
                buyNum: this.buyNum
            };
        }

        this._render();
        return new Promise((resolve, reject) => {
            this._resolve = resolve;
            this._reject = reject;
        });
    }
    close() {
        innerScroll.enableScroll($choseArea);
        $('.chose-panel').hide();
    }

    /**
     * 设置商品模式
     */
    _setModes() {
        this.modes = { // 商品特性
            discount: this.data.discountBuy ? true : false, // 量贩
            tickets: this.data.tickets ? true : false, // 门票
            limitCode: this.data.cartInfo.limitProductCode ? true : false, // 限购
            limit: this.data.cartInfo.limit ? true : false, // 限制购买数量
            soonSoldOut: $('.soon-sold-out-tag').length ? true : false, // 即将售罄
            seckill: $('.seckill-time').length ? true : false, // 秒杀
            disableNum: this.disableNum, // 禁用编辑
            showBuyNow: this.data.showBuyNow // 是否显示双按钮
        };
    }
    _render() {
        let html;

        html = panelT(Object.assign(this.data, this.setting));
        if ($chosePanel.length) {
            $chosePanel.replaceWith(html);
        } else {
            $yohoPage.append(html);
        }

        this._setVariable();
        this._initBlockStatus();
        innerScroll.disableScroll($choseArea);
    }
    _getButtonText() {
        if (this.modes.showBuyNow) {
            return {
                double: true,
                text: '加入购物车'
            };
        }
        if (this.modes.tickets || this.modes.limitCode || this.modes.seckill) {
            return {
                double: false,
                text: '立即购买'
            };
        }
        return {
            double: false,
            text: '加入购物车'
        };
    }
    _defaultBuyNum() {
        return (this.modes.discount && this.data.discountBuy.num) ||
            (this.data.cartInfo && this.data.cartInfo.num) || 1;
    }

    /**
     * 初始化属性按钮状态不满足库存的灰色
     */
    _initBlockStatus() {
        // 获取sku列表中库存小于最小购买数量的属性,如果在其他sku中它们没有满足购买数量条件的可以灰色
        let noStorageSkus = this.skus.filter(sku => sku.storage < this.minBuyNum);

        $chosePanel.find('.thumb').attr('src', this.data.cartInfo.defaultThumb);

        $('.block').removeClass('zero-stock');
        noStorageSkus.forEach(sku => {
            for (let propType in sku.prop) {
                if (propType) {
                    let prop = sku.prop[propType];
                    let zeroStock = !this.skus.some(_ => _.prop[propType].valId === prop.valId &&
                    _.storage >= this.minBuyNum);
                    let $block = $(`.block[data-prop-id="${propType}"][data-value-id="${prop.valId}"]`);

                    if (zeroStock) {
                        $block.addClass('zero-stock');
                    } else {
                        $block.removeClass('zero-stock');
                    }
                }
            }
        });
    }
    _setVariable() {
        $chosePanel = $('.chose-panel');
        $choseArea = $('.chose-panel .main .chose-items');
        $goodNum = $('#good-num');
        $btnMinus = $('.btn-minus');
        $thumbImg = $('.thumb-img');
        $choseBtnSure = $('#chose-btn-sure');
        $noChoose = $('.not-choose');
        $chooseInfo = $('.choosed-info');
    }
    _regEvents() {
        $yohoPage.on('touchstart', '.chose-panel', (e) => {
            return this._closeClick(e);
        });
        $yohoPage.on('touchstart', '.block', (e) => {
            this._blockClick(e);
        });
        $yohoPage.on('touchstart', '.btn-plus,.btn-minus', (e) => {
            this._numClick(e);
        });
        $yohoPage.on('touchstart', '.thumb-img .thumb', (e) => {
            this._thumbClick(e);
        });
        $yohoPage.on('touchstart', '#chose-btn-sure', (e) => {
            return this._choseBtnSureClick(e, false);
        });
        $yohoPage.on('touchstart', '#chose-btn-buynow', (e) => {
            let sku = this._checkSku(this.buyNum);

            if (window._yas && window._yas.sendCustomInfo) {
                window._yas.sendCustomInfo({
                    op: 'YB_GDS_BUYNOW_BTN',
                    param: JSON.stringify({
                        C_ID: this.C_ID,
                        PRD_ID: this.data.cartInfo.productId,
                        PRD_NUM: this.buyNum,
                        PRD_SKN: this.data.cartInfo.productSkn,
                        PRD_SKU: sku && sku.skuId
                    })
                }, true);
            }

            return this._choseBtnSureClick(e, true);
        });
    }

    /**
     * 点击关闭按钮
     */
    _closeClick(e) {
        let $cur = $(e.target);

        if ($cur.closest('.main').length > 0 && !$cur.hasClass('close')) {
            return;
        }
        this.close();
        this._reject && this._reject();
        return false;
    }

    /**
     * 点击属性
     */
    _blockClick(e) {
        let $block = $(e.currentTarget);

        if ($block.hasClass('chosed')) {
            $block.removeClass('chosed');
        } else {
            $block.addClass('chosed').siblings().removeClass('chosed');
        }
        this._selectBlock($block);
    }

    /**
     * 点击数量加减
     */
    _numClick(e) {
        let buyNum;

        if (this.modes.disableNum) {
            return;
        }
        buyNum = $(e.currentTarget).hasClass('btn-minus') ? this.buyNum - 1 : this.buyNum + 1;
        if (this._checkSku(buyNum)) {
            this.buyNum = buyNum;
            $goodNum.val(this.buyNum);
            if (this.modes.discount) {
                if (buyNum <= this.minBuyNum) {
                    $('.btn-minus').addClass('discount-gray');
                } else {
                    $('.btn-minus').removeClass('discount-gray');
                }
            }
        }
    }

    /**
     * 点击缩略图
     */
    _thumbClick() {
        if ($thumbImg.hasClass('hover')) {
            $thumbImg.removeClass('hover');
        } else {
            $thumbImg.addClass('hover');
        }
    }

    /**
     * 点击确定或者立即购买按钮
     */
    _choseBtnSureClick(e, buyNow) {
        let selectSku = this._checkSku(this.buyNum);

        if (selectSku) {
            this.close();
            this._resolve && this._resolve({
                sku: selectSku,
                skn: this.data.cartInfo.productSkn,
                productId: this.data.cartInfo.productId,
                buyNum: this.buyNum,
                modes: this.modes,
                buyNow: buyNow
            });
            return false;
        }
    }

    /**
     * 验证选择sku的购买数量是否通过
     */
    _checkSku(buyNum) {
        if ($('.block.chosed.zero-stock').length) {
            return false;
        }
        let validSelects = this.props
            .filter(prop => !$(`.block[data-prop-id="${prop.type}"]`).hasClass('chosed'))
            .map(prop => {
                return prop.name;
            });

        if (validSelects.length) {
            tip.show(`请选择${validSelects.join('和')}~`);
            return false;
        }
        let selectSku = this._getSelectSku();

        if (!selectSku) {
            tip.show('无法选择该属性的商品');
            return false;
        }
        if (buyNum < this.minBuyNum) {
            if (this.modes.discount) {
                tip.show(`量贩商品,${this.minBuyNum}件起购`);
                return false;
            } else {
                tip.show('您选择的数量不能为零~');
                return false;
            }
        }
        if (this.modes.tickets && buyNum > selectSku.limitNum) {
            if (selectSku.limitNum) {
                tip.show(`每人只可购买${selectSku.limitNum}张此门票`);
                return false;
            }
        }
        if (this.modes.limit && buyNum > this.maxBuyNum) {
            tip.show('您选择数量大于限购数量~');
            return false;
        }
        if (buyNum > selectSku.storage) {
            tip.show('您选择的数量超过了最大库存量~');
            return false;
        }
        return selectSku;
    }

    /**
     * 选择属性
     */
    _selectBlock($selectBlock) {
        let that = this;
        let propId = $selectBlock.data('prop-id'),
            valueId = $selectBlock.data('value-id');
        let chosed = $($selectBlock).hasClass('chosed');

        if ($('.block.chosed').length === 0) {
            this._initBlockStatus();
        } else {
            // 根据选择的属性值筛选出符合条件的sku列表,然后遍历其他属性如果在sku列表中不存在该属性值,则灰色
            let filterSkus = this.skus.filter(sku => (!chosed || sku.prop[propId].valId === valueId) &&
                sku.storage >= this.minBuyNum);
            let filterProps = this.props.filter(prop => prop.type !== propId);

            filterProps.forEach(prop => {
                $(`.block[data-prop-id="${prop.type}"]`).each((i, ele) => {
                    let $block = $(ele);
                    let valId = $block.data('value-id');
                    let existsSku = filterSkus.some(sku => sku.prop[prop.type].valId === valId);
                    let fsku = that.skus.filter(sku => sku.prop[propId].valId === valueId &&
                        sku.prop[prop.type].valId === valId);
                    let limitTip = '';

                    if (!existsSku) {
                        $block.addClass('zero-stock');
                        if (fsku.length && fsku[0].limitBuyTip) {
                            limitTip = fsku[0].limitBuyTip;
                        }
                    } else {
                        $block.removeClass('zero-stock');
                    }

                    $block.data('limittip', limitTip);
                });
            });
        }
        if (window._yas && window._yas.sendCustomInfo && chosed) {
            if (propId === 'color') {
                window._yas.sendCustomInfo({
                    op: 'YB_GDS_COLOR_C',
                    param: JSON.stringify({
                        C_ID: this.C_ID,
                        PRD_ID: this.data.cartInfo.productId,
                        COLOR: $selectBlock.text()
                    })
                }, true);
            } else if (propId === 'size') {
                window._yas.sendCustomInfo({
                    op: 'YB_GDS_SIZE_C',
                    param: JSON.stringify({
                        C_ID: this.C_ID,
                        PRD_ID: this.data.cartInfo.productId,
                        SIZE: $selectBlock.text()
                    })
                }, true);
            }
        }

        this._refreshBlockStatus();
    }

    /**
     * 选择属性后刷新其他属性的状态
     */
    _refreshBlockStatus() {
        let selectSku = this._getSelectSku();
        let $zeroChose = $('.block.chosed.zero-stock');

        // 设置底部按钮文字
        if ($zeroChose.length) {
            let tipText = '已售罄';

            if ($zeroChose.data('limittip')) {
                tipText = $zeroChose.data('limittip');
            }

            $choseBtnSure.css('background-color', '#c0c0c0').text(tipText);
        } else {
            $choseBtnSure.css('background-color', '#eb0313').text(this.setting.buttonText.text);
        }

        // 设置默认购买数量
        this.buyNum = this._defaultBuyNum();
        $goodNum.val(this.buyNum);
        if (this.modes.discount) {
            $btnMinus.addClass('discount-gray');
        }

        // 根据颜色属性设置缩略图
        let $colorBlock = $('.block.chosed[data-prop-id="color"]');

        if ($colorBlock.length) {
            let colorSkus = this.skus.filter(sku => sku.prop.color &&
                sku.prop.color.valId === $colorBlock.data('value-id'));

            if (colorSkus.length) {
                let thumb = colorSkus[0].thumb;

                if (!thumb) {
                    thumb = this.data.cartInfo.defaultThumb;
                }
                $chosePanel.find('.thumb').attr('src', thumb);
            }
        }

        // 设置选择属性提示
        let valueList = Array.from($('.block.chosed').map((index, ele) => {
            return $(ele).text();
        }));

        // if (this.modes.tickets) {
        //     let $chosed = $('.block.chosed');

        //     valueList = Array.from($chosed.not('.hide').map((index, ele) => {
        //         return $(ele).text();
        //     }));
        // }

        if (valueList.length) {
            $noChoose.addClass('hide');
            $chooseInfo.removeClass('hide');
            $chooseInfo.text(`已选:${valueList.join('、')}`);
        } else {
            $noChoose.removeClass('hide');
            $chooseInfo.addClass('hide');
        }

        if (selectSku) {
            // 设置left-num文字
            // let cartInfo = this.data.cartInfo,
            //     numText;
            let numText;

            if (selectSku.limitNum) {
                if (selectSku.limitNum) {
                    numText = `限购${selectSku.limitNum}件`;
                } else {
                    numText = '';
                }
            } else if (this.modes.soonSoldOut) {
                numText = '即将售罄';
            } else if (selectSku.storage < 4 && selectSku.storage > 0) {
                numText = `剩余${selectSku.storage}件`;
            } else {
                numText = '';
            }
            $chosePanel.find('.left-num').text(numText);
            $chosePanel.find('.size-info').text(selectSku.sizeInfo).removeClass('hide');
            $chosePanel.find('.size-rec').text(selectSku.sizeRec || '').removeClass('hide');
        } else {
            $chosePanel.find('.left-num').text('');
            $chosePanel.find('.size-info').text('').addClass('hide');
            $chosePanel.find('.size-rec').text('').addClass('hide');
        }
    }

    /**
     * 根据已选择的属性值获得符合条件的sku
     */
    _getSelectSku() {
        let selectValues,
            selectSku;

        if ($('.block.chosed').length !== this.props.length) {
            return;
        }
        selectValues = Array.from($('.block.chosed').map((index, ele) => {
            let $block = $(ele);

            return {
                propId: $block.data('prop-id'),
                valueId: $block.data('value-id')
            };
        }));
        selectSku = this.skus.filter(sku => {
            return selectValues
                .map(value => {
                    return sku.prop[value.propId].valId === value.valueId;
                })
                .filter(match => match).length === this.props.length;
        });
        if (selectSku.length >= 1) {
            return selectSku[0];
        }
        return;
    }
}


module.exports = new ChosePanel();