<template>
    <div class="nus_step" v-if="list && list.length > 0"
        :class="rootClass">
        <div class="nu_step-hd">
            <template
                v-for="(item, index) in list">
                <nu-funicon
                    class="nu_step-icon"
                    :class="[_getClass(index), _getStyle(index, '', item), iconClass]"
                    :style="_getStyle(index, 'background', item)"
                    :imgUrl="item.imgUrl"
                    :icon="item.icon"
                    :key="index">
                </nu-funicon>
                <step-line
                    class="nu_step-line"
                    v-if="index < list.length - 1"
                    :class="_getClass(index)"
                    :lineBg="_getLineBg(index)"
                    :lineWidth="lineWidth"
                    :key="index + item">
                </step-line>
            </template>
        </div>
        <div class="nu_step-bd">
            <template
                v-for="(item, index) in list">
                <div class="nu_step-textCont" :key="index"
                    :class="[_getClass(index), _getStyle(index)]"
                    :style="[_getStyle(index, 'color'), textWidth]">
                    <span class="nu_step-text">{{ item && item.text }}</span>
                </div>
            </template>
        </div>
    </div>
</template>

<script>
import { prefixStyle } from 'nimble-lib';
import NuFunicon from '../funicon';
import WidgetTmp from '../_comm/WidgetTmp';
import StepLine from './stepLine/StepLine';
/**
 * 线的类型
 */
const LINE_STYLE = {
    GRADIENT: 'gradient' // 渐变色
};

export default {
    extends: WidgetTmp,
    name: 'NuStep',
    components: {
        NuFunicon,
        StepLine
    },
    props: {
        /**
         * 线的风格类型(实线(默认)solid,渐变gradient)
         */
        type: {
            type: String,
            default: 'solid'
        },
        /**
         * 自定义icon的class名称
         */
        iconClass: {
            type: String
        },
        /**
         * step的列表项
         */
        list: {
            type: Array
        },
        /**
         * 步数
         */
        step: {
            type: [Number, String],
            default: 0
        },
        /**
         * 线的背景色
         */
        lineBgs: {
            type: Object
        },
        /**
         * icon的颜色
         */
        iconColors: {
            type: Object
        },
        /**
         * 线宽
         */
        lineWidth: {
            type: [Number, String]
        },

        /**
         * 过滤方法
         */
        filterText: {
            type: Function
        }
    },
    computed: {
        /**
         * 状态值
         * @returns {Number} 状态值
         */
        myStep () {
            return (this.step * 1) || 0;
        },
        /**
         * 线的背景颜色／图片
         * @returns {Array} 线的背景颜色／图片
         */
        myLineBgs () {
            const _that = this;
            const _lineBgs = _that.lineBgs || {};
            let _unStart = _lineBgs.unStart;
            let _actived = _lineBgs.actived;
            let _end = _lineBgs.end;
            if (!_end && !_actived && !_unStart) {
                return [];
            }
            return [{
                out: _end || _actived || _unStart
            }, {
                out: _actived || _unStart || _end,
                in: _actived || _end || _unStart
            }, {
                out: _unStart || _actived || _end
            }];
        },

        /**
         * 图片／icon的颜色
         * @returns {Array} 返回过滤后的图片／icon的颜色
         */
        myIconColors () {
            const _that = this;
            let _res;
            const _iconColors = _that.iconColors;
            if (_iconColors) {
                _res = [_iconColors.unStart, _iconColors.actived, _iconColors.end];
            }
            return _res;
        },
        /**
         * 获取class名称
         * @returns {String} 返回线的class名称
         */
        rootClass () {
            return this.type === LINE_STYLE.GRADIENT ? 'nu_gradient' : '';
        },
        /**
         * 文案的宽度
         * @returns {Object} 返回图片的宽度
         */
        textWidth () {
            const _list = this.list || [];
            return {
                width: `${(100 / (_list.length - 1)).toFixed(2)}%`
            };
        }
    },
    methods: {
        /**
         * 获取index
         * @param {Number} index 索引
         * @returns {Number} 返回index
         */
        _getStatus (index) {
            const _status = this.myStep;
            let _res = 0; // 未开始
            if (_status + '' === (index + 1) + '') {
                _res = 1;
            } else if (_status > index) {
                _res = 2; // 结束
            }
            return _res;
        },

        /**
         * 获取text的样式
         * @param {Number} index 索引
         * @param {String} prop style的key
         * @param {String} item item项
         * @returns {String} 返回icon的样式
         */
        _getStyle (index, prop, item) {
            const _that = this;
            const _iconColors = _that.myIconColors || [];
            let _style;
            let textStyle = (item && item.color) || _iconColors[_that._getStatus(index)];
            if (textStyle) {
                if (_that._isColor(textStyle)) { // 颜色
                    if (prop) {
                        _style = {
                            [prop]: textStyle
                        };
                    }
                } else if (!prop) {
                    _style = textStyle;
                }
            }
            return _style;
        },

        /**
         * 获取step的className
         * @param {Number} index 索引
         * @returns {String} 返回step的className
         */
        _getClass (index) {
            let _res;
            switch (this._getStatus(index) + '') {
                case '1':
                    _res = 'nu_actived';
                    break;
                case '2':
                    _res = 'nu_end';
                    break;
            }
            return _res;
        },

        /**
         * 获取线的背景
         * @param {Number} index 索引
         * @returns {Object} 返回线的背景样式
         */
        _getLineBg (index) {
            const _that = this;
            let _res;
            if (_that.type === LINE_STYLE.GRADIENT) {
                _res = {
                    outStyle: _that._getLineGradient(index)
                };
            } else {
                let _lineBg = _that.myLineBgs[_that._getStatus(index)];
                _res = {
                    outStyle: _that._filterStyle(_lineBg && _lineBg.out),
                    inStyle: _that._filterStyle(_lineBg && _lineBg.in)
                };
            }
            return _res;
        },

        /**
         * 获取线的背景色
         * @param {String} lineBg 线的背景色／图片
         * @return {Object|String} 返回线背景色
         */
        _filterStyle (lineBg) {
            let _style;
            if (lineBg) {
                if (/(\.|\/|\\)/.test(lineBg)) { // 图片
                    _style = {
                        backgroundImage: `url(${lineBg})`
                    };
                } else if (this._isColor(lineBg)) { // 颜色
                    _style = {
                        backgroundColor: lineBg
                    };
                } else {
                    _style = lineBg;
                }
            }
            return _style;
        },
        /**
         * 获取线的渐进色
         * @param {Number} index 索引
         * @returns {Object} 返回线的渐进色
         */
        _getLineGradient (index) {
            const _that = this;
            const _iconColors = _that.myIconColors || {};
            const _list = _that.list || [];
            const _startBg = (_list[index] && _list[index].color) || _iconColors[_that._getStatus(index)];
            const _endBg = (_list[index + 1] && _list[index + 1].color) || _iconColors[_that._getStatus(index + 1)];
            let _prefix = prefixStyle('transition-property', true);
            if (_prefix) {
                _prefix = `-${_prefix.toLowerCase()}-`;
            }
            return {
                background: `${_prefix}linear-gradient(to right, ${_startBg}, ${_endBg})`
            };
        },
        /**
         * 判断是否是颜色值
         * @param {String} color 颜色值
         * @returns {Boolean} 是否是颜色值
         */
        _isColor (color) {
            color = (color || '') + '';
            return /^#[a-f0-9]+$/i.test(color) || /^(rgb|hsl)(a)?/ig.test(color);
        }
    }
};
</script>

