<script setup lang="ts">
import settingsDefault from '@/settings.default';
import useMenuStore from '@/store/modules/menu';
import useSettingsStore from '@/store/modules/settings';
import eventBus from '@/utils/eventBus';
import { useClipboard } from '@vueuse/core';

defineOptions({
  name: 'AppSetting',
});

const route = useRoute();

const settingsStore = useSettingsStore();
const menuStore = useMenuStore();

const isShow = ref(false);

watch(
  () => settingsStore.settings.menu.menuMode,
  (value) => {
    if (value === 'single') {
      menuStore.setActived(0);
    } else {
      menuStore.setActived(route.fullPath);
    }
  }
);

onMounted(() => {
  eventBus.on('global-app-setting-toggle', () => {
    isShow.value = !isShow.value;
  });
});

const { copy, copied, isSupported } = useClipboard();

// watch(copied, (val) => {
//   if (val) {
//     Message.success('复制成功，请粘贴到 src/settings.ts 文件中！', {
//       zIndex: 2000,
//     })
//   }
// })

function isObject(value: any) {
  return typeof value === 'object' && !Array.isArray(value);
}
// 比较两个对象，并提取出不同的部分
function getObjectDiff(
  originalObj: Record<string, any>,
  diffObj: Record<string, any>
) {
  if (!isObject(originalObj) || !isObject(diffObj)) {
    return diffObj;
  }
  const diff: Record<string, any> = {};
  for (const key in diffObj) {
    const originalValue = originalObj[key];
    const diffValue = diffObj[key];
    if (JSON.stringify(originalValue) !== JSON.stringify(diffValue)) {
      if (isObject(originalValue) && isObject(diffValue)) {
        const nestedDiff = getObjectDiff(originalValue, diffValue);
        if (Object.keys(nestedDiff).length > 0) {
          diff[key] = nestedDiff;
        }
      } else {
        diff[key] = diffValue;
      }
    }
  }
  return diff;
}

function handleCopy() {
  copy(
    JSON.stringify(
      getObjectDiff(settingsDefault, settingsStore.settings),
      null,
      2
    )
  );
}
</script>

