<script lang="ts" setup>
import Loading from '@/components/Loading/Loading.vue';
import NavBar from '@/components/NavBar/NavBar.vue';
import Footer from '@/components/Footer/Footer.vue';
import { ElMessage as elMessage } from 'element-plus';
import {
  onMounted,
  onUnmounted,
  watch,
  computed,
  reactive,
  ref,
  resolveDynamicComponent,
} from 'vue';
import { updateLocalLoginCount } from '@/utils/utils';
import { getSecurityInfo } from '@/services/security-enhance.service';
import { findMainMenu, getStoreData, setMenuStoreData, setStoreData } from '@/utils/composition';
import { getGenericInfo } from '@/services/header/header.service';
import { getEnergySavingService, getPowerSupplyMode } from '@/pages/System/Power/services/power.services';
import { IGeneric, IMainMenu, INavData, ISecondMenu } from '@/model/base-interface';
import { saveStoreToLocal } from '@/utils/common-service';
import { getSupplyChainConfig } from '@/pages/Maintance/AssetMaintance/asset.service';
import useStore from '@/stores';
import {
  MaintanceId,
  ManageId,
  UserId,
  SysId,
  ServiceId,
  MainMenuId,
  NavTheme,
} from '@/model/base-enum';
import LeftNavCollapse from '@/components/LeftNavCollapse/LeftNavCollapse.vue';
import { h } from 'vue';
import { traduction } from '@/utils/language';
import { useRouter } from 'vue-router';
import { LDAP_PAGE_ENABLED } from '@/model/configure';

const props = defineProps({
  showElMessage: {
    type: Boolean,
    required: false,
    default: true,
  },
});

const customToolShow = import.meta.env.VITE_CUSTOM_TOOL === 'true';
if (customToolShow) {
  const Customize = resolveDynamicComponent('@/components/Customize');
}

const isInLoading = computed(() => {
  return getStoreData('glob', 'isLoading');
});

const store = useStore();
const ibmcTime = ref('');
const copyRight = ref('');
const theme = getStoreData('glob', 'webStyle');
const data: INavData = reactive({
  health: { critical: 0, major: 0, minor: 0 },
  powerState: '',
  uidState: '',
});
let timer: any = null;
let genericTimer: any = null;
let leftNavTheme = computed(() => {
  return useStore()?.state?.loct?.navStyle || '';
});

// 监听message提示信息
let msgInstance: any = null;
const unWatchMsg = watch(
  () => store.state.event.alertMessage,
  (newVal, oldVal) => {
    if (!props.showElMessage) {
      return;
    }
    if (msgInstance) {
      msgInstance.close();
      msgInstance = null;
    }
    msgInstance = elMessage({
      type: newVal.type,
      message: h('span', { id: 'commonAlert' }, newVal.message),
      duration: newVal.type === 'success' ? 5000 : 10000,
      showClose: true,
    });
  },
  {
    deep: true,
  },
);

// 主菜单和二级菜单数据
const mainMenus = getStoreData('menu', 'mainMenu');

const leftNavCollapseStatus = reactive({
  collapse: false,
  isHome: true,
});
// 查询锁定状态的值SystemLockDownEnabled
function getSecurityInfoData() {
  getSecurityInfo()
    .then(res => {
      // 接口返回的值赋值给store;
      setStoreData('glob', 'systemLocked', res.SystemLockDownEnabled || false);
      setStoreData('glob', 'localAccountPasswordRulePolicy', res.LocalAccountPasswordRulePolicy || 'Default');
      setStoreData('glob', 'localAccountPasswordPattern', new RegExp(res?.LocalAccountPasswordPattern || ''));
      setStoreData('glob', 'snmpCommunityPasswordRulePolicy', res.SnmpCommunityPasswordRulePolicy || 'Default');
      setStoreData('glob', 'snmpCommunityPasswordPattern', new RegExp(res?.SnmpCommunityPasswordPattern || ''));
      setStoreData('glob', 'vncPasswordRulePolicy', res.VNCPasswordRulePolicy || 'Default');
      setStoreData('glob', 'vncPasswordPattern', new RegExp(res?.VNCPasswordPattern || ''));
    })
    .finally(() => {
      // 以后定时10秒获取系统锁定状态
      timer = setTimeout(() => {
        getSecurityInfoData();
      }, 10000);
    });
}

