<!-- 主题设置抽屉 -->
<template>
    <ele-drawer
        :size="268"
        style="max-width: 100%"
        :append-to-body="true"
        v-model="visible"
        title="主题风格设置"
        :z-index="2002"
    >
        <div :class="['setting-wrapper', { 'setting-dark': darkMode }]">
            <!-- 侧栏风格 -->
            <div class="setting-theme">
                <ele-tooltip
                    content="暗色侧栏"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-side-dark"
                        @click="updateSidebarStyle('dark')"
                    >
                        <ele-text
                            v-if="sidebarStyle === 'dark'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
                <ele-tooltip
                    content="亮色侧栏"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-side-light"
                        @click="updateSidebarStyle('light')"
                    >
                        <ele-text
                            v-if="sidebarStyle === 'light'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
            </div>
            <!-- 顶栏风格 -->
            <div class="setting-theme">
                <ele-tooltip
                    content="亮色顶栏"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-head-light"
                        @click="updateHeaderStyle('light')"
                    >
                        <ele-text
                            v-if="headerStyle === 'light'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
                <ele-tooltip
                    content="暗色顶栏"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-head-dark"
                        @click="updateHeaderStyle('dark')"
                    >
                        <ele-text
                            v-if="headerStyle === 'dark'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
                <ele-tooltip
                    content="主色顶栏"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-head-primary"
                        @click="updateHeaderStyle('primary')"
                    >
                        <ele-text
                            v-if="headerStyle === 'primary'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
            </div>
            <!-- 主题色 -->
            <div class="setting-colors">
                <div
                    v-for="item in themes"
                    :key="item.name"
                    :style="{ 'background-color': item.color || item.value }"
                    class="setting-color-item"
                    @click="updateColor(item.value)"
                >
                    <el-icon v-if="item.value ? item.value === color : !color">
                        <CheckOutlined />
                    </el-icon>
                    <ele-tooltip
                        :content="item.name"
                        placement="top"
                        :hide-after="0"
                        :offset="9"
                    >
                        <div class="setting-color-tooltip"></div>
                    </ele-tooltip>
                </div>
                <!-- 颜色选择器 -->
                <el-color-picker
                    ref="colorPickerRef"
                    v-model="colorValue"
                    :predefine="predefineColors"
                    class="setting-color-picker"
                    @change="updateColor"
                    @activeChange="handleColorChange"
                />
            </div>
            <!-- 暗黑模式 -->
            <div class="setting-item">
                <div class="setting-item-title">开启暗黑模式</div>
                <div class="setting-item-control" ref="darkSwitchRef">
                    <el-switch
                        size="small"
                        :model-value="darkMode"
                        @update:modelValue="updateDarkMode"
                    />
                </div>
            </div>
            <el-divider />
            <!-- 导航布局 -->
            <ele-text type="placeholder" class="setting-title"
                >导航模式</ele-text
            >
            <div class="setting-theme">
                <ele-tooltip
                    content="左侧菜单布局"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-side-dark setting-layout-side"
                        @click="updateLayout('default')"
                    >
                        <ele-text
                            v-if="layout === 'default'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
                <ele-tooltip
                    content="顶部菜单布局"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-head-dark setting-layout-top"
                        @click="updateLayout('top')"
                    >
                        <ele-text
                            v-if="layout === 'top'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
                <ele-tooltip
                    content="混合菜单布局"
                    placement="top"
                    :hide-after="0"
                    :offset="9"
                >
                    <div
                        class="setting-layout-mix"
                        @click="updateLayout('mix')"
                    >
                        <ele-text
                            v-if="layout === 'mix'"
                            type="primary"
                            :icon="CheckOutlined"
                        />
                    </div>
                </ele-tooltip>
            </div>
            <!-- 侧栏菜单布局 -->
            <div class="setting-item">
                <div class="setting-item-title">侧栏双排菜单</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :disabled="layout === 'top'"
                        :model-value="sidebarLayout === 'mix'"
                        @update:modelValue="updateSidebarLayout"
                    />
                </div>
            </div>
            <!-- 混合菜单分割 -->
            <div class="setting-item">
                <div class="setting-item-title">混合菜单分割</div>
                <div class="setting-item-control" style="width: 72px">
                    <el-select
                        size="small"
                        :disabled="
                            layout === 'top' ||
                            (sidebarLayout !== 'mix' && layout !== 'mix')
                        "
                        :model-value="menuItemTrigger"
                        @update:modelValue="updateMenuItemTrigger"
                        :popper-options="{ strategy: 'fixed' }"
                    >
                        <el-option value="route" label="Route" />
                        <el-option value="click" label="Click" />
                        <el-option value="hover" label="Hover" />
                    </el-select>
                </div>
            </div>
            <el-divider />
            <ele-text type="placeholder" class="setting-title"
                >更多配置</ele-text
            >
            <!-- 固定主体 -->
            <div class="setting-item">
                <div class="setting-item-title">内容区域滚动</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :model-value="fixedBody"
                        @update:modelValue="updateFixedBody"
                    />
                </div>
            </div>
            <!-- 固定顶栏 -->
            <div class="setting-item">
                <div class="setting-item-title">固定顶栏区域</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :disabled="fixedBody"
                        :model-value="fixedHeader"
                        @update:modelValue="updateFixedHeader"
                    />
                </div>
            </div>
            <!-- 固定侧栏 -->
            <div class="setting-item hidden-xs-only">
                <div class="setting-item-title">固定侧栏区域</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :model-value="fixedSidebar"
                        :disabled="fixedBody || layout === 'top'"
                        @update:modelValue="updateFixedSidebar"
                    />
                </div>
            </div>
            <!-- 图标是否置于顶栏 -->
            <div class="setting-item hidden-xs-only">
                <div class="setting-item-title">Logo置于顶栏</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :model-value="logoInHeader"
                        :disabled="layout === 'top'"
                        @update:modelValue="updateLogoInHeader"
                    />
                </div>
            </div>
            <!-- 侧栏彩色图标 -->
            <div class="setting-item">
                <div class="setting-item-title">侧栏彩色图标</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :model-value="colorfulIcon"
                        :disabled="layout === 'top'"
                        @update:modelValue="updateColorfulIcon"
                    />
                </div>
            </div>
            <!-- 侧栏排它展开 -->
            <div class="setting-item">
                <div class="setting-item-title">侧栏排它展开</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :model-value="uniqueOpened"
                        @update:modelValue="updateUniqueOpened"
                    />
                </div>
            </div>
            <!-- 内容区域铺满 -->
            <div class="setting-item hidden-xs-only">
                <div class="setting-item-title">内容区域铺满</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :model-value="fluid"
                        @update:modelValue="updateFluid"
                    />
                </div>
            </div>
            <el-divider />
            <ele-text type="placeholder" class="setting-title"
                >页签配置</ele-text
            >
            <!-- 页签 -->
            <div class="setting-item">
                <div class="setting-item-title">开启多页签栏</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :model-value="tabBar"
                        @update:modelValue="updateTabBar"
                    />
                </div>
            </div>
            <!-- 固定主页页签 -->
            <div class="setting-item">
                <div class="setting-item-title">固定主页页签</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :disabled="!tabBar"
                        :model-value="fixedHome"
                        @update:modelValue="updateFixedHome"
                    />
                </div>
            </div>
            <!-- 页签置于顶栏 -->
            <div class="setting-item">
                <div class="setting-item-title">页签置于顶栏</div>
                <div class="setting-item-control">
                    <el-switch
                        size="small"
                        :disabled="!tabBar"
                        :model-value="tabInHeader"
                        @update:modelValue="updateTabInHeader"
                    />
                </div>
            </div>
            <!-- 页签风格 -->
            <div class="setting-item">
                <div class="setting-item-title">页签显示风格</div>
                <div class="setting-item-control" style="width: 90px">
                    <el-select
                        size="small"
                        :disabled="!tabBar"
                        :model-value="tabStyle"
                        @update:modelValue="updateTabStyle"
                        :popper-options="{ strategy: 'fixed' }"
                    >
                        <el-option value="simple" label="默认" />
                        <el-option value="indicator" label="圆点" />
                        <el-option value="tag" label="标签" />
                        <el-option value="button" label="卡片" />
                    </el-select>
                </div>
            </div>
            <el-divider />
            <ele-text type="placeholder" class="setting-title"
                >其它配置</ele-text
            >
            <!-- 切换动画 -->
            <div class="setting-item">
                <div class="setting-item-title">路由切换动画</div>
                <div class="setting-item-control" style="width: 110px">
                    <el-select
                        size="small"
                        :model-value="transitionName"
                        @update:modelValue="updateTransitionName"
                        :popper-options="{ strategy: 'fixed' }"
                    >
                        <el-option value="slide-right" label="滑动消退" />
                        <el-option value="slide-bottom" label="底部消退" />
                        <el-option value="zoom-in" label="放大渐变" />
                        <el-option value="zoom-out" label="缩小渐变" />
                        <el-option value="fade" label="淡入淡出" />
                    </el-select>
                </div>
            </div>
            <el-divider />
            <!-- 重置 -->
            <div style="padding-top: 6px">
                <el-button size="small" class="ele-fluid" @click="resetSetting">
                    重置
                </el-button>
            </div>
        </div>
    </ele-drawer>
