<template>
    <div class="side-setting">
        <setting-item>
            <a-button @click="saveSetting" type="primary" icon="save">{{ $t('save') }}</a-button>
            <a-button @click="resetSetting" type="dashed" icon="redo" style="float: right">
                {{ $t('reset') }}
            </a-button>
        </setting-item>
        <setting-item :title="$t('theme.title')">
            <img-checkbox-group
                @change="values => setTheme({ ...theme, mode: values[0] })"
                :default-values="[theme.mode]"
            >
                <img-checkbox
                    :title="$t('theme.dark')"
                    img="https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg"
                    value="dark"
                />
                <img-checkbox
                    :title="$t('theme.light')"
                    img="https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg"
                    value="light"
                />
            </img-checkbox-group>
        </setting-item>
        <setting-item :title="$t('theme.color')">
            <color-checkbox-group
                @change="(values, colors) => setTheme({ ...theme, color: colors[0] })"
                :defaultValues="[palettes.indexOf(theme.color)]"
                :multiple="false"
            >
                <color-checkbox
                    v-for="(color, index) in palettes"
                    :key="index"
                    :color="color"
                    :value="index"
                />
            </color-checkbox-group>
        </setting-item>
        <a-divider />
        <setting-item :title="$t('navigate.title')">
            <img-checkbox-group @change="values => setLayout(values[0])" :default-values="[layout]">
                <img-checkbox
                    :title="$t('navigate.side')"
                    img="https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg"
                    value="side"
                />
                <img-checkbox
                    :title="$t('navigate.head')"
                    img="https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg"
                    value="head"
                />
                <img-checkbox
                    :title="$t('navigate.mix')"
                    img="https://gw.alipayobjects.com/zos/antfincdn/x8Ob%26B8cy8/LCkqqYNmvBEbokSDscrm.svg"
                    value="mix"
                />
            </img-checkbox-group>
        </setting-item>
        <setting-item>
            <a-list :split="false">
                <a-list-item>
                    {{ $t('navigate.content.title') }}
                    <a-select
                        :getPopupContainer="getPopupContainer"
                        :value="pageWidth"
                        @change="setPageWidth"
                        class="select-item"
                        size="small"
                        slot="actions"
                    >
                        <a-select-option value="fluid">{{ $t('navigate.content.fluid') }}</a-select-option>
                        <a-select-option value="fixed">{{ $t('navigate.content.fixed') }}</a-select-option>
                    </a-select>
                </a-list-item>
                <a-list-item>
                    {{ $t('navigate.fixedHeader') }}
                    <a-switch :checked="fixedHeader" slot="actions" size="small" @change="setFixedHeader" />
                </a-list-item>
                <a-list-item>
                    {{ $t('navigate.fixedSideBar') }}
                    <a-switch :checked="fixedSideBar" slot="actions" size="small" @change="setFixedSideBar" />
                </a-list-item>
            </a-list>
        </setting-item>
        <a-divider />
        <setting-item :title="$t('other.title')">
            <a-list :split="false">
                <a-list-item>
                    {{ $t('other.multiPages') }}
                    <a-switch :checked="multiPage" slot="actions" size="small" @change="setMultiPage" />
                </a-list-item>
                <a-list-item>
                    {{ $t('other.hideSetting') }}
                    <a-switch :checked="hideSetting" slot="actions" size="small" @change="setHideSetting" />
                </a-list-item>
            </a-list>
        </setting-item>
        <a-divider />
        <setting-item :title="$t('animate.title')">
            <a-list :split="false">
                <a-list-item>
                    {{ $t('animate.disable') }}
                    <a-switch
                        :checked="animate.disabled"
                        slot="actions"
                        size="small"
                        @change="val => setAnimate({ ...animate, disabled: val })"
                    />
                </a-list-item>
                <a-list-item>
                    {{ $t('animate.effect') }}
                    <a-select
                        :value="animate.name"
                        :getPopupContainer="getPopupContainer"
                        @change="val => setAnimate({ ...animate, name: val })"
                        class="select-item"
                        size="small"
                        slot="actions"
                    >
                        <a-select-option :key="index" :value="item.name" v-for="(item, index) in animates">{{
                            item.alias
                        }}</a-select-option>
                    </a-select>
                </a-list-item>
                <a-list-item>
                    {{ $t('animate.direction') }}
                    <a-select
                        :value="animate.direction"
                        :getPopupContainer="getPopupContainer"
                        @change="val => setAnimate({ ...animate, direction: val })"
                        class="select-item"
                        size="small"
                        slot="actions"
                    >
                        <a-select-option :key="index" :value="item" v-for="(item, index) in directions">{{
                            item
                        }}</a-select-option>
                    </a-select>
                </a-list-item>
            </a-list>
        </setting-item>
    </div>
</template>

<script>
import SettingItem from './SettingItem';
import { ColorCheckbox, ImgCheckbox } from '@/components/checkbox';
import { mapState, mapMutations } from 'vuex';
import { settingConfig } from '@/config';
import fastEqual from 'fast-deep-equal';
import settingI18n from './i18n';

