<template>
  <div>
    <div class="nav-menu">
      <div class="header-logo">
        <img
          style="vertical-align: middle"
          src="../assets/images/factory-logo.png"
          alt="logo"
        />
      </div>
      <!-- 导航栏 -->
      <nav class="mega-nav">
        <NavMenuItem
          v-for="item in displayMenuList"
          :key="item.id"
          :item="item"
        />
      </nav>

      <div v-if="userInfo" class="user-info">
        <span class="user-avatar" style="color: #fff; font-size: 14px">
          工厂： {{ userInfo.factoryCode }}
        </span>
        <span class="user-avatar">
          <el-icon><User /></el-icon>
        </span>
        <el-dropdown style="color: #fff; font-size: 14px">
          <span class="el-dropdown-link">
            <el-icon style="vertical-align: middle"><User /></el-icon>
            {{ userInfo.account }}
            <el-icon style="vertical-align: middle" class="el-icon--right">
              <arrow-down />
            </el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="toDownload">我的下载</el-dropdown-item>
              <el-dropdown-item @click="resetPassword"
                >修改密码</el-dropdown-item
              >
              <el-dropdown-item @click="logout">退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </div>
    <div ref="tabsContainer" class="nav-tabs">
      <div
        class="tabs-node tabs-node--fixed"
        :class="{ 'is-active': activeTab === DASHBOARD_PATH }"
        :style="{
          backgroundColor: activeTab === DASHBOARD_PATH ? '#409EFF' : '',
          color: activeTab === DASHBOARD_PATH ? '#fff' : '',
        }"
        @click="activeTab = DASHBOARD_PATH"
      >
        <div class="nav-tabs-node_label">
          <span>{{ DASHBOARD_TITLE }}</span>
        </div>
      </div>

      <el-icon
        v-if="showScrollArrows"
        class="nav-tabs-arrow left"
        @click="scrollTabs('left')"
      >
        <ArrowLeft />
      </el-icon>

      <div ref="tabsScrollContainer" class="tabs-scroll-container">
        <div
          ref="tabsInnerWrapper"
          class="tabs-wrapper"
          :style="{ transform: `translateX(${scrollOffset}px)` }"
        >
          <div
            v-for="item in scrollableTabs"
            :key="item.name"
            class="tabs-node"
            :class="{ 'is-active': item.name === activeTab }"
            :style="{
              backgroundColor: item.name === activeTab ? '#409EFF' : '',
              color: item.name === activeTab ? '#fff' : '',
            }"
            @click="activeTab = item.name"
          >
            <div class="nav-tabs-node_label">
              <span>{{ item.title }}</span>
              <el-icon class="el-icon-close" @click.stop="removeTab(item.name)">
                <CircleClose />
              </el-icon>
            </div>
          </div>
        </div>
      </div>

      <el-icon
        v-if="showScrollArrows"
        class="nav-tabs-arrow right"
        @click="scrollTabs('right')"
      >
        <ArrowRight />
      </el-icon>
    </div>
  </div>
  <el-dialog
    v-model="dialogVisible"
    title="修改密码"
    width="30%"
    :close-on-click-modal="false"
    @opened="onPasswordDialogOpened"
  >
    <ElForm
      ref="passwordFormRef"
      :model="passwordForm"
      :rules="rules"
      label-width="80px"
    >
      <ElFormItem label="原密码" prop="oldPwd">
        <ElInput
          v-model="passwordForm.oldPwd"
          type="password"
          clearable
          placeholder="请输入原密码"
        />
      </ElFormItem>
      <ElFormItem label="新密码" prop="newPwd">
        <ElInput
          v-model="passwordForm.newPwd"
          type="password"
          clearable
          placeholder="请输入新密码"
        />
      </ElFormItem>
      <ElFormItem label="确认密码" prop="confirmPwd">
        <ElInput
          v-model="passwordForm.confirmPwd"
          type="password"
          clearable
          placeholder="请再次输入密码"
        />
      </ElFormItem>
    </ElForm>
    <template #footer>
      <span class="dialog-footer">
        <ElButton @click="dialogVisible = false">取消</ElButton>
        <ElButton type="primary" @click="submitForm">确定</ElButton>
      </span>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import {
  User,
  ArrowDown,
  CircleClose,
  ArrowLeft,
  ArrowRight,
} from '@element-plus/icons-vue'
import {
  ref,
  reactive,
  computed,
  watch,
  nextTick,
  onMounted,
  onUnmounted,
} from 'vue'
import { useRoute, useRouter } from 'vue-router'
import Menu, { type MenuItem } from '@/router/menu'
import userUserStore from '@/store/user'

