<!--
  Program: Top menu
  Author: SDL
  Brief: top menu common layout
-->
<template>
  <header id="header-design" class="container-fluid fixed-top ui--header" :class="{ 'bg-ctrl': bgCtrl || !isMainIndex }">
    <span class="scroll-bg"></span>
    <nav class="navbar navbar-expand-lg d-flex ui--top">
      <!-- brand -->
      <router-link :to="{ name: 'mainIndexPage' }" class="navbar-brand cursor-pointer" href="javascript:">
        <img :src="$CONTEXT + '/static/image/main/simbol.png'" class="ui--brand-simbol" :alt="$t('sdl.common.projectName')" />
        <span class="brand-text">{{ $t('sdl.common.projectName') }}</span>
      </router-link>
      <!-- menu -->

      <ul class="navbar-nav" v-click-outside="menuClose">
        <li class="nav-item dropdown ui--nav-mymenu" ref="myMenus" :class="{ show: isMyMenuOpen }">
          <a class="nav-link dropdown-toggle" href="javascript:" @click="menuToggle()"> <i class="me-1 bi bi-star-fill"></i> My Menu </a>
          <div class="dropdown-menu text-left" :class="{ show: isMyMenuOpen }" style="transition: opacity 1s">
            <transition name="parent-transition">
              <ul class="dropdown-item">
                <li v-if="myMenus.length === 0">
                  <ul>
                    <li>
                      <span class="text-secondary">{{ $t('sdl.common.message.emptyMyMenu') }}</span>
                    </li>
                  </ul>
                </li>
                <li v-for="(chunk, index) in chunkedMyMenus" :key="index">
                  <TransitionGroup name="myMenu" tag="ul">
                    <!-- If you want to see drop area, add below source into props -->
                    <!-- :class="{ 'drop-area': draggingIndex !== null }"-->
                    <li
                      v-for="(item, subIndex) in chunk"
                      :key="item"
                      :draggable="true"
                      @dragstart="myMenuDragStart($event, 10 * index + subIndex)"
                      @dragend="myMenuDragEnd"
                      @dragenter.stop.prevent="myMenuDragEnter($event, 10 * index + subIndex)"
                      @dragover.stop.prevent="myMenuDragOver($event)"
                      @drop="myMenuDrop($event)"
                    >
                      <!--                      <i class="bi bi-grip-vertical drag-handle" title="Move Row"></i>-->
                      <a href="javascript:" @click="moveMenu(item.defaultPage.pagePath)" :draggable="false">
                        {{ getLabel(item) }}
                      </a>
                    </li>
                  </TransitionGroup>
                </li>
              </ul>
            </transition>
          </div>
        </li>
        <li class="nav-item dropdown" v-for="menu in rootMenus" :key="menu.menuId" :ref="menu.menuId" :class="{ show: menu.selected }">
          <a
            class="nav-link dropdown-toggle"
            href="javascript:"
            @click="
              openExternalUrl(menu.externalUrlUsed, menu.externalUrl, $event);
              menuToggle(menu, $event);
            "
          >
            {{ getLabel(menu) }}
            <i class="bi bi-arrow-up-right" v-show="menu.externalUrlUsed"></i>
          </a>
          <!--          <a class="nav-link dropdown-toggle" href="javascript:" data-toggle="dropdown">{{ menu.localeLabel }}</a>-->
          <!-- dropdown-menu  -->
          <div class="dropdown-menu text-left" v-if="menu.externalUrlUsed === false" :class="{ 'text-center': getSubmenu(menu.menuId).length > subMenuLimitCnt, show: menu.selected }">
            <ul class="dropdown-item" :style="menu.selectedStyle">
              <li v-for="submenu in getSubmenu(menu.menuId)" :key="submenu.menuId">
                <strong v-if="submenu.externalUrlUsed === true">
                  <a href="javascript:" @click="openExternalUrl(submenu.externalUrlUsed, submenu.externalUrl)"> {{ getLabel(submenu) }} <i class="bi bi-arrow-up-right"></i> </a>
                </strong>
                <strong v-else-if="submenu.defaultPage">
                  <a href="javascript:" @click="moveMenu(submenu.defaultPage.pagePath)">
                    {{ getLabel(submenu) }}
                    <i class="bi bi-chevron-right"></i>
                  </a>
                </strong>
                <strong v-else>{{ getLabel(submenu) }}</strong>
                <ul>
                  <li v-for="item in getSubmenu(submenu.menuId)" :key="item.menuId">
                    <a v-if="item.externalUrlUsed" href="javascript:" @click="openExternalUrl(item.externalUrlUsed, item.externalUrl)">
                      {{ getLabel(item) }}
                      <i class="bi bi-arrow-up-right"></i>
                    </a>
                    <a v-else href="javascript:" @click="moveMenu(item.menuUrl)">
                      {{ getLabel(item) }}
                    </a>
                  </li>
                </ul>
              </li>
            </ul>
          </div>
        </li>
      </ul>
      <!-- right menu -->
      <ul class="right-container list-unstyled" v-click-outside="areaClose">
        <li class="ui--nav-notice">
          <a href="javascript:" data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.main.message.notice')" data-bs-custom-class="ui--utility-tooltip" @click="areaToggle('showNoticeArea')">
            <i class="bi bi-bell-fill icon-bell"></i>
            <span class="badge rounded-pill bg-danger" v-if="newNoticeCount > 0">{{ newNoticeCount }}</span>
          </a>
          <!-- Notice -->
          <div class="ui--utility-item ui--notice" :class="{ active: area.showNoticeArea }">
            <h5>
              {{ $t('sdl.main.message.notice') }}
              <button type="button" class="close btn-close" @click="areaToggle('showNoticeArea')"></button>
            </h5>
            <div class="ui--notice-row">
              <div class="ui--notice-list">
                <a href="javascript:void(0)" v-for="notice in noticeList" :key="notice.postId" :class="{ active: selectedNotice.postId === notice.postId, notread: !notice.noticeChecked }" @click="selectNotice(notice)">
                  {{ notice.postTitle }}
                </a>
              </div>
              <div class="ui--notice-contents">
                <div class="ui--in-board" v-html="$filters.nl2br(selectedNotice.postDetail)"></div>
              </div>
            </div>
          </div>
          <!-- // Notice -->
        </li>
        <li><span class="me-2 ms-2 ui--slide">|</span></li>
        <li>
          <a href="javascript:" data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.excel.linkSite.title')" data-bs-custom-class="ui--utility-tooltip" @click="areaToggle('showLinkSiteArea')"
            ><i class="bi bi-link ui--trans-rotate-45 fs-6"></i
          ></a>
          <!-- link site -->
          <div class="ui--utility-item ui--utility-language" :class="{ active: area.showLinkSiteArea }">
            <!-- active -->
            <ul class="ui--language-list list-unstyled">
              <li><a href="javascript:">IRP</a></li>
              <li><a href="javascript:">IT4U</a></li>
              <li><a href="javascript:">IT-VOC</a></li>
            </ul>
          </div>
          <!-- // linksite -->
        </li>
        <li>
          <a href="javascript:" data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.translation.translation')" data-bs-custom-class="ui--utility-tooltip" @click="openTrans"
            ><i class="bi bi-translate"></i
          ></a>
        </li>
        <li>
          <a href="javascript:" data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.common.label.integratedSearch')" data-bs-custom-class="ui--utility-tooltip" @click="openSearchPopup"
            ><i class="bi bi-search"></i
          ></a>
        </li>
        <li>
          <a href="javascript:" data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.main.message.sitemap')" data-bs-custom-class="ui--utility-tooltip" @click="openSitemapPopup"
            ><i class="bi bi-grid-3x3-gap-fill"></i
          ></a>
        </li>
        <li><span class="me-2 ms-2 ui--slide">|</span></li>
        <li>
          <a href="javascript:" data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.main.message.timeZone')" data-bs-custom-class="ui--utility-tooltip" @click="openTZPopup"><i class="bi bi-clock"></i></a>
        </li>
        <li>
          <a href="javascript:" data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.common.language.select')" data-bs-custom-class="ui--utility-tooltip" @click="areaToggle('showLanguageArea')">
            <i class="bi bi-globe"></i>
          </a>
          <div class="ui--utility-item ui--utility-language" :class="{ active: area.showLanguageArea }">
            <!-- active -->
            <ul class="ui--language-list list-unstyled">
              <li v-for="locale in availableLocales" :key="locale" :data-locale="locale" :class="{ selected: locale === $i18n.locale }">
                <a href="javascript:" @click="changeLocale(locale)">{{ getLocaleLabel(locale) }}</a>
              </li>
            </ul>
          </div>
          <!-- // Language -->
        </li>
        <li>
          <a href="javascript:" @click="areaToggle('showUserArea')">
            <div data-bs-toggle="tooltip" data-bs-placement="bottom" :data-bs-original-title="$t('sdl.main.message.myProfile')" data-bs-custom-class="ui--utility-tooltip" class="ui--user-last">
              {{ lastUserName }}
            </div>
          </a>
          <!-- User -->
          <div class="ui--utility-item ui--user" :class="{ active: area.showUserArea }">
            <h4>
              <span class="ui--blind">My Profile</span>
              <button type="button" class="close btn-close" @click="areaToggle('showUserArea')"></button>
            </h4>
            <ul class="ui--user-info">
              <li class="mb-3">
                <strong>{{ userInfo.userName }}</strong>
                {{ $t('sdl.offsider.label.honorific') }}
                <button class="btn ui--btn-logout" @click="goLoginPage">Logout</button>
              </li>
              <li class="mb-1">{{ userInfo.email }}</li>
              <li class="mb-1">{{ userInfo.deptName }}/{{ userInfo.compName }}</li>
              <li>
                <a class="ui--link-user" href="javascript:" @click="changePasswordPopup">{{ $t('sdl.identity.label.pwdChange') }}</a>
                <span class="me-2 ms-2 ui--slide">|</span>
                <a class="ui--link-user" href="javascript:" @click="entrustApprovalPopup">{{ $t('sdl.offsider.label.agencyAppr') }}</a>
              </li>
            </ul>
            <ul class="d-flex ui--contact-info">
              <li class="flex-fill"><a class="ui--btn-contact" href="javascript:">Contact US</a></li>
              <li class="flex-fill"><a class="ui--btn-contact" href="javascript:">IT VOC</a></li>
            </ul>
          </div>
          <!-- // User -->
        </li>
      </ul>
    </nav>
  </header>
