import { createStore } from 'vuex'
import type { Router } from 'vue-router'
import { fetchUserRoutes } from '@/api/menu'
import type { MenuItemRaw } from '@/api/menu'
import { buildDynamicRoutes } from '@/router/dynamicRoutes'
import { fetchIndustryTree, fetchJobCategoryTree, fetchRegionTree } from '@/api/common'
import type { IndustryItem, JobCategoryItem, RegionItem } from '@/api/common'
import { fetchJobIntention, saveJobIntention } from '@/api/jobs'
import type { JobIntention } from '@/api/jobs'
import { fetchUserInfo } from '@/api/auth'
import type { UserInfo } from '@/api/auth'

/** 职位列表页缓存数据（从详情页返回时恢复用） */
export interface JobListCache {
  /** 缓存的职位列表 */
  list: any[]
  /** 当前已加载到的页码 */
  pageNum: number
  /** 总记录数 */
  total: number
  /** 列表滚动位置 */
  scrollTop: number
}

export interface RootState {
  appName: string
  showLogin: boolean
  loginRedirect: string

  /**
   * 登录状态 — 登录成功设为 true，退出成功设为 false
   * 因为后端 Cookie 是 HttpOnly 的，前端 JS 无法读取，所以用内存状态管理
   */
  isAuthenticated: boolean

  /**
   * 后端返回的原始菜单数据，SideNav 用它来渲染导航
   */
  dynamicMenus: MenuItemRaw[]

  /**
   * 标记动态路由是否已经加载过，避免重复请求
   * 每次登出时重置为 false
   */
  routesLoaded: boolean

  /**
   * 记录已注册的动态路由 name，登出时用来逐个 removeRoute
   */
  dynamicRouteNames: string[]

  /**
   * 行业树分类数据（一级二级嵌套）
   * 由 /public/industries/tree 接口返回，进首页和 Jobs 页时刷新
   * 其他页面/组件可直接从 store 读取
   */
  industries: IndustryItem[]

  /**
   * 岗位树分类数据（一级二级三级嵌套）
   * 由 /public/job-categories/tree 接口返回，进首页和 Jobs 页时刷新
   * 其他页面/组件可直接从 store 读取
   */
  jobCategories: JobCategoryItem[]

  /**
   * 地区树分类数据（省市区三级嵌套）
   * 由 /public/regions/tree 接口返回，进首页和 Jobs 页时刷新
   * 其他页面/组件可直接从 store 读取
   */
  regions: RegionItem[]

  /**
   * 职位列表页缓存 — 从详情页返回时恢复列表和滚动位置
   * 为 null 表示没有缓存，需要重新请求
   */
  jobListCache: JobListCache | null

  /**
   * 求职意向数据 — JobGoalDialog 和 Jobs 页面共享
   * 由 loadJobIntention action 从接口加载，saveJobIntention action 保存后更新
   */
  jobIntention: JobIntention

  /**
   * 用户个人信息 — 登录后从 /user/manage/info 接口获取
   * 多个页面可直接从 store 读取
   */
  userInfo: UserInfo | null

  /**
   * 设置弹窗 — 控制显示/隐藏及初始 Tab
   */
  showSettings: boolean
  settingsTab: string
}