import type { FormRules } from 'element-plus'
import { useValue } from '@/utils/hooks/useValue'

import { changePasswordApi } from '@/api/auth'
import { ElMessage } from 'element-plus'

import NavMenuItem from './NavMenuItem.vue'

const removeMenuItemByIndex = (items: MenuItem[], indexToRemove: string) => {
  for (let i = items.length - 1; i >= 0; i--) {
    if (items[i].index === indexToRemove) {
      items.splice(i, 1)
    } else if (items[i].children?.length) {
      removeMenuItemByIndex(items[i].children!, indexToRemove)
    }
  }
}
interface PasswordForm {
  oldPwd: string
  newPwd: string
  confirmPwd?: string
}
const route = useRoute()
const menuList = reactive(Menu)
const DASHBOARD_PATH = '/dashboard'
const DASHBOARD_TITLE = '概览'

const displayMenuList = computed(() =>
  menuList.filter((item) => item.index !== DASHBOARD_PATH),
)

const userStore = userUserStore()
const userInfo = userStore.user
const dialogVisible = ref(false)
// 密码form
const [passwordForm, resetPasswordForm] = useValue<PasswordForm>(
  {} as PasswordForm,
)
const passwordFormRef = ref()
const rules = reactive<FormRules<PasswordForm>>({
  oldPwd: [
    {
      required: true,
      message: '请输入原密码',
    },
  ],
  newPwd: [
    {
      required: true,
      message: '请输入新密码',
    },
  ],
  confirmPwd: [
    {
      required: true,
      message: '请再次输入密码',
    },
    {
      validator: (_rule, value, callback) => {
        if (value !== passwordForm.value.newPwd) {
          callback(new Error('两次密码不一致'))
        } else {
          callback()
        }
      },
      trigger: 'blur',
    },
  ],
})

const logout = () => {
  userStore.logout()
  window.location.reload()
}
const resetPassword = () => {
  dialogVisible.value = true
  resetPasswordForm()
}
const onPasswordDialogOpened = () => {
  passwordFormRef.value.clearValidate()
}

const submitForm = async () => {
  try {
    await passwordFormRef.value.validate()
  } catch {
    return
  }
  try {
    const res = await changePasswordApi(passwordForm.value)
    ElMessage({
      message: res.message,
      type: 'success',
      offset: window.innerHeight / 2,
    })
    dialogVisible.value = false
    userStore.logout()
    window.location.reload()
  } catch (e) {
    // showError(e)
  }
}
const tabs = ref<Array<{ name: string; title: string; path: string }>>([])
const activeTab = ref('')
const router = useRouter()

const scrollableTabs = computed(() =>
  tabs.value.filter((tab) => tab.path !== DASHBOARD_PATH),
)

const addTab = () => {
  const { path, meta } = route

  if (path === DASHBOARD_PATH) {
    activeTab.value = DASHBOARD_PATH
    return
  }

  const existingTab = tabs.value.find((tab) => tab.path === path)

  if (!existingTab) {
    const newTab = {
      name: path,
      title: (meta.title as string) || '未命名页面',
      path: path,
    }
    tabs.value.push(newTab)
  }

  activeTab.value = path
}

const removeTab = (targetName: string) => {
  const tabIndex = tabs.value.findIndex((tab) => tab.name === targetName)

  if (tabIndex !== -1) {
    tabs.value.splice(tabIndex, 1)

    if (activeTab.value === targetName) {
      const lastTab = tabs.value[tabs.value.length - 1]
      nextTick(() => {
        if (lastTab) {
          activeTab.value = lastTab.name
          router.push(lastTab.path)
        } else {
          activeTab.value = DASHBOARD_PATH
          router.push(DASHBOARD_PATH)
        }
      })
    }
  }
}
const tabsContainer = ref<HTMLDivElement | null>(null)
const tabsScrollContainer = ref<HTMLDivElement | null>(null)
const tabsInnerWrapper = ref<HTMLDivElement | null>(null)
const scrollOffset = ref(0)
const scrollStep = 200
const showScrollArrows = ref(false)

const clampScrollOffset = () => {
  if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return

  const containerWidth = tabsScrollContainer.value.clientWidth
  const innerWidth = tabsInnerWrapper.value.scrollWidth
  const maxScroll = Math.min(0, containerWidth - innerWidth)

  scrollOffset.value = Math.min(0, Math.max(maxScroll, scrollOffset.value))
}