</template>

<script>
import { mapActions, mapGetters } from 'vuex';
import _ from 'lodash';
import axios from 'axios';
import store from '@/vuex/store';
import SDLLocale from '@/mixin/SDLLocale';
import { SDLUtil, StringUtil } from '@/utils';
import loginService from '@/service/loginService';
import SearchPopup from './popup/SearchPopup.vue';
import SitemapPopup from './popup/SitemapPopup.vue';
import TimeZonePopup from './popup/TimeZonePopup.vue';
import EntrustApprovalPopup from '@/components/common/popup/EntrustApprovalPopup.vue';
import ChangePasswordPopup from '@/components/common/popup/ChangePasswordPopup.vue';
import debounce from 'lodash/debounce.js';

export default {
  name: 'TopMenu',
  mixins: [SDLLocale],
  props: {
    isMainIndex: {
      type: Boolean,
      default: () => false,
    },
  },
  data() {
    return {
      userInfo: {},
      area: {
        showLinkSiteArea: false,
        showNoticeArea: false,
        showUserArea: false,
        showLanguageArea: false,
      },
      noticeList: [],
      readNoticeList: [],
      selectedNotice: {},
      subMenuLimitCnt: 2,
      rootMenus: [],
      isMenuOpen: false,
      isMyMenuOpen: false,
      draggingIndex: null,
      bgCtrl: false,
    };
  },
  computed: {
    ...mapGetters({
      menus: 'getMenus', // Receive menus with getter
      myMenus: 'getMyMenus',
    }),
    myMenuDivider() {
      return Math.ceil(this.myMenus.length / 10);
    },
    newNoticeCount() {
      return this.noticeList.filter(notice => !notice.noticeChecked).length;
    },
    lastUserName() {
      return this.userInfo.userName && this.userInfo.userName.toUpperCase().split('')[0];
    },
    availableLocales() {
      return this.$i18n.availableLocales;
    },
    chunkedMyMenus() {
      const result = [];
      for (let i = 0; i < this.myMenus.length; i += 10) {
        result.push(this.myMenus.slice(i, i + 10));
      }
      return result;
    },
  },
  watch: {
    $route() {
      this.getNoticeList();
    },
  },
  methods: {
    ...mapActions(['logout', 'setLocale', 'moveMyMenu']),
    areaToggle(areaKey) {
      this.menuClose();
      Object.keys(this.area).forEach(key => {
        if (key === areaKey) {
          if (key === 'showNoticeArea' && !_.isEmpty(this.noticeList)) {
            this.selectNotice(_.first(this.noticeList));
          }
          this.area[key] = !this.area[key];
        } else {
          this.area[key] = false;
        }
      });
    },
    areaClose() {
      Object.keys(this.area).forEach(key => {
        this.area[key] = false;
      });
    },
    menuToggle(menu, event) {
      if (menu) {
        const menuFlag = menu.selected;
        if (this.isMenuOpen || this.isMyMenuOpen) this.menuClose();

        this.isMenuOpen = !menuFlag;
        menu.selected = !menuFlag;
      } else {
        if (this.isMenuOpen) this.menuClose();
        this.isMyMenuOpen = !this.isMyMenuOpen;
      }
    },
    menuClose() {
      if (this.isMyMenuOpen) this.isMyMenuOpen = false;
      if (this.isMenuOpen) {
        this.rootMenus.forEach(rootMenu => {
          rootMenu.selected = false;
        });
        this.isMenuOpen = false;
      }
    },
    closeAll() {
      this.menuClose();
      this.areaClose();
    },
    /**
     * Deprecated
     *
     * This function has been deprecated after 5.2.0 version.
     *
     * @param menu
     * @param event
     */
    setMenuStyle(menu, event) {
      const ml = event ? event.target.offsetParent.offsetLeft + 12 : this.$refs[menu.menuId][0].offsetLeft + 12;
      if (this.getSubmenu(menu.menuId).length <= this.subMenuLimitCnt) {
        menu.selectedStyle = {
          marginLeft: `${ml}px`,
        };
      }
    },
    getSubmenu(parentId) {
      return _.sortBy(
        this.menus.filter(menu => menu.parentId === parentId),
        ['menuSequence'],
      );
    },
    moveMenu(pagePath) {
      // Initialize saved parameters when forced to move from the menu
      this.closeAll();
      store.commit('PARAMS', {});
      this.$router.push({ path: pagePath });
    },
    openExternalUrl(isExternal, url, event) {
      if (isExternal) {
        window.open(url.startsWith('http') ? url : `http://${url}`, '_blank');
        if (event) {
          const { parentElement } = event.target;
          // Remove selected class
          setTimeout(() => {
            parentElement.classList.remove('show');
          });
        }
      }
    },
    // Retrieving Notice List
    getNoticeList() {
      SDLUtil.showLoadingBar(true);
      axios
        .get(`${SDLUtil.API_URL}/notice-popup-posts`)
        .then(({ data }) => {
          if (!_.isEmpty(data)) this.noticeList = data;
        })
        .catch(err => {
          SDLUtil.showLoadingBar(false);
          SDLUtil.errorAlert(err);
        });
      SDLUtil.showLoadingBar(false);
    },
    // View Notice Details
    selectNotice(notice) {
      if (!notice.noticeChecked) {
        const params = { postId: notice.postId, userId: SDLUtil.getLoginedUserInfo().userId };
        SDLUtil.showLoadingBar(true);
        axios
          .post(`${SDLUtil.API_URL}/check-notice?${StringUtil.queryStringfy(params)}`)
          .then(() => {
            this.selectedNotice = notice;
            this.getNoticeList();
          })
          .catch(err => {
            SDLUtil.showLoadingBar(false);
            SDLUtil.errorAlert(err);
          });
        SDLUtil.showLoadingBar(false);
      } else {
        this.selectedNotice = notice;
      }
    },
    openTrans() {
      const width = 1100;
      const height = 670;
      const leftPosition = Math.ceil((window.screen.width - width) / 2);
      const topPosition = Math.ceil((window.screen.height - height) / 2);

      window.open(`${SDLUtil.WEB_CONTEXT_PATH}/transPopup`, 'popup', `width=${width},height=${height},top=${topPosition},left=${leftPosition},location=0,directories=0,resizable=0,status=0,toolbar=0,menubar=0`, '_blank');
    },
    openSearchPopup() {
      SDLUtil.show(
        SearchPopup,
        {},
        {
          width: '600px',
          height: 'auto',
        },
      );
    },
    openSitemapPopup() {
      SDLUtil.show(
        SitemapPopup,
        {},
        {
          width: '960px',
          height: 'auto',
        },
      );
    },
    openTZPopup() {
      SDLUtil.show(
        TimeZonePopup,
        {},
        {
          width: '600px',
          height: 'auto',
        },
      );
    },
    changePasswordPopup() {
      SDLUtil.show(ChangePasswordPopup, null, {
        width: 600,
        height: 'auto',
      });
    },
    entrustApprovalPopup() {
      SDLUtil.show(EntrustApprovalPopup, null, {
        width: 660,
        height: 'auto',
      });
    },
    goLoginPage() {
      this.$router.push(`${this.$CONTEXT}/logout`);
    },
    changeLocale(locale) {
      this.$i18n.locale = locale;
      this.setLocale(locale);
      this.updateUserToken({ language: locale });
      this.area.showLanguageArea = false;
    },
    getLocaleLabel(locale) {
      return this.$i18n.getLocaleMessage(locale)['sdl.common.language.label'];
    },
    updateUserToken(param) {
      const params = {
        language: this.userInfo.language,
        timeZoneId: this.userInfo.timeZoneId,
        timeZoneCode: this.userInfo.timeZoneCode,
        ...param,
      };

      axios.put(`${SDLUtil.API_URL}/auth/users/user-token`, params).then(({ data }) => {
        loginService.setToken(data.jwtToken);
        this.userInfo = SDLUtil.getLoginedUserInfo();
      });
    },
    myMenuDragEnter: _.debounce(function (e, targetIndex) {
      if (this.draggingIndex !== null && targetIndex !== this.draggingIndex) {
        e.dataTransfer.dropEffect = 'move';

        const draggedItem = this.myMenus[this.draggingIndex];
        this.myMenus.splice(this.draggingIndex, 1);
        this.myMenus.splice(targetIndex, 0, draggedItem);

        this.draggingIndex = targetIndex;
      }
    }, 100),
    myMenuDragOver(e) {
      e.dataTransfer.dropEffect = 'move';
    },
    myMenuDragStart(e, idx) {
      e.dataTransfer.effectAllowed = 'move';
      this.draggingIndex = idx;
    },
    myMenuDragEnd() {
      this.draggingIndex = null;
    },
    myMenuDrop(e) {
      const myMenuIds = this.myMenus.map(menu => {
        return menu.menuId;
      });
      this.moveMyMenu(myMenuIds);
    },
  },
  created() {
    this.userInfo = SDLUtil.getLoginedUserInfo();
    // document.querySelector('body').classList.remove('sdl-wrap', 'ui--login-wrap');
    if (document.querySelector('body').classList.contains('ui--login-wrap')) {
      document.querySelector('body').classList.remove('ui--login-wrap');
    }
    if (document.querySelector('body').classList.contains('sdl-wrap')) {
      document.querySelector('body').classList.remove('sdl-wrap');
    }
    this.rootMenus = _.sortBy(
      this.menus
        .filter(menu => menu.menuLevel === 1 && menu.menuId !== 'COMM_URL')
        .map(menu => ({
          ...menu,
          selected: false,
          selectedStyle: {},
        })),
      ['menuSequence'],
    );
    this.getNoticeList();
  },
  mounted() {
    document.addEventListener(
      'scroll',
      debounce(() => {
        this.bgCtrl = window.scrollY > 50;
      }, 50),
    );
    const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
    const tooltipList = [...tooltipTriggerList].map(
      tooltipTriggerEl =>
        new bootstrap.Tooltip(tooltipTriggerEl, {
          trigger: 'hover',
        }),
    );
  },
};
</script>

<style scoped>
.parent-transition-enter-active,
.parent-transition-leave-active {
  transition: opacity 1s;
}

.parent-transition-enter,
.parent-transition-leave-to {
  opacity: 0;
}

.myMenu-move, /* 움직이는 엘리먼트에 트랜지션 적용 */
.myMenu-enter-active,
.myMenu-leave-active {
  transition: all 0.2s ease;
}

.myMenu-enter-from,
.myMenu-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* 이동 애니메이션을 올바르게 계산할 수 있도록
   레이아웃 흐름에서 나머지 항목을 꺼내기. */
.myMenu-leave-active {
  position: absolute;
}

.drag-handle {
  cursor: move;
}

.drop-area {
  border: 2px dashed #ccc; /* 점선 테두리 스타일 */
}
</style>
