<template>
  <div class="app-wrapper">
    <!-- 遮罩层 -->
    <div
      v-if="device === 'mobile' && sidebar.opened"
      class="drawer-bg"
      @click="handleClickOutside"
    />
    <!-- 左侧侧边栏 -->
    <sidebar v-if="!sidebar.hide" />
    <!-- 右侧主容器 -->
    <div class="main-wrapper">
      <!-- 顶部导航栏 -->
      <navbar @setLayout="setLayout" />
      <!-- 内容区 -->
      <div :class="{ 'hasTagsView': needTagsView }" class="content-wrapper">
        <!-- 标签栏 -->
        <div v-if="needTagsView" :class="{ 'fixed-header': fixedHeader }">
          <tags-view />
        </div>
        <!-- 主内容 -->
        <app-main />
      </div>
    </div>
    <!-- 设置组件 -->
    <settings ref="settingRef" />
    <!-- 公告弹窗组件 -->
    <notice-popup ref="noticePopupRef" />
  </div>
</template>

<script setup>
import {useWindowSize} from '@vueuse/core';
import Sidebar from './components/Sidebar/index.vue';
import {AppMain, Settings, TagsView, Navbar} from './components';
import NoticePopup from '@/components/NoticePopup/index.vue';

import useAppStore from '@/store/modules/app';
import useSettingsStore from '@/store/modules/settings';

const settingsStore = useSettingsStore();
const theme = computed(() => settingsStore.theme);
const sideTheme = computed(() => settingsStore.sideTheme);
const sidebar = computed(() => useAppStore().sidebar);
const device = computed(() => useAppStore().device);
const needTagsView = computed(() => settingsStore.tagsView);
const fixedHeader = computed(() => settingsStore.fixedHeader);

const { width } = useWindowSize();
const WIDTH = 992; // refer to Bootstrap's responsive design

watchEffect(() => {
  if (device.value === 'mobile' && sidebar.value.opened) {
    useAppStore().closeSideBar({ withoutAnimation: false });
  }
  if (width.value - 1 < WIDTH) {
    useAppStore().toggleDevice('mobile');
    useAppStore().closeSideBar({ withoutAnimation: true });
  } else {
    useAppStore().toggleDevice('desktop');
  }
});

function handleClickOutside() {
  useAppStore().closeSideBar({ withoutAnimation: false });
}

const settingRef = ref(null);
const noticePopupRef = ref(null);

function setLayout() {
  settingRef.value.openSetting();
}

// 暴露公告弹窗引用，供其他组件调用
defineExpose({
  noticePopupRef
});
</script>

<style lang="scss" scoped>
@import '@/assets/styles/mixin.scss';
@import '@/assets/styles/variables.module.scss';

.app-wrapper {
  @include clearfix;
  width: 100%;
  height: 100%;
  display: flex;
  overflow: hidden;
}

.drawer-bg {
  background: #000;
  opacity: 0.3;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
}

.main-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

.navbar-container {
  height: 50px;
  width: 100%;
  flex-shrink: 0;
  background: #fff;
}

.content-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
  padding-top: 0;
}

.fixed-header {
  position: fixed;
  top: 50px;
  right: 0;
  left: 0;
  z-index: 9;
  width: 100%;
  padding: 0 15px;
  background: #fff;
}

.sidebarHide {
  .sidebar-container {
    display: none;
  }
}

.mobile {
  .main-wrapper {
    margin-left: 0;
  }
}
</style>