const checkScrollArrows = () => {
  nextTick(() => {
    if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return

    const containerWidth = tabsScrollContainer.value.clientWidth
    const innerWidth = tabsInnerWrapper.value.scrollWidth

    showScrollArrows.value = innerWidth > containerWidth
    clampScrollOffset()
    ensureActiveTabVisible()
  })
}

const resizeObserver = new ResizeObserver(checkScrollArrows)

const scrollTabs = (direction: 'left' | 'right') => {
  if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return

  const containerWidth = tabsScrollContainer.value.clientWidth
  const innerWidth = tabsInnerWrapper.value.scrollWidth
  const maxScroll = Math.min(0, containerWidth - innerWidth)

  if (direction === 'left') {
    scrollOffset.value = Math.min(0, scrollOffset.value + scrollStep)
  } else {
    scrollOffset.value = Math.max(maxScroll, scrollOffset.value - scrollStep)
  }
}

const ensureActiveTabVisible = () => {
  nextTick(() => {
    if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return

    const activeTabEl = tabsScrollContainer.value.querySelector(
      '.tabs-node.is-active',
    ) as HTMLElement | null
    if (!activeTabEl) return

    const containerWidth = tabsScrollContainer.value.clientWidth
    const tabLeft = activeTabEl.offsetLeft
    const tabRight = tabLeft + activeTabEl.offsetWidth
    const visibleLeft = -scrollOffset.value
    const visibleRight = visibleLeft + containerWidth

    if (tabLeft < visibleLeft) {
      scrollOffset.value = -tabLeft
    } else if (tabRight > visibleRight) {
      scrollOffset.value = -(tabRight - containerWidth)
    }

    clampScrollOffset()
  })
}

// 监听路由变化，自动添加标签
watch(
  () => route.path,
  () => {
    addTab()
  },
  { immediate: true },
)

// 点击标签时切换路由
watch(activeTab, (newTab) => {
  if (newTab) {
    router.push(newTab)
  }
  ensureActiveTabVisible()
  checkScrollArrows()
})
watch(scrollableTabs, checkScrollArrows)
onMounted(() => {
  let showCustomerManagement = false
  const userJson = localStorage.getItem('user')
  if (userJson) {
    try {
      const user = JSON.parse(userJson)
      if (user && user.factory && user.factory.type === 2) {
        showCustomerManagement = true
      }
    } catch (e) {
      // ignore
    }
  }
  if (!showCustomerManagement) {
    removeMenuItemByIndex(menuList, '/system/customers')
  }
  // 初始检查
  checkScrollArrows()

  if (tabsContainer.value) {
    resizeObserver.observe(tabsContainer.value)
  }
  if (tabsScrollContainer.value) {
    resizeObserver.observe(tabsScrollContainer.value)
  }
})

const toDownload = () => {
  router.push({ name: 'MyDownloads' })
}

onUnmounted(() => {
  resizeObserver.disconnect()
})
</script>
<style lang="scss" scoped>
.nav-tabs {
  background-color: #f5f5f5;
  padding: 10px 50px 10px 20px;
  font-size: 14px;
  display: flex;
  align-items: center;
  position: relative;
  z-index: 1;
}
.tabs-scroll-container {
  overflow: hidden;
  flex: 1;
  min-width: 0;
}

.tabs-wrapper {
  display: flex;
  align-items: center;
  gap: 10px;
  transition: transform 0.3s ease;
  pointer-events: none;
}

.nav-tabs-arrow {
  cursor: pointer;
  color: #409eff;
  font-size: 20px;
  flex-shrink: 0;
  position: relative;
  z-index: 2;

  &.left {
    margin-right: 10px;
  }

  &.right {
    margin-left: 10px;
  }

  &:hover {
    color: #66b1ff;
  }
}
.tabs-node {
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 4px;
  transition: all 0.3s;
  box-shadow: var(--el-box-shadow-light);
  background-color: #fff;
  pointer-events: auto;
  flex-shrink: 0;

  &--fixed {
    margin-right: 10px;
  }

  &:hover {
    background-color: #c6e2ff;
  }

  &.is-active:hover {
    background-color: #409eff;
  }
}
.nav-tabs-node_label {
  display: flex;
  align-items: center;
  gap: 2px;
  white-space: nowrap;
}
.nav-menu {
  height: 60px;
  background-color: #001529;
  display: flex;
  align-items: center;
  padding: 0 40px;
}

.mega-nav {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: center;
  margin-left: 60px;
}

.user-info {
  display: flex;
  align-items: center;
}
.header-logo {
  margin-left: 120px;
}
</style>