async function getPowerSourceSwitchSupported() {
  let powerSourceSwitchSupported = true;
  try {
    await getPowerSupplyMode();
  } catch (error: any) {
    if (error.status === 404) {
      powerSourceSwitchSupported = false;
    }
  } finally {
    setStoreData('loct', 'powerSourceSwitchSupported', powerSourceSwitchSupported);
  }
}

function getGeneric() {
  getGenericInfo()
    .then((res: IGeneric) => {
      // 显示预置证书提示,要早于saveBaseGenericInfo
      showPresetCertMessage(res.customeCertFlag);
      // 处理store的loct数据状态
      saveBaseGenericInfo(res);
      // 处理菜单数据
      updateMenu(res);

      // 组装数据（告警、状态）
      data.health.critical = res.healthSummary.critical;
      data.health.major = res.healthSummary.major;
      data.health.minor = res.healthSummary.minor;
      data.powerState = res.powerState;
      data.uidState = res.uidState;

      // 处理时间和版权信息
      if (res.currentTime) {
        const timeSplitArr = res.currentTime.split(/\s+/);
        const datePart = timeSplitArr[0].replace(/-/g, '/');
        const timePart = timeSplitArr[1].substr(0, 5);
        const timeZone = timeSplitArr[2];
        ibmcTime.value = `${datePart} ${timePart} ${timeZone}`;

        // 处理法语
        if (getStoreData('loct', 'locale') === 'fr') {
          ibmcTime.value = ibmcTime.value.replace(/:/g, 'h');
        }
      }
      copyRight.value = res.copyRight;
    })
    .finally(() => {
      genericTimer = setTimeout(getGeneric, 30000);
    });
}
const $router = useRouter();
let unWatchPreset = null as any;
function showPresetCertMessage(flag: any) {
  if (flag === false && getStoreData('loct', 'customeCertFlag') !== flag) {
    // 当处于Web服务页面，进行重新刷新，展示最新证书信息
    if ($router.currentRoute.value.fullPath.indexOf('web') > -1) {
      location.reload();
      return;
    }
    let presetMessage = elMessage({
      type: 'warning',
      message: h('p', { id: 'presetCertMessage' }, [
        h('span', null, traduction('PRESET_CERT_TIP')),
        h(
          'a',
          {
            href: '#/navigate/user/certificate/ssl-certificate',
            style: 'color:var( --o-color-primary)',
          },
          traduction('PRESET_CERT_TIP_2'),
        ),
      ]),
      duration: 5000,
      showClose: true,
    });
    setStoreData('glob', 'showPresetMessage', true);
    unWatchPreset = watch(
      () => store.state.glob.showPresetMessage,
      (newVal, oldVal) => {
        if (presetMessage && oldVal === true && newVal === false) {
          presetMessage.close();
          presetMessage = null as any;
          unWatchPreset();
        }
      },
      {
        deep: true,
      },
    );
  }
}

function showAssetChangeAlarm() {
  getSupplyChainConfig()
    .then((res: { data: { CheckEnabled: any; ChangedEvents: string|any[]; }; }) => {
      if (res.data.CheckEnabled && res.data.ChangedEvents.length > 0) {
        let presetMessage = elMessage({
          type: 'warning',
          message: h('p', { id: 'presetCertMessage' }, [
            h('span', null, traduction('ASSET_CHANGE_ALARM')),
            h(
              'a',
              {
                href: '#/navigate/maintenance/asset-maintance/supply-chain-config',
                style: 'color:var( --o-color-primary)',
              },
              traduction('GO_AND_CONFIRM'),
            ),
          ]),
          duration: 5000,
          showClose: true,
        });
      }
    });
}