</template>

<script setup>
    import { ref, nextTick } from 'vue';
    import { storeToRefs } from 'pinia';
    import { CheckOutlined } from '@/components/icons';
    import { useThemeStore } from '@/store/modules/theme';
    import { doWithTransition } from '@/utils/common';

    /** 抽屉是否打开 */
    const visible = defineModel({ type: Boolean });

    const themeStore = useThemeStore();

    const {
        tabBar,
        layout,
        sidebarLayout,
        headerStyle,
        sidebarStyle,
        tabStyle,
        fixedHeader,
        fixedSidebar,
        fixedBody,
        fluid,
        logoInHeader,
        transitionName,
        colorfulIcon,
        uniqueOpened,
        fixedHome,
        tabInHeader,
        menuItemTrigger,
        darkMode,
        color
    } = storeToRefs(themeStore);

    /** 预设主题颜色 */
    const themes = ref([
        { name: '拂晓蓝', color: '#1677ff' },
        { name: '薄暮', value: '#5f80c7' },
        { name: '日暮', value: '#faad14' },
        { name: '火山', value: '#f5686f' },
        { name: '酱紫', value: '#9266f9' },
        { name: '极光绿', value: '#33cc99' },
        { name: '极客蓝', value: '#32a2d4' }
    ]);

    /** 颜色选择器预设颜色 */
    const predefineColors = ref([
        '#f5222d',
        '#fa541c',
        '#fa8c16',
        '#faad14',
        '#a0d911',
        '#52c41a',
        '#13c2c2',
        '#2f54eb',
        '#722ed1',
        '#eb2f96'
    ]);

    /** 颜色选择器选中颜色 */
    const colorValue = ref(void 0);

    /** 暗黑主题切换开关 */
    const darkSwitchRef = ref(null);

    const updateTabBar = (value) => {
        themeStore.setTabBar(value);
    };

    const updateLayout = (value) => {
        themeStore.setLayout(value);
    };

    const updateSidebarLayout = (value) => {
        themeStore.setSidebarLayout(value ? 'mix' : 'default');
    };

    const updateHeaderStyle = (value) => {
        themeStore.setHeaderStyle(value);
    };

    const updateSidebarStyle = (value) => {
        themeStore.setSidebarStyle(value);
    };

    const updateTabStyle = (value) => {
        themeStore.setTabStyle(value);
    };

    const updateFixedHeader = (value) => {
        themeStore.setFixedHeader(value);
    };

    const updateFixedSidebar = (value) => {
        themeStore.setFixedSidebar(value);
    };

    const updateFixedBody = (value) => {
        themeStore.setFixedBody(value);
    };

    const updateFluid = (value) => {
        themeStore.setFluid(value);
    };

    const updateLogoInHeader = (value) => {
        themeStore.setLogoInHeader(value);
    };

    const updateColorfulIcon = (value) => {
        themeStore.setColorfulIcon(value);
    };

    const updateUniqueOpened = (value) => {
        themeStore.setUniqueOpened(value);
    };

    const updateFixedHome = (value) => {
        themeStore.setFixedHome(value);
    };

    const updateTabInHeader = (value) => {
        themeStore.setTabInHeader(value);
    };

    const updateTransitionName = (value) => {
        themeStore.setTransitionName(value);
    };

    const updateMenuItemTrigger = (value) => {
        themeStore.setMenuItemTrigger(value);
    };

    const updateDarkMode = (isDark) => {
        doWithTransition(
            () => themeStore.setDarkMode(isDark),
            darkSwitchRef.value?.querySelector?.('.el-switch__action'),
            !isDark
        );
    };

    const updateColor = async (value) => {
        await themeStore.setColor(value ?? null);
        initColorValue();
    };

    const resetSetting = async () => {
        await themeStore.resetSetting();
        initColorValue();
    };

    /** 更新颜色选择器选中 */
    const initColorValue = () => {
        if (color.value && !themes.value.some((t) => t.value === color.value)) {
            colorValue.value = color.value;
        } else {
            colorValue.value = void 0;
        }
    };

    initColorValue();

    // 解决 ElColorPicker 第一次点击预设颜色未选中的问题
    const colorPickerRef = ref(null);
    const handleColorChange = (color) => {
        const index = predefineColors.value.indexOf(color.toLowerCase());
        const ins = colorPickerRef.value?.$refs?.predefine;
        if (index != -1 && ins != null && !ins.rgbaColors[index].selected) {
            nextTick(() => {
                ins.rgbaColors[index].selected = true;
            });
        }
    };