<style lang="scss">
@import '../../../_assets/style/_iconFont.scss';
@import '../../../_assets/style/_var.scss';
@import '../../../_assets/style/_mixin.scss';

.nus_step {
    user-select: none;
    font-size: $nustep-step-text-font-size;
    &.nu_gradient {
        .nu_step-line{
            margin: 0 -2px;
            background: linear-gradient(to right, $nustep-step-unStart-bg, $nustep-step-unStart-bg);
            &.nu_end {
                background: linear-gradient(to right, $nustep-step-end-bg, $nustep-step-actived-bg);
            }
            &.nu_actived {
                background: linear-gradient(to right, $nustep-step-actived-bg, $nustep-step-unStart-bg);
            }
            .nu_line {
                display: none;
            }
        }
    }
    .nu_step-hd {
        display: flex;
        justify-content: space-around;
        align-items: center;
        color: $nustep-icon-color;
    }
    .nu_step-icon {
        position: relative;
        z-index: 1;
        border-radius: 50%;
        background-color: $nustep-step-unStart-bg;
        box-sizing: content-box;
        padding: 6px;
        &.nu_end {
            background-color: $nustep-step-end-bg;
        }
        &.nu_actived {
            background-color: $nustep-step-actived-bg;
        }
    }

    .nu_step-bd {
        margin-top: 5px;
        display: flex;
        align-items: flex-start;
        position: relative;
        justify-content: center;
        line-height: 1;
        padding: 0 1em;
    }
    .nu_step-textCont {
        text-align: center;
        color: $nustep-step-unStart-bg;
        &.nu_end {
            color: $nustep-step-end-bg;
        }
        &.nu_actived {
            color: $nustep-step-actived-bg;
        }
        &:first-child, &:last-child {
            position: absolute;
            .nu_step-text {
                width: 50%;
                display: inline-block;
            }
        }
        &:first-child {
            left: 0;
            text-align: left;
        }
        &:last-child {
            right: 0;
            text-align: right;
        }
    }
}
</style>