<template>
  <HSlideover v-model="isShow" title="应用配置">
    <div class="rounded-2 bg-rose/20 px-4 py-2 text-sm/6 c-rose">
      <p class="my-1">
        应用配置可实时预览效果，但只是临时生效，要想真正应用于项目，可以点击下方的「复制配置」按钮，并将配置粘贴到
        src/settings.ts 文件中。
      </p>
      <p class="my-1">注意：在生产环境中应关闭该模块。</p>
    </div>
    <div class="divider">颜色主题风格</div>
    <div class="flex items-center justify-center pb-4">
      <HTabList
        v-model="settingsStore.settings.app.colorScheme"
        :options="[
          { icon: 'i-ri:sun-line', label: '明亮', value: 'light' },
          { icon: 'i-ri:moon-line', label: '暗黑', value: 'dark' },
          { icon: 'i-codicon:color-mode', label: '系统', value: '' },
        ]"
        class="w-60"
      />
    </div>
    <div v-if="settingsStore.mode === 'pc'" class="divider">导航栏模式</div>
    <div v-if="settingsStore.mode === 'pc'" class="menu-mode">
      <HTooltip text="侧边栏模式 (含主导航)" placement="bottom" :delay="500">
        <div
          class="mode mode-side"
          :class="{ active: settingsStore.settings.menu.menuMode === 'side' }"
          @click="settingsStore.settings.menu.menuMode = 'side'"
        >
          <div class="mode-container" />
        </div>
      </HTooltip>
      <HTooltip text="顶部模式" placement="bottom" :delay="500">
        <div
          class="mode mode-head"
          :class="{ active: settingsStore.settings.menu.menuMode === 'head' }"
          @click="settingsStore.settings.menu.menuMode = 'head'"
        >
          <div class="mode-container" />
        </div>
      </HTooltip>
      <HTooltip text="侧边栏模式 (不含主导航)" placement="bottom" :delay="500">
        <div
          class="mode mode-single"
          :class="{ active: settingsStore.settings.menu.menuMode === 'single' }"
          @click="settingsStore.settings.menu.menuMode = 'single'"
        >
          <div class="mode-container" />
        </div>
      </HTooltip>
    </div>
    <div class="divider">导航栏</div>
    <div class="setting-item">
      <div class="label">
        主导航切换跳转
        <HTooltip
          text="开启该功能后，切换主导航时，页面自动跳转至该主导航下，次导航里第一个导航"
        >
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle
        v-model="settingsStore.settings.menu.switchMainMenuAndPageJump"
        :disabled="['single'].includes(settingsStore.settings.menu.menuMode)"
      />
    </div>
    <div class="setting-item">
      <div class="label">
        次导航保持展开一个
        <HTooltip text="开启该功能后，次导航只保持单个菜单的展开">
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle v-model="settingsStore.settings.menu.subMenuUniqueOpened" />
    </div>
    <div class="setting-item">
      <div class="label">次导航是否折叠</div>
      <HToggle v-model="settingsStore.settings.menu.subMenuCollapse" />
    </div>
    <div v-if="settingsStore.mode === 'pc'" class="setting-item">
      <div class="label">显示次导航折叠按钮</div>
      <HToggle
        v-model="settingsStore.settings.menu.enableSubMenuCollapseButton"
      />
    </div>
    <div class="setting-item">
      <div class="label">是否启用快捷键</div>
      <HToggle
        v-model="settingsStore.settings.menu.enableHotkeys"
        :disabled="['single'].includes(settingsStore.settings.menu.menuMode)"
      />
    </div>
    <div class="divider">顶栏</div>
    <div class="setting-item">
      <div class="label">模式</div>
      <HCheckList
        v-model="settingsStore.settings.topbar.mode"
        :options="[
          { label: '静止', value: 'static' },
          { label: '固定', value: 'fixed' },
          { label: '粘性', value: 'sticky' },
        ]"
      />
    </div>
    <div>
      <div class="divider">标签栏</div>
      <div class="setting-item">
        <div class="label">是否启用</div>
        <HToggle v-model="settingsStore.settings.tabbar.enable" />
      </div>
      <div class="setting-item">
        <div class="label">是否显示图标</div>
        <HToggle
          v-model="settingsStore.settings.tabbar.enableIcon"
          :disabled="!settingsStore.settings.tabbar.enable"
        />
      </div>
      <div class="setting-item">
        <div class="label">是否启用快捷键</div>
        <HToggle
          v-model="settingsStore.settings.tabbar.enableHotkeys"
          :disabled="!settingsStore.settings.tabbar.enable"
        />
      </div>
    </div>
    <div class="divider">工具栏</div>
    <div v-if="settingsStore.mode === 'pc'" class="setting-item">
      <div class="label">面包屑导航</div>
      <HToggle v-model="settingsStore.settings.toolbar.breadcrumb" />
    </div>
    <div class="setting-item">
      <div class="label">
        导航搜索
        <HTooltip text="对导航进行快捷搜索">
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle v-model="settingsStore.settings.toolbar.navSearch" />
    </div>
    <div v-if="settingsStore.mode === 'pc'" class="setting-item">
      <div class="label">全屏</div>
      <HToggle v-model="settingsStore.settings.toolbar.fullscreen" />
    </div>
    <div class="setting-item">
      <div class="label">
        页面刷新
        <HTooltip text="使用框架内提供的刷新功能进行页面刷新">
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle v-model="settingsStore.settings.toolbar.pageReload" />
    </div>
    <div class="setting-item">
      <div class="label">
        颜色主题
        <HTooltip text="开启后可在明亮/暗黑模式中切换">
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle v-model="settingsStore.settings.toolbar.colorScheme" />
    </div>
    <div class="divider">页面</div>
    <div class="setting-item">
      <div class="label">是否启用快捷键</div>
      <HToggle v-model="settingsStore.settings.mainPage.enableHotkeys" />
    </div>
    <div class="divider">导航搜索</div>
    <div class="setting-item">
      <div class="label">是否启用快捷键</div>
      <HToggle
        v-model="settingsStore.settings.navSearch.enableHotkeys"
        :disabled="!settingsStore.settings.toolbar.navSearch"
      />
    </div>
    <div class="divider">底部版权</div>
    <div class="setting-item">
      <div class="label">是否启用</div>
      <HToggle v-model="settingsStore.settings.copyright.enable" />
    </div>
    <div class="setting-item">
      <div class="label">日期</div>
      <HInput
        v-model="settingsStore.settings.copyright.dates"
        :disabled="!settingsStore.settings.copyright.enable"
      />
    </div>
    <div class="setting-item">
      <div class="label">公司</div>
      <HInput
        v-model="settingsStore.settings.copyright.company"
        :disabled="!settingsStore.settings.copyright.enable"
      />
    </div>
    <div class="setting-item">
      <div class="label">网址</div>
      <HInput
        v-model="settingsStore.settings.copyright.website"
        :disabled="!settingsStore.settings.copyright.enable"
      />
    </div>
    <div class="setting-item">
      <div class="label">备案</div>
      <HInput
        v-model="settingsStore.settings.copyright.beian"
        :disabled="!settingsStore.settings.copyright.enable"
      />
    </div>
    <div class="divider">主页</div>
    <div class="setting-item">
      <div class="label">
        是否启用
        <HTooltip
          text="该功能开启时，登录成功默认进入主页，反之则默认进入导航栏里第一个导航页面"
        >
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle v-model="settingsStore.settings.home.enable" />
    </div>
    <div class="setting-item">
      <div class="label">
        主页名称
        <HTooltip text="开启国际化时，该设置无效">
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HInput v-model="settingsStore.settings.home.title" />
    </div>
    <div class="divider">其它</div>
    <div class="setting-item">
      <div class="label">是否启用权限</div>
      <HToggle v-model="settingsStore.settings.app.enablePermission" />
    </div>
    <div class="setting-item">
      <div class="label">
        载入进度条
        <HTooltip text="该功能开启时，跳转路由会看到页面顶部有进度条">
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle v-model="settingsStore.settings.app.enableProgress" />
    </div>
    <div class="setting-item">
      <div class="label">
        动态标题
        <HTooltip
          text="该功能开启时，页面标题会显示当前路由标题，格式为“页面标题 - 网站名称”；关闭时则显示网站名称，网站名称在项目根目录下 .env.* 文件里配置"
        >
          <SvgIcon name="i-ri:question-line" />
        </HTooltip>
      </div>
      <HToggle v-model="settingsStore.settings.app.enableDynamicTitle" />
    </div>
    <template v-if="isSupported" #footer>
      <HButton block @click="handleCopy">
        <SvgIcon name="i-ep:document-copy" />
        复制配置
      </HButton>
    </template>
  </HSlideover>