// 保存基础数据状态
function saveBaseGenericInfo(res: IGeneric) {
  setStoreData('loct', 'armspt', res.armSupport || false);
  setStoreData('loct', 'fanspt', res.fanSupport || false);
  setStoreData('loct', 'fdmspt', res.fdmSupport || false);
  setStoreData('loct', 'ibmaspt', res.ibmaSupport || false);
  setStoreData('loct', 'ibmarun', res.ibmaRunning || false);
  setStoreData('loct', 'tcespt', res.tceSupport || false);
  setStoreData('loct', 'licensespt', res.licenseSupport || false);
  setStoreData('loct', 'powprespt', res.powerPredictSupported || false);
  setStoreData('loct', 'usbspt', res.usbSupport || false);
  setStoreData('loct', 'spspt', res.spSupport || false);
  setStoreData('loct', 'partityspt', res.partitySupport || false);
  setStoreData('loct', 'kvmspt', res.kvmSupported || false);
  setStoreData('loct', 'vmmspt', res.vmmSupported || false);
  setStoreData('loct', 'vncspt', res.vncSupported || false);
  setStoreData('loct', 'snmpspt', res.snmpSupported || false);
  setStoreData('loct', 'rmcpspt', res.rmcpSupported || false);
  setStoreData('loct', 'platform', res.armSupport ? 'Arm' : 'x86');
  setStoreData('loct', 'customizedId', res.customizedId || 0);
  setStoreData('loct', 'tpcmspt', res.tpcmSupport || false);
  setStoreData('loct', 'obsspt', res.observabilitySupported || false);
  setStoreData('loct', 'sbootspt', res.secureBootVerificationEnabled || false); 
  setStoreData('loct', 'powerState', res.powerState);
  setStoreData(
    'loct',
    'customeCertFlag',
    res.customeCertFlag !== undefined ? res.customeCertFlag : true,
  );
  setStoreData('loct', 'multihost', res.multihostSupported || false);
  setStoreData('loct', 'computeDomain', res.computeSupported || false);
  setStoreData('loct', 'sensorLocation', res.sensorSupported || false);
  setStoreData('loct', 'assetChange', res.assetChangeEnabled || false);
  setStoreData('loct', 'powerSupplySupported', res.powerSupplySupported || false);
  setStoreData('loct', 'powerConverterSupported', res.powerConverterSupported || false);
  setStoreData('loct', 'dynamicEnergySavingSupported', res.dynamicEnergySavingSupported || false);
  setStoreData('loct', 'langSupported', res.langSupported || {});
  setStoreData('loct', 'syslog', res.syslog);
  saveStoreToLocal();
}

/**
 * 处理菜单数据，处理原则如下
 * 1： 权限影响的页面显示
 * 用户配置权限：双因素页面，在线用户页面，配置更新页面
 * 调试诊断权限：录像截屏页面
 * 常规配置权限：固件升级页面，语言管理页面
 * 2. 环境支持影响页面显示
 */
function updateMenu(res: IGeneric) {
  const privil = getStoreData('loct', 'privil');
  const multihost = getStoreData('loct', 'multihost');
  const maintanceMenu = findMainMenu(MainMenuId.Maintance);
  const userMenu = findMainMenu(MainMenuId.User);
  const systemMenu = findMainMenu(MainMenuId.System);
  const manageMenu = findMainMenu(MainMenuId.Manager);
  const serviceMenu = findMainMenu(MainMenuId.Service);

  const hasConfigUsers = privil.includes('UserConfigEnabled');
  // 双因素因接口已交付，放开双因素二级菜单，恢复将UserId.TwoFactor加入到数组列表中
  toggleMenu(userMenu, [UserId.Online], hasConfigUsers);
  toggleMenu(userMenu, [UserId.TwoFactor], hasConfigUsers && LDAP_PAGE_ENABLED);
  toggleMenu(userMenu, [UserId.Ldap], LDAP_PAGE_ENABLED);
  toggleMenu(manageMenu, [ManageId.Update], hasConfigUsers);

  const hasOemDiagnosis = privil.includes('DiagnosisEnabled');
  toggleMenu(maintanceMenu, [MaintanceId.SysLog], hasOemDiagnosis);

  const hasConfigureComponents = privil.includes('BasicConfigEnabled');
  // 语言管理未交付，裁剪，后面恢复将 ManageId.Language 加入到数组中，并在路由守卫中解除限制
  toggleMenu(manageMenu, [ManageId.Upgrade, ManageId.Language], hasConfigureComponents);

  // 接口支持
  toggleMenu(systemMenu, [SysId.Partity], res.partitySupport);
  toggleMenu(systemMenu, [SysId.Fans], res.fanSupport);
  toggleMenu(manageMenu, [ManageId.Ibma], res.ibmaSupport);
  toggleMenu(manageMenu, [ManageId.License], res.licenseSupport);
  toggleMenu(manageMenu, [ManageId.Sp], res.spSupport);
  toggleMenu(userMenu, [UserId.TrustedCompute], res.tpcmSupport);
  toggleMenu(manageMenu, [ManageId.USB], res.usbSupport);
  toggleMenu(maintanceMenu, [MaintanceId.Data], res.observabilitySupported);

  // multiHost裁剪
  toggleMenu(systemMenu, [SysId.Storage], !multihost);
  toggleMenu(serviceMenu, [ServiceId.Kvm], res.kvmSupported);
  toggleMenu(maintanceMenu, [MaintanceId.Video], res.kvmSupported && hasOemDiagnosis);
  toggleMenu(serviceMenu, [ServiceId.Vmm], res.vmmSupported);
  toggleMenu(serviceMenu, [ServiceId.Vnc], res.vncSupported);
  toggleMenu(serviceMenu, [ServiceId.Snmp], res.snmpSupported);
  toggleMenu(systemMenu, [SysId.Bios], !multihost);
}