</script>

<style lang="scss" scoped>
    .setting-wrapper {
        .setting-title {
            font-size: 13px;
            margin-bottom: 14px;
        }

        /* 主题风格 */
        .setting-theme > div {
            width: 52px;
            height: 36px;
            line-height: 1;
            border-radius: var(--el-border-radius-base);
            margin: 0 20px 22px 0;
            padding: 15px 0 0 24px;
            box-sizing: border-box;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
            background: #f0f2f5;
            display: inline-block;
            vertical-align: top;
            position: relative;
            overflow: hidden;
            cursor: pointer;
            transition: background-color 0.2s;
            font-size: 16px;

            &::before,
            &::after {
                content: '';
                width: 100%;
                height: 10px;
                background: #fff;
                position: absolute;
                left: 0;
                top: 0;
                transition: background-color 0.2s;
            }

            &::after {
                width: 14px;
                height: 100%;
            }

            &.setting-side-dark::after,
            &.setting-head-dark::before,
            &.setting-layout-mix::before,
            &.setting-layout-mix::after {
                background: #001529;
            }

            &.setting-head-light::before,
            &.setting-head-dark::before,
            &.setting-head-primary::before {
                z-index: 1;
            }

            &.setting-side-light::before,
            &.setting-side-dark:not(.setting-layout-side)::before,
            &.setting-head-light::after,
            &.setting-head-dark::after,
            &.setting-head-primary::after {
                opacity: 0.4;
            }

            &.setting-head-primary::before {
                background: var(--el-color-primary) !important;
            }

            &.setting-layout-top {
                padding-left: 18px;

                &::after {
                    display: none;
                }
            }
        }

        /* 主题色选择 */
        .setting-colors {
            color: #fff;
            margin-bottom: 22px;
            line-height: 0;
        }

        .setting-color-item {
            width: 20px;
            height: 20px;
            line-height: 20px;
            border-radius: var(--el-border-radius-small);
            margin: 8px 8px 0 0;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            vertical-align: top;
            position: relative;
            text-align: center;
            cursor: pointer;

            .setting-color-tooltip {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
            }
        }

        .setting-colors .setting-color-item:last-child {
            margin-right: 0;
        }

        /* 主题配置项 */
        .setting-item {
            display: flex;
            align-items: center;
            margin-bottom: 12px;

            .setting-item-title {
                flex: 1;
                line-height: 28px;
            }

            .setting-item-control {
                line-height: 1;
            }
        }

        .el-divider.el-divider--horizontal {
            margin: 20px 0 12px 0;
            opacity: 0.6;
        }

        /* 暗黑模式 */
        &.setting-dark .setting-theme > div {
            background: #000;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);

            &::before,
            &::after {
                background: #1f1f1f;
            }

            &.setting-side-dark::after,
            &.setting-head-dark::before,
            &.setting-layout-mix::before,
            &.setting-layout-mix::after {
                background: #262626;
            }
        }

        /* 颜色选择器 */
        .setting-colors :deep(.el-color-picker) {
            margin-top: 8px;
            line-height: 0;

            .el-color-picker__trigger {
                padding: 0;
                width: 20px;
                height: 20px;
                border: none;
            }

            .el-color-picker__color {
                border: none;
            }

            .el-color-picker__empty {
                background: conic-gradient(
                    from 90deg at 50% 50%,
                    rgb(255, 0, 0) -19.41deg,
                    rgb(255, 0, 0) 18.76deg,
                    rgb(255, 138, 0) 59.32deg,
                    rgb(255, 230, 0) 99.87deg,
                    rgb(20, 255, 0) 141.65deg,
                    rgb(0, 163, 255) 177.72deg,
                    rgb(5, 0, 255) 220.23deg,
                    rgb(173, 0, 255) 260.13deg,
                    rgb(255, 0, 199) 300.69deg,
                    rgb(255, 0, 0) 340.59deg,
                    rgb(255, 0, 0) 378.76deg
                );
                height: 100%;
                width: 100%;

                & > svg {
                    display: none;
                }
            }
        }
    }
</style>
