<template>
  <div>
    <div class="nav-menu">
      <div class="header-logo">
        <img src="../assets/images/factory-logo.png" alt="logo" />
      </div>
      <!-- 导航栏 -->
      <el-menu
        class="el-menu-demo"
        mode="horizontal"
        background-color="#001529"
        text-color="#fff"
        style="border-bottom: none"
        :default-active="defaultActive"
        router
      >
        <template v-for="item in menuList">
          <el-menu-item
            v-if="!item.children"
            :key="item.id"
            :index="item.index"
            >{{ item.label }}</el-menu-item
          >
          <el-sub-menu v-else :key="item.index" :index="item.index">
            <template #title>
              <span class="label">{{ item.label }}</span>
            </template>
            <el-menu-item
              v-for="sub in item.children"
              :key="sub.id"
              :index="sub.index"
              >{{ sub.label }}</el-menu-item
            >
          </el-sub-menu>
        </template>
      </el-menu>
      <SideBar />
      <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">
      <el-icon
        v-if="showScrollArrows"
        class="nav-tabs-arrow left"
        @click="scrollTabs('left')"
      >
        <ArrowLeft />
      </el-icon>

      <div
        ref="tabsWrapper"
        class="tabs-scroll-container"
        :style="{ width: showScrollArrows ? 'calc(100% - 80px)' : '100%' }"
      >
        <div
          class="tabs-wrapper"
          :style="{ transform: `translateX(${scrollOffset}px)` }"
        >
          <div
            v-for="item in tabs"
            :key="item.name"
            class="tabs-node"
            :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
                v-if="item.path != '/dashboard' && tabs.length > 1"
                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,
  watch,
  computed,
  nextTick,
  onMounted,
  onUnmounted,
} from 'vue'
import { useRoute, useRouter } from 'vue-router'
import Menu 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 SideBar from './SideBar.vue'

interface MenuItem {
  index: string
  id: number
  label: string
  children?: MenuItem[]
}
interface PasswordForm {
  oldPwd: string
  newPwd: string
  confirmPwd?: string
}
const route = useRoute()
// 使用 computed 替代直接赋值
const defaultActive = computed({
  get: () => route.path,
  set: (val) => {
    router.push(val)
  },
})
const menuList = reactive(Menu)

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 addTab = () => {
  const { path, meta } = route
  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]
      if (lastTab) {
        nextTick(() => {
          activeTab.value = lastTab.name
          router.push(lastTab.path)
        })
      }
    }
  }
}
const tabsContainer = ref<HTMLDivElement | null>(null)
const tabsWrapper = ref<HTMLDivElement | null>(null)
const scrollOffset = ref(0)
const scrollStep = 200 // 每次滚动的像素数
const showScrollArrows = ref(false)
// 检查是否需要显示滚动箭头
const checkScrollArrows = () => {
  nextTick(() => {
    if (!tabsContainer.value || !tabsWrapper.value) return

    const containerWidth = tabsContainer.value.clientWidth
    const wrapperWidth = tabsWrapper.value.scrollWidth

    // 如果包装器宽度大于容器宽度，显示箭头
    showScrollArrows.value = wrapperWidth > containerWidth

    // 调整滚动位置，确保不会超出边界
    if (showScrollArrows.value) {
      const maxScroll = -(wrapperWidth - containerWidth)

      // 如果当前滚动位置已经超出最大可滚动范围，重新调整
      if (scrollOffset.value < maxScroll) {
        scrollOffset.value = maxScroll
      }

      // 确保不会滚动到容器左侧之外
      if (scrollOffset.value > 0) {
        scrollOffset.value = 0
      }
    } else {
      // 如果不需要滚动，重置滚动位置
      scrollOffset.value = 0
    }
  })
}

// 添加窗口大小监听器
const resizeObserver = new ResizeObserver(checkScrollArrows)
const scrollTabs = (direction: 'left' | 'right') => {
  if (!tabsContainer.value || !tabsWrapper.value) return

  const containerWidth = tabsContainer.value.clientWidth
  const wrapperWidth = tabsWrapper.value.scrollWidth

  if (direction === 'left') {
    // 向左滚动（显示前面的标签）
    scrollOffset.value = Math.min(0, scrollOffset.value + scrollStep)
  } else {
    // 向右滚动（显示后面的标签）
    const maxScroll = -(wrapperWidth - containerWidth)
    scrollOffset.value = Math.max(maxScroll, scrollOffset.value - scrollStep)
  }
}
// 确保活动标签始终在可视范围内
const ensureActiveTabVisible = () => {
  nextTick(() => {
    if (!tabsContainer.value || !tabsWrapper.value) return

    const activeTab = tabsWrapper.value.querySelector(
      '.tabs-node[style*="background-color: rgb(64, 158, 255)"]',
    ) as HTMLElement
    if (!activeTab) return

    const containerRect = tabsContainer.value.getBoundingClientRect()
    const activeTabRect = activeTab.getBoundingClientRect()
    const wrapperRect = tabsWrapper.value.getBoundingClientRect()

    // 计算活动标签相对于包装器的位置
    const relativeLeft = activeTabRect.left - wrapperRect.left
    const relativeRight = activeTabRect.right - wrapperRect.left

    // 如果标签部分或完全在容器外
    if (relativeLeft < 0 || relativeRight > containerRect.width) {
      // 调整滚动位置，使活动标签居中
      const centerOffset = containerRect.width / 2 - activeTabRect.width / 2
      scrollOffset.value = -relativeLeft + centerOffset

      // 重新检查滚动边界
      checkScrollArrows()
    }
  })
}

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

// 点击标签时切换路由
watch(activeTab, (newTab) => {
  if (newTab) {
    router.push(newTab)
  }
  // 监听活动标签变化时调整滚动
  ensureActiveTabVisible()
  checkScrollArrows()
})
watch(tabs, 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) {
    const systemSettingsMenu = menuList.find(
      (item: MenuItem) => item.label === '系统设置',
    )
    if (systemSettingsMenu && systemSettingsMenu.children) {
      systemSettingsMenu.children = systemSettingsMenu.children.filter(
        (child: MenuItem) => child.index !== '/system/customers',
      )
    }
  }
  // 初始检查
  checkScrollArrows()

  // 监听容器大小变化
  if (tabsContainer.value) {
    resizeObserver.observe(tabsContainer.value)
  }
})

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

onUnmounted(() => {
  // 清理监听器
  resizeObserver.disconnect()
})
</script>
<style lang="scss" scoped>
.nav-tabs {
  background-color: #f5f5f5;
  padding: 10px 20px;
  font-size: 14px;
  display: flex;
  align-items: center;
}
.tabs-scroll-container {
  overflow: hidden;
  flex-grow: 1;
}

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

.nav-tabs-arrow {
  cursor: pointer;
  color: #409eff;
  font-size: 20px;

  &.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;
  &:hover {
    background-color: #c6e2ff;
  }
}
.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;

  :deep(.el-sub-menu .el-sub-menu__icon-arrow) {
    display: none;
  }
}

.el-menu-demo {
  flex: 1;
  height: 100%;
  border-bottom: none;
  margin-left: 20px;
  :deep(.el-menu-item) {
    border-bottom: none !important;
  }
  :deep(.el-menu-item.is-active) {
    background-color: #409eff !important;
    color: #fff !important;
    border: none !important;
  }
}
.user-info {
  display: flex;
  align-items: center;
}
</style>
