import { normalizeCorpIdFields } from './api-base-config'

const env = __VITE_ENV__;
const PREFIX = env.MP_CACHE_PREFIX
const EXPIRE_PREFIX = `${PREFIX}_expire_`

/**
 * 生成缓存key
 */
function getKey(key) {
  return PREFIX + key
}

/**
 * 生成过期时间key
 */
function getExpireKey(key) {
  return PREFIX + EXPIRE_PREFIX + key
}

/**
 * 检查是否过期
 */
function isExpired(key) {
  try {
    const expireTime = uni.getStorageSync(getExpireKey(key))
    if (expireTime && Date.now() > expireTime) {
      // 过期了，删除缓存
      uni.removeStorageSync(getKey(key))
      uni.removeStorageSync(getExpireKey(key))
      return true
    }
    return false
  } catch (e) {
    return false
  }
}

/**
 * 设置缓存
 * @param {string} key 缓存key
 * @param {any} value 缓存值
 * @param {number} expire 过期时间（秒），0表示永不过期
 */
function set(key, value, expire = 0) {
  try {
    const normalizedValue = normalizeCorpIdFields(value)
    // 序列化数据
    let serializedValue
    if (typeof normalizedValue === 'object' && normalizedValue !== null) {
      // 对象和数组需要JSON序列化
      serializedValue = JSON.stringify(normalizedValue)
    } else {
      // 基本类型直接存储
      serializedValue = normalizedValue
    }

    uni.setStorageSync(getKey(key), serializedValue)

    // 设置过期时间
    if (expire > 0) {
      const expireTime = Date.now() + expire * 1000
      uni.setStorageSync(getExpireKey(key), expireTime)
    }

    return true
  } catch (e) {
    console.error('缓存设置失败:', e)
    return false
  }
}

/**
 * 获取缓存
 * @param {string} key 缓存key
 * @param {any} defaultValue 默认值
 */
function get(key, defaultValue = null) {
  try {
    // 检查是否过期
    if (isExpired(key)) {
      return defaultValue
    }

    const value = uni.getStorageSync(getKey(key))
    if (value === '') {
      return defaultValue
    }

    // 尝试反序列化JSON
    if (typeof value === 'string') {
      try {
        // 尝试解析JSON
        const parsed = JSON.parse(value)
        const normalizedValue = normalizeCorpIdFields(parsed)
        if (JSON.stringify(normalizedValue) !== JSON.stringify(parsed)) {
          uni.setStorageSync(getKey(key), JSON.stringify(normalizedValue))
        }
        return normalizedValue
      } catch (e) {
        // 如果解析失败，说明是普通字符串，直接返回
        return value
      }
    }

    const normalizedValue = normalizeCorpIdFields(value)
    if (JSON.stringify(normalizedValue) !== JSON.stringify(value)) {
      uni.setStorageSync(getKey(key), normalizedValue)
    }
    return normalizedValue
  } catch (e) {
    console.error('缓存获取失败:', e)
    return defaultValue
  }
}

/**
 * 删除缓存
 * @param {string} key 缓存key
 */
function remove(key) {
  try {
    uni.removeStorageSync(getKey(key))
    uni.removeStorageSync(getExpireKey(key))
    return true
  } catch (e) {
    console.error('缓存删除失败:', e)
    return false
  }
}

/**
 * 检查缓存是否存在
 * @param {string} key 缓存key
 */
function has(key) {
  try {
    if (isExpired(key)) {
      return false
    }
    const value = uni.getStorageSync(getKey(key))
    return value !== ''
  } catch (e) {
    return false
  }
}

/**
 * 清空所有缓存
 */
function clear() {
  try {
    uni.clearStorageSync()
    return true
  } catch (e) {
    console.error('缓存清空失败:', e)
    return false
  }
}

/**
 * 获取缓存信息
 */
function getInfo() {
  try {
    const info = uni.getStorageInfoSync()
    return {
      keys: info.keys || [],
      currentSize: info.currentSize || 0,
      limitSize: info.limitSize || 0
    }
  } catch (e) {
    return {
      keys: [],
      currentSize: 0,
      limitSize: 0
    }
  }
}

/**
 * 批量设置缓存
 * @param {object} data key-value对象
 * @param {number} expire 过期时间（秒）
 */
function setBatch(data, expire = 0) {
  let success = true
  for (const [key, value] of Object.entries(data)) {
    if (!set(key, value, expire)) {
      success = false
    }
  }
  return success
}

/**
 * 批量获取缓存
 * @param {array} keys key数组
 */
function getBatch(keys) {
  const result = {}
  for (const key of keys) {
    result[key] = get(key)
  }
  return result
}

// 导出所有函数
export {
  set,
  get,
  remove,
  has,
  clear,
  getInfo,
  setBatch,
  getBatch
}

// 默认导出对象
export default {
  set,
  get,
  remove,
  has,
  clear,
  getInfo,
  setBatch,
  getBatch
}
