import { RouteRecordRaw } from 'vue-router'
import { PrimaryTableCol } from 'tdesign-vue-next'
import { useAuthStore } from '@/stores/modules/auth'
import { cloneDeep } from 'lodash-es'

export const EMPTY = '-' // 空占位符

// 插槽名
export const soltName = (col: PrimaryTableCol) => {
  return col.colKey as string
}

// 系统权限按钮
export const buttonPms = (key: string) => {
  const userAuth = useAuthStore()
  return userAuth.authButtonList.includes(key)
}

/**
 * @description 获取localStorage
 * @param {String} key Storage名称
 * @returns {String}
 */
export const localGet = (key: string) => {
  const value = window.localStorage.getItem(key)
  try {
    return JSON.parse(window.localStorage.getItem(key) as string)
  } catch (error) {
    return value
  }
}

/**
 * @description 存储localStorage
 * @param {String} key Storage名称
 * @param {*} value Storage值
 * @returns {void}
 */
export const localSet = (key: string, value: any) => {
  window.localStorage.setItem(key, JSON.stringify(value))
}

/**
 * @description 清除localStorage
 * @param {String} key Storage名称
 * @returns {void}
 */
export const localRemove = (key: string) => {
  window.localStorage.removeItem(key)
}

/**
 * @description 清除所有localStorage
 * @returns {void}
 */
export const localClear = () => {
  window.localStorage.clear()
}

/**
 * @description 判断数据类型
 * @param {*} val 需要判断类型的数据
 * @returns {String}
 */
export const isType = (val: any) => {
  if (val === null) return 'null'
  if (typeof val !== 'object') return typeof val
  else return Object.prototype.toString.call(val).slice(8, -1).toLocaleLowerCase()
}

/**
 * @description 生成唯一 uuid
 * @returns {String}
 */
export const generateUUID = () => {
  let uuid = ''
  for (let i = 0; i < 32; i++) {
    let random = (Math.random() * 16) | 0
    if (i === 8 || i === 12 || i === 16 || i === 20) uuid += '-'
    uuid += (i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random).toString(16)
  }
  return uuid
}

/**
 * 判断两个对象是否相同
 * @param {Object} a 要比较的对象一
 * @param {Object} b 要比较的对象二
 * @returns {Boolean} 相同返回 true，反之 false
 */
export const isObjectValueEqual = (a: { [key: string]: any }, b: { [key: string]: any }) => {
  if (!a || !b) return false
  let aProps = Object.getOwnPropertyNames(a)
  let bProps = Object.getOwnPropertyNames(b)
  if (aProps.length != bProps.length) return false
  for (let i = 0; i < aProps.length; i++) {
    let propName = aProps[i]
    let propA = a[propName]
    let propB = b[propName]
    if (!Object.prototype.hasOwnProperty.call(b, propName)) return false
    if (propA instanceof Object) {
      if (!isObjectValueEqual(propA, propB)) return false
    } else if (propA !== propB) {
      return false
    }
  }
  return true
}

/**
 * @description 生成随机数
 * @param {Number} min 最小值
 * @param {Number} max 最大值
 * @returns {Number}
 */
export const randomNum = (min: number, max: number): number => {
  return Math.floor(Math.random() * (min - max) + max)
}

/**
 * @description 使用递归扁平化菜单，方便添加动态路由
 * @param {Array} menuList 菜单列表
 * @returns {Array}
 */
export const getFlatMenuList = (menuList: Menu.MenuOptions[]): Menu.MenuOptions[] => {
  let newMenuList: Menu.MenuOptions[] = JSON.parse(JSON.stringify(menuList))
  return newMenuList.flatMap(item => [item, ...(item.children ? getFlatMenuList(item.children) : [])])
}

/**
 * @description 递归查询当前 name 所对应的菜单对象
 * @param {Array} menuList 菜单列表
 * @param {String} name 当前访问路由name
 * @returns {Object | null}
 */
export const findMenuByName = (menuList: any[], name: string): any => {
  for (const item of menuList) {
    if (item.menuSign === name) return item
    if (item.children) {
      const res = findMenuByName(item.children, name)
      if (res) return res
    }
  }
  return null
}

/**
 * @description 使用递归扁平化路由表
 * @param {RouteRecordRaw[]} routes 路由表
 * @returns {RouteRecordRaw[]}
 */
export const getFlatRouters = (routes: RouteRecordRaw[]): RouteRecordRaw[] => {
  const newRouteList = cloneDeep(routes)
  return newRouteList.flatMap((item: any) => [item, ...(item.children ? getFlatRouters(item.children) : [])])
}

// 是否为电话号码
export const isPhoneNumber = function (phone: string): boolean {
  const isMob = /^((\+?86)|(\(\+86\)))?(1[3-9][0-9]{9})$/
  return isMob.test(phone)
}

// 格式化输出内容，将行间公式和行内公式替换为对应的数学公式组件
export function formatOutputKatex(content: string) {
  if (!content) return ''

  const replaceFormula = (formula: string) => {
    formula = formula.replace(/\s+/g, ' ').trim() // 去除换行符和多余空格
    return `$${formula}$`
  }

  // 替换行间公式 \[ ... \]
  content = content.replace(/\\\[(.*?)\\\]/gs, (match, formula) => replaceFormula(formula))

  // 替换行内公式 \( ... \)
  content = content.replace(/\\\((.*?)\\\)/gs, (match, formula) => replaceFormula(formula))

  return content
}
