<template>
  <el-container ref="main" v-show="!flag.loading" class="root-container">
    <el-header v-show="state.size.headHeight != '0px'" class="app-head" :height="state.size.headHeight">
      <Head :title="title" :logo="logo" :username="username">
        <template #left>
          <MenuTree v-show="mode == 'horizontal'" :data="menus" mode="horizontal" />
        </template>
        <HeadPersonal @updatePwd="updatePwd" @logout="onLogout" :center="center" />
        <Fullscreen />
        <StyleChange v-if="styleAble" />
        <LangChange v-if="langAble" />
        <SizeChange v-if="sizeAble" />
      </Head>
    </el-header>
    <el-container id="container">
      <el-aside v-show="mode == 'vertical' && state.size.asideWidth != '0px'" :width="state.size.asideWidth">
        <MenuTree :data="menus" mode="vertical">
          <template #footer>
            <div>v{{ VITE_APP_VERSION }}-{{ VITE_GIT_HASH.substring(0, 8) }}</div>
            <template v-if="NODE_ENV != 'production'">
              <div>dev-{{ DEV_MODE_TS }}</div>
            </template>
          </template>
        </MenuTree>
      </el-aside>
      <el-main class="app-main">
        <router-view />
      </el-main>
    </el-container>
  </el-container>
</template>

<script lang="ts" setup>
import { onBeforeUnmount, onMounted, reactive, ref, watch, computed } from "vue";
import { useStore } from "vuex";
import { useRouter, useRoute } from "vue-router";
import { Api, NoobHead } from "noob-mengyxu";
import { md5 } from "js-md5";

const DEV_MODE_TS = "2026-03-26T08:35:00.000Z";
const { VITE_APP_VERSION, VITE_GIT_HASH, NODE_ENV } = import.meta.env;
const { Head, MenuTree, HeadPersonal, Fullscreen, StyleChange, LangChange, SizeChange } = NoobHead;

const { state, commit, dispatch } = useStore();
const emit = defineEmits(["updatePwd", "logout"]);
const router = useRouter();
const route = useRoute();
const main = ref();
const flag = reactive({
  showHeader: true,
  showAside: true,
  loading: false,
});
let interval = 0;

const props = defineProps({
  title: {
    type: String,
    default: null,
  },
  menus: {
    type: Array<any>(),
    default: null,
  },
  mode: {
    type: String,
    default: "vertical",
  },
  styleAble: {
    type: Boolean,
    default: true,
  },
  sizeAble: {
    type: Boolean,
    default: true,
  },
  langAble: {
    type: Boolean,
    default: true,
  },
  center: {
    type: String,
    default: "home",
  },
  checkUser: {
    type: Boolean,
    default: true,
  },
  username: {
    type: String,
    default: null,
  },
  closeAble: {
    type: Boolean,
    default: false,
  },
  logo: {
    type: String,
    default: null,
  },
});

const onResize = () => {
  const height = window.innerHeight;
  commit("initSize", [height, window.innerWidth]);
};

const getUser = (first?) => {
  if (!props.checkUser) return;
  if (first) flag.loading = true;

  Api.pub.getInfo().then((rsp) => {
    if (first) flag.loading = false;
    if (rsp) {
      if (state.user?.userId !== rsp.userId) {
        commit("updateState", ["user", rsp]);
      }
    } else {
      router.push("/login");
    }
  });
};

const onLogout = () => {
  Api.pub.logout().then((rsp) => {
    getUser();
    emit("logout");
  });
};

const updatePwd = (pwd) => {
  pwd.old = md5(pwd.old);
  pwd.new = md5(pwd.new);
  pwd.reNew = md5(pwd.reNew);
  emit("updatePwd", pwd);
  Api.user.updatePwd(pwd);
};

onMounted(() => {
  // router.push("/"); // redundant - already navigated from login
  dispatch("getMenus");
  getUser(); // Don't show loading screen after successful login
  interval = setInterval(getUser, 5000);
  window.onresize = onResize;
  onResize();
});

// Watch for navigation from login page
watch(
  () => route.path,
  (newPath, oldPath) => {
    if (oldPath === "/login" && newPath !== "/login" && !state.user?.userId) {
      getUser();
      interval = setInterval(getUser, 5000);
    }
  }
);

onBeforeUnmount(() => {
  clearInterval(interval);
});
</script>

<style lang="scss">
body {
  font-size: v-bind("state.size.fontSize") !important;
  font-family: "Microsoft YaHei";
  width: 100%;
  min-height: 100vh;
  overflow: hidden;
  padding: 0px;
  margin: 0px;
}
</style>

<style lang="scss" scoped>
.root-container {
  min-height: 100vh !important;
  height: 100vh !important;
  max-height: 100vh !important;
  display: flex !important;
  flex-direction: column !important;
  overflow: hidden !important;
  background-color: v-bind("state.style.bodyBg");
}

#container {
  flex: 1 1 auto !important;
  min-height: 0 !important;
  overflow: hidden !important;
}

.app-main {
  box-shadow: 2px 2px 5px 3px #e5e6eb;
  border-radius: 4px;
  margin: 0px 0px 0px 3px !important;
  padding: 0 !important;
  flex: 1 1 auto !important;
  min-height: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  overflow-y: auto !important;
}

.el-header,
.main-head,
.main-table {
  padding: 0;
}

#container,
.app-main {
  background-color: v-bind("state.style.bodyBg");
  color: v-bind("state.style.color");
  font-size: v-bind("state.size.fontSize");
}

.app-head {
  padding: 0px !important;
  background-color: v-bind("state.style.headBg");
  height: v-bind("state.size.headHeight");
}

:deep(.head-icon) {
  float: right;
  cursor: pointer;
  height: v-bind("state.size.headHeight");
  margin-right: 20px;
  font-size: v-bind("state.size.headIconSize");
  align-items: center;
  color: v-bind("state.style.color");
}

:deep(.el-input),
:deep(.el-textarea),
:deep(.el-date-editor),
:deep(.el-input__wrapper) {
  --el-input-bg-color: v-bind("state.style.itemBg") !important;
  --el-fill-color-blank: v-bind("state.style.itemBg") !important;
  --el-input-text-color: v-bind("state.style.color") !important;
}

:deep(.el-popper) {
  --el-bg-color-overlay: v-bind("state.style.itemBg") !important;
  --el-fill-color-light: v-bind("state.style.bodyBg") !important;
  text-align: left;
}

:deep(.el-dialog) {
  --el-dialog-bg-color: v-bind("state.style.bodyBg") !important;
}

:deep(.el-drawer) {
  --el-drawer-bg-color: v-bind("state.style.bodyBg") !important;
}

:deep(*) {
  --el-text-color-regular: v-bind("state.style.color") !important;
  --el-text-color-primary: v-bind("state.style.color") !important;
  --el-disabled-bg-color: v-bind("state.style.itemBg") !important;
}

:deep(*::selection) {
  background-color: v-bind("state.style.selectionBg");
  color: v-bind("state.style.selectionColor");
}
</style>