function toggleMenu(mainMenu: IMainMenu, subMenuIds: string[], supported: boolean) {
  mainMenu.children.forEach((item: ISecondMenu) => {
    if (subMenuIds.includes(item.id)) {
      setMenuStoreData(mainMenu.id, subMenuIds, supported);
    }
  });
}

function reload() {
  getGeneric();
}

onMounted(() => {
  // 当tabIsValid 不存在时，代表是新开的Tab标签
  const tabIsValid = sessionStorage.getItem('tabIsValid');
  if (!tabIsValid) {
    updateLocalLoginCount('add');
  }

  // 查询基本属性
  getGeneric();

  // 页面登录进来就查一次锁定状态的值
  getSecurityInfoData();

  getPowerSourceSwitchSupported();

  // 设置导航模式
  const navStyle = localStorage.getItem('customizeStyle')
    ? JSON.parse(localStorage.getItem('customizeStyle') as string)?.layout?.nav
    : 'topLeft';
  setStoreData('loct', 'navStyle', navStyle ? navStyle : 'topLeft');
  if ($router.currentRoute.value.fullPath.indexOf('home') > -1) {
    leftNavCollapseStatus.isHome = true;
  } else {
    leftNavCollapseStatus.isHome = false;
  }
});

onUnmounted(() => {
  // 取消监听alertMessage信息
  unWatchMsg();
  // 清除
  if (timer) {
    timer = clearTimeout(timer);
  }

  if (genericTimer) {
    genericTimer = clearTimeout(genericTimer);
  }

  if (unWatchPreset) {
    unWatchPreset();
  }
});
function leftNavCollapseChange(status: boolean[]) {
  leftNavCollapseStatus.collapse = status[0];
  leftNavCollapseStatus.isHome = status[1];
}
</script>

<template>
  <Loading :state="isInLoading" />
  <NavBar :options="mainMenus" :theme="theme" :data="data" @reload="reload" />
  <section
    class="nav-container"
    :class="{
      'padding-left': leftNavTheme === NavTheme.Top,
      'is-home-section': leftNavCollapseStatus.isHome
    }"
  >
    <div
      v-if="leftNavTheme === NavTheme.Left"
      id="leftNavCollapseBox"
      :class="{
        'is-collapse': leftNavCollapseStatus.collapse,
        'is-home-left-nav': leftNavCollapseStatus.isHome
      }"
    >
      <LeftNavCollapse @collapse-change="leftNavCollapseChange"></LeftNavCollapse>
    </div>
    <router-view />
  </section>
  <Footer :time="ibmcTime" :copy-right="copyRight"></Footer>
  <template v-if="customToolShow">
    <Customize />
  </template>
</template>

<style lang="scss" scoped>
.footer {
  position: fixed;
  z-index: 1000;
  bottom: 0;
  height: 32px;
  width: 100%;
  background-color: var(--o-bg-color-dark);
  color: var(--o-text-color-tertiary);
  text-align: center;
  line-height: 32px;
  padding: 0 28px;
}

.nav-container {
  flex: 1;
  flex-direction: row;
  padding: 48px 0 32px 0;
  display: flex;

  &.padding-left {
    padding-left: 24px;
  }
  &.is-home-section {
    padding-left: 0;
  }
}
#leftNavCollapseBox {
  margin-right: 280px;
  &.is-collapse {
    margin-right: 88px;
  }
  &.is-home-left-nav {
    margin-right: 256px;
    &.is-collapse {
      margin-right: 64px;
    }
  }
}
</style>
<style lang="scss">
.el-message {
  margin-top: 36px !important;
  box-shadow: none !important;
  #commonAlert{
    padding-right: 16px;
  }
}
</style>