export default createStore<RootState>({
  state: {
    appName: 'JobAssistant',
    showLogin: false,
    loginRedirect: '',
    isAuthenticated: sessionStorage.getItem('isAuthenticated') === 'true',
    dynamicMenus: [],
    routesLoaded: false,
    dynamicRouteNames: [],
    industries: [],
    jobCategories: [],
    regions: [],
    jobListCache: null,
    jobIntention: {
      categoryIds: [],
      regionCodes: [],
      industryIds: [],
      employmentType: 0,
    },
    userInfo: null,
    showSettings: false,
    settingsTab: 'account',
  },
  getters: {
    getAppName: (state) => state.appName,
  },
  mutations: {
    SET_APP_NAME(state, name: string) {
      state.appName = name
    },
    SET_SHOW_LOGIN(state, show: boolean) {
      state.showLogin = show
    },
    SET_LOGIN_REDIRECT(state, path: string) {
      state.loginRedirect = path
    },
    SET_AUTHENTICATED(state, val: boolean) {
      state.isAuthenticated = val
      if (val) {
        sessionStorage.setItem('isAuthenticated', 'true')
      } else {
        sessionStorage.removeItem('isAuthenticated')
      }
    },
    SET_DYNAMIC_MENUS(state, menus: MenuItemRaw[]) {
      state.dynamicMenus = menus
    },
    SET_ROUTES_LOADED(state, loaded: boolean) {
      state.routesLoaded = loaded
    },
    SET_DYNAMIC_ROUTE_NAMES(state, names: string[]) {
      state.dynamicRouteNames = names
    },
    SET_INDUSTRIES(state, data: IndustryItem[]) {
      state.industries = data
    },
    SET_JOB_CATEGORIES(state, data: JobCategoryItem[]) {
      state.jobCategories = data
    },
    SET_REGIONS(state, data: RegionItem[]) {
      state.regions = data
    },
    SET_JOB_LIST_CACHE(state, cache: JobListCache | null) {
      state.jobListCache = cache
    },
    SET_JOB_INTENTION(state, data: JobIntention) {
      state.jobIntention = {
        categoryIds: data.categoryIds ?? [],
        regionCodes: data.regionCodes ?? [],
        industryIds: data.industryIds ?? [],
        employmentType: data.employmentType ?? 0,
      }
    },
    SET_USER_INFO(state, data: UserInfo | null) {
      state.userInfo = data
    },
    SET_SHOW_SETTINGS(state, show: boolean) {
      state.showSettings = show
    },
    SET_SETTINGS_TAB(state, tab: string) {
      state.settingsTab = tab
    },
  },
  actions: {
    updateAppName({ commit }, name: string) {
      commit('SET_APP_NAME', name)
    },
    openLogin({ commit }, redirect = '') {
      commit('SET_LOGIN_REDIRECT', redirect)
      commit('SET_SHOW_LOGIN', true)
    },
    closeLogin({ commit }) {
      commit('SET_SHOW_LOGIN', false)
      commit('SET_LOGIN_REDIRECT', '')
    },

    /**
     * 核心 action：从后端（或 mock）拉取菜单，转成路由并注册
     *
     * @param router — vue-router 实例，由路由守卫调用时传入
     *
     * 流程：
     *   1. 调 fetchUserRoutes 拿到后端菜单数据
     *   2. 存到 state.dynamicMenus（给 SideNav 渲染用）
     *   3. 用 buildDynamicRoutes 转成 RouteRecordRaw
     *   4. 逐条 router.addRoute 注册
     *   5. 记录已注册的路由名，标记 routesLoaded = true
     */
    async loadDynamicRoutes({ commit }, router: Router) {
      const menus = await fetchUserRoutes()
      commit('SET_DYNAMIC_MENUS', menus)

      const routes = buildDynamicRoutes(menus)
      const names: string[] = []

      for (const route of routes) {
        router.addRoute(route)
        if (route.name) names.push(route.name as string)
      }

      commit('SET_DYNAMIC_ROUTE_NAMES', names)
      commit('SET_ROUTES_LOADED', true)
    },

    /**
     * 登出：重置状态（不再操作 localStorage，登录状态由 Cookie 管理）
     * 注意：动态路由不清除，与登录状态无关
     */
    logout({ commit }) {
      commit('SET_AUTHENTICATED', false)
      commit('SET_SHOW_LOGIN', false)
      commit('SET_LOGIN_REDIRECT', '')
      commit('SET_USER_INFO', null)
      // 清除 Jobs 页面缓存数据
      commit('SET_JOB_LIST_CACHE', null)
      commit('SET_JOB_INTENTION', {
        categoryIds: [],
        regionCodes: [],
        industryIds: [],
        employmentType: 0,
      })
    },

    /**
     * 加载工具类公共数据（行业分类、岗位分类等）
     * 进首页和 Jobs 页时调用
     * 如果 store 中已有数据则跳过请求，避免重复加载
     * 传入 force = true 可强制刷新
     */
    async loadCommonData({ commit, state }, { force = false } = {}) {
      const needIndustry = force || state.industries.length === 0
      const needJobCategory = force || state.jobCategories.length === 0
      const needRegion = force || state.regions.length === 0

      // 三个都已缓存，直接返回
      if (!needIndustry && !needJobCategory && !needRegion) return

      try {
        const promises: Promise<any>[] = []
        // 按需发起请求，保持顺序以便后续取值
        promises.push(needIndustry ? fetchIndustryTree() : Promise.resolve(null))
        promises.push(needJobCategory ? fetchJobCategoryTree() : Promise.resolve(null))
        promises.push(needRegion ? fetchRegionTree() : Promise.resolve(null))

        const [industryRes, jobCategoryRes, regionRes] = await Promise.all(promises)

        if (industryRes && industryRes.code === '0' && industryRes.data) {
          commit('SET_INDUSTRIES', industryRes.data)
        }
        if (jobCategoryRes && jobCategoryRes.code === '0' && jobCategoryRes.data) {
          commit('SET_JOB_CATEGORIES', jobCategoryRes.data)
        }
        if (regionRes && regionRes.code === '0' && regionRes.data) {
          commit('SET_REGIONS', regionRes.data)
        }
      } catch (err) {
        console.error('[store] 加载公共分类数据失败', err)
      }
    },

    /**
     * 从接口加载求职意向数据到 store
     * JobGoalDialog 和 Jobs 页面都可调用
     */
    async loadJobIntention({ commit }) {
      try {
        const res = await fetchJobIntention()
        if (res.code === '0' && res.data) {
          commit('SET_JOB_INTENTION', res.data)
        }
      } catch (err) {
        console.error('[store] 加载求职意向失败', err)
      }
    },

    /**
     * 加载用户个人信息到 store
     * 登录状态下调用，多个页面可直接读取 store.state.userInfo
     */
    async loadUserInfo({ commit }) {
      try {
        const res = await fetchUserInfo()
        if (res.code === '0' && res.data) {
          commit('SET_USER_INFO', res.data)
        }
      } catch (err) {
        console.error('[store] 加载用户信息失败', err)
      }
    },

    /**
     * 保存求职意向：已登录时调接口保存并更新 store，未登录时仅更新 store
     * @param data 求职意向数据
     */
    async saveJobIntention({ commit, state }, data: JobIntention) {
      if (state.isAuthenticated) {
        // 已登录 — 调接口持久化，成功后同步 store
        const res = await saveJobIntention(data)
        if (res.code === '0') {
          commit('SET_JOB_INTENTION', data)
        }
        return res
      } else {
        // 未登录 — 仅本地更新 store，不请求接口
        commit('SET_JOB_INTENTION', data)
        return { code: '0', message: 'ok' }
      }
    },
  },
  modules: {},
})