</template>

<style lang="scss" scoped>
.divider {
  --at-apply: flex items-center justify-between gap-4 my-4 whitespace-nowrap
    text-sm font-500;

  &::before,
  &::after {
    --at-apply: content-empty w-full h-1px bg-stone-2 dark-bg-stone-6;
  }
}

.menu-mode {
  --at-apply: flex items-center justify-center gap-4 pb-4;

  .mode {
    --at-apply: relative w-16 h-12 rounded-2 ring-1 ring-stone-2
      dark-ring-stone-7 cursor-pointer transition;

    &.active {
      --at-apply: ring-ui-primary ring-2;
    }

    &::before,
    &::after,
    .mode-container {
      --at-apply: absolute pointer-events-none;
    }

    &::before {
      --at-apply: content-empty bg-ui-primary;
    }

    &::after {
      --at-apply: content-empty bg-ui-primary/60;
    }

    .mode-container {
      --at-apply: bg-ui-primary/20 border-dashed border-ui-primary;

      &::before {
        --at-apply: content-empty absolute w-full h-full;
      }
    }

    &-side {
      &::before {
        --at-apply: top-2 bottom-2 left-2 w-2 rounded-tl-1 rounded-bl-1;
      }

      &::after {
        --at-apply: top-2 bottom-2 left-4.5 w-3;
      }

      .mode-container {
        --at-apply: inset-t-2 inset-r-2 inset-b-2 inset-l-8 rounded-tr-1
          rounded-br-1;
      }
    }

    &-head {
      &::before {
        --at-apply: top-2 left-2 right-2 h-2 rounded-tl-1 rounded-tr-1;
      }

      &::after {
        --at-apply: top-4.5 left-2 bottom-2 w-3 rounded-bl-1;
      }

      .mode-container {
        --at-apply: inset-t-4.5 inset-r-2 inset-b-2 inset-l-5.5 rounded-br-1;
      }
    }

    &-single {
      &::after {
        --at-apply: top-2 left-2 bottom-2 w-3 rounded-tl-1 rounded-bl-1;
      }

      .mode-container {
        --at-apply: inset-t-2 inset-r-2 inset-b-2 inset-l-5.5 rounded-tr-1
          rounded-br-1;
      }
    }
  }
}

.setting-item {
  --at-apply: flex items-center justify-between gap-4 px-4 py-2 rounded-2
    transition hover-bg-stone-1 dark-hover-bg-stone-9;

  .label {
    --at-apply: flex items-center flex-shrink-0 gap-2 text-sm;

    i {
      --at-apply: text-xl text-orange cursor-help;
    }
  }
}
</style>
