// src/utils/storage.ts
import type { Ref } from 'vue'
import { useStorage as useVueUseStorage } from '@vueuse/core'

// 项目前缀（避免存储键冲突）
const PROJECT_PREFIX = 'foreign_'
type StorageType = 'local' | 'session'

/**
 * 给key添加项目前缀
 */
const addPrefix = (key: string): string => `${PROJECT_PREFIX}${key}`

/**
 * 获取对应的 Storage 实例
 */
const getStorageInstance = (type: StorageType = 'session') => {
  return type === 'local' ? localStorage : sessionStorage
}

/**
 * 通用方法：自动反序列化存储值
 */
const autoParse = (value: string | null) => {
  if (value === null) return undefined
  try {
    return JSON.parse(value)
  } catch (e) {
    return value
  }
}

/**
 * 增/改：设置存储值（默认localStorage，自动加前缀）
 */
export const setStorage = <T = unknown>(key: string, value: T, type: StorageType = 'session'): void => {
  const prefixedKey = addPrefix(key)
  const storage = getStorageInstance(type)
  let storedValue: string
  if (typeof value === 'object' && value !== null) {
    storedValue = JSON.stringify(value)
  } else {
    storedValue = String(value)
  }
  storage.setItem(prefixedKey, storedValue)
}

/**
 * 查：获取存储值（默认localStorage，自动加前缀，无需默认值）
 */
export const getStorage = <T = unknown>(
  key: string,
  type: StorageType = 'session',
  defaultValue?: T,
): T | undefined => {
  const prefixedKey = addPrefix(key)
  const storage = getStorageInstance(type)
  const rawValue = storage.getItem(prefixedKey)
  return rawValue === null ? defaultValue : (autoParse(rawValue) as T)
}

/**
 * 删：删除指定键
 */
export const removeStorage = (key: string, type: StorageType = 'session'): void => {
  const prefixedKey = addPrefix(key)
  getStorageInstance(type).removeItem(prefixedKey)
}

/**
 * 清空：只清空当前项目前缀的存储
 */
export const clearStorage = (type: StorageType = 'session'): void => {
  const storage = getStorageInstance(type)
  Object.keys(storage).forEach((key) => {
    if (key.startsWith(PROJECT_PREFIX)) {
      storage.removeItem(key)
    }
  })
}

/**
 * 响应式存储引用（兼容自动反序列化）
 */
export const useStorage = <T = unknown>(
  key: string,
  defaultValue: T,
  type: StorageType = 'session',
): Ref<T> => {
  const prefixedKey = addPrefix(key)
  return useVueUseStorage(prefixedKey, defaultValue, getStorageInstance(type), {
    serializer: {
      read: autoParse,
      write: (v: unknown) => {
        if (typeof v === 'object' && v !== null) {
          return JSON.stringify(v)
        }
        return String(v)
      },
    },
  }) as Ref<T>
}