const ColorCheckboxGroup = ColorCheckbox.Group;
const ImgCheckboxGroup = ImgCheckbox.Group;

/**
 * 把对象按照 js配置文件的格式进行格式化
 * @param obj 格式化的对象
 * @param dep 层级，此项无需传值
 * @returns {string}
 */
function formatConfig(obj, dep) {
    dep = dep || 1;
    const LN = '\n',
        TAB = '  ';
    let indent = '';
    for (let i = 0; i < dep; i++) {
        indent += TAB;
    }
    let isArray = false,
        arrayLastIsObj = false;
    let str = '',
        prefix = '{',
        subfix = '}';
    if (Array.isArray(obj)) {
        isArray = true;
        prefix = '[';
        subfix = ']';
        str = obj
            .map((item, index) => {
                let format = '';
                if (typeof item == 'function') {
                    //
                } else if (typeof item == 'object') {
                    arrayLastIsObj = true;
                    format = `${LN}${indent}${formatConfig(item, dep + 1)},`;
                } else if ((typeof item == 'number' && !isNaN(item)) || typeof item == 'boolean') {
                    format = `${item},`;
                } else if (typeof item == 'string') {
                    format = `'${item}',`;
                }
                if (index == obj.length - 1) {
                    format = format.substring(0, format.length - 1);
                } else {
                    arrayLastIsObj = false;
                }
                return format;
            })
            .join('');
    } else if (typeof obj != 'function' && typeof obj == 'object') {
        str = Object.keys(obj)
            .map((key, index, keys) => {
                const val = obj[key];
                let format = '';
                if (typeof val == 'function') {
                    //
                } else if (typeof val == 'object') {
                    format = `${LN}${indent}${key}: ${formatConfig(val, dep + 1)},`;
                } else if ((typeof val == 'number' && !isNaN(val)) || typeof val == 'boolean') {
                    format = `${LN}${indent}${key}: ${val},`;
                } else if (typeof val == 'string') {
                    format = `${LN}${indent}${key}: '${val}',`;
                }
                if (index == keys.length - 1) {
                    format = format.substring(0, format.length - 1);
                }
                return format;
            })
            .join('');
    }
    const len = TAB.length;
    if (indent.length >= len) {
        indent = indent.substring(0, indent.length - len);
    }
    if (!isArray || arrayLastIsObj) {
        subfix = LN + indent + subfix;
    }
    return `${prefix}${str}${subfix}`;
}

export default {
    name: 'Setting',
    i18n: settingI18n,
    components: { ImgCheckboxGroup, ImgCheckbox, ColorCheckboxGroup, ColorCheckbox, SettingItem },
    data() {
        return {};
    },
    computed: {
        directions() {
            return this.animates.find(item => item.name == this.animate.name).directions;
        },
        ...mapState('settingModule', [
            'theme',
            'layout',
            'animate',
            'animates',
            'palettes',
            'multiPage',
            'fixedHeader',
            'fixedSideBar',
            'hideSetting',
            'pageWidth',
        ]),
    },
    watch: {
        'animate.name': function(val) {
            this.setAnimate({ name: val, direction: this.directions[0] });
        },
    },
    methods: {
        getPopupContainer() {
            return this.$el.parentNode;
        },
        saveSetting() {
            const closeMessage = this.$message.loading(this.$t('saveTips'), 0);
            const config = this.extractConfig(true);
            localStorage.setItem(process.env.VUE_APP_SETTING_KEY, JSON.stringify(config));
            setTimeout(closeMessage, 800);
        },
        resetSetting() {
            this.$confirm({
                title: this.$t('resetTips'),
                onOk() {
                    localStorage.removeItem(process.env.VUE_APP_SETTING_KEY);
                    window.location.reload();
                },
            });
        },
        //提取配置
        extractConfig(local = false) {
            let config = {};
            let mySetting = this.$store.state.settingModule;
            let dftSetting = local ? settingConfig : settingConfig;
            Object.keys(mySetting).forEach(key => {
                const dftValue = dftSetting[key],
                    myValue = mySetting[key];
                if (dftValue != undefined && !fastEqual(dftValue, myValue)) {
                    config[key] = myValue;
                }
            });
            return config;
        },
        ...mapMutations('settingModule', [
            'setTheme',
            'setLayout',
            'setMultiPage',
            'setWeekMode',
            'setFixedSideBar',
            'setFixedHeader',
            'setAnimate',
            'setHideSetting',
            'setPageWidth',
        ]),
    },
};
</script>

<style lang="less" scoped>
.side-setting {
    min-height: 100%;
    background-color: @base-bg-color;
    padding: 24px;
    font-size: 14px;
    line-height: 1.5;
    word-wrap: break-word;
    position: relative;
    .flex {
        display: flex;
    }
    .select-item {
        width: 80px;
    }
}
</style>
