import type { LocationQuery, LocationQueryRaw } from 'vue-router'

// 注意：zone（专区）不纳入筛选持久化体系，作为独立的视图切换状态。
// 否则切回“全部专区”时，空 query 会回退读取 sessionStorage 中残留的旧 zone，导致专区被弹回。
export const desktopHomeFilterQueryKeys = [
  'keyword',
  'sort',
  'server',
  'region',
  'login_method',
  'rank',
  'insurance',
  'stamina',
  'load',
  'skin_group',
  'skin_name',
  'min_coin',
  'max_coin',
  'min_price',
  'max_price',
  'min_deposit',
  'max_deposit',
  'min_total',
  'max_total',
  'min_fire_level',
  'max_fire_level',
] as const

export const mobileHomeFilterQueryKeys = ['keyword', 'sort', 'zone', 'filters', 'ranges'] as const

export type HomeQueryValue = string | number | undefined

export const desktopHomeFilterStorageKey = 'hfb.home.filters.desktop'
export const mobileHomeFilterStorageKey = 'hfb.home.filters.mobile'

export function readQueryString(query: LocationQuery | LocationQueryRaw, key: string) {
  const value = query[key]
  if (Array.isArray(value)) return String(value[0] || '')
  return value === undefined || value === null ? '' : String(value)
}

export function readQueryNumber(query: LocationQuery | LocationQueryRaw, key: string) {
  const value = readQueryString(query, key)
  if (value === '') return undefined
  const number = Number(value)
  return Number.isFinite(number) ? number : undefined
}

export function mergeHomeQuery(
  currentQuery: LocationQuery,
  managedKeys: readonly string[],
  nextValues: Record<string, HomeQueryValue>
): LocationQueryRaw {
  const managedKeySet = new Set(managedKeys)
  const nextQuery: LocationQueryRaw = {}

  for (const [key, value] of Object.entries(currentQuery)) {
    if (!managedKeySet.has(key)) nextQuery[key] = value
  }

  for (const [key, value] of Object.entries(nextValues)) {
    if (value === undefined || value === '') continue
    nextQuery[key] = String(value)
  }

  return nextQuery
}

export function isSameQuery(left: LocationQuery, right: LocationQueryRaw) {
  return stableQuerySignature(left) === stableQuerySignature(right)
}

export function hasHomeQueryValues(
  query: LocationQuery | LocationQueryRaw,
  keys: readonly string[]
) {
  return keys.some(key => {
    const value = query[key]
    if (Array.isArray(value)) return value.some(item => item !== undefined && item !== '')
    return value !== undefined && value !== ''
  })
}

export function readStoredHomeQuery(storageKey: string): LocationQueryRaw {
  if (typeof window === 'undefined') return {}
  try {
    const raw = window.sessionStorage.getItem(storageKey)
    if (!raw) return {}
    const parsed = JSON.parse(raw)
    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {}
    const query: LocationQueryRaw = {}
    for (const [key, value] of Object.entries(parsed)) {
      if (typeof value === 'string' && value !== '') query[key] = value
    }
    return query
  } catch {
    return {}
  }
}

export function storeHomeQuery(storageKey: string, query: LocationQueryRaw) {
  if (typeof window === 'undefined') return
  try {
    window.sessionStorage.setItem(storageKey, JSON.stringify(query))
  } catch {
    // 浏览器禁用 sessionStorage 时忽略，URL 仍然可用。
  }
}

export function clearStoredHomeQuery(storageKey: string) {
  if (typeof window === 'undefined') return
  try {
    window.sessionStorage.removeItem(storageKey)
  } catch {
    // 浏览器禁用 sessionStorage 时忽略。
  }
}

export function encodeHomeQueryJson(value: unknown) {
  if (!hasMeaningfulValue(value)) return undefined
  return JSON.stringify(value)
}

export function decodeHomeQueryJson<T>(
  query: LocationQuery | LocationQueryRaw,
  key: string,
  fallback: T
): T {
  const raw = readQueryString(query, key)
  if (!raw) return fallback
  try {
    const parsed = JSON.parse(raw)
    return parsed && typeof parsed === 'object' ? (parsed as T) : fallback
  } catch {
    return fallback
  }
}

function stableQuerySignature(query: LocationQuery | LocationQueryRaw) {
  const entries: Array<[string, string | string[]]> = Object.entries(query)
    .filter(([, value]) => value !== undefined && value !== '')
    .map(([key, value]) => [
      key,
      Array.isArray(value) ? value.map(item => String(item ?? '')) : String(value ?? ''),
    ])

  return JSON.stringify(entries.sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)))
}

function hasMeaningfulValue(value: unknown): boolean {
  if (!value || typeof value !== 'object') return false
  if (Array.isArray(value)) return value.length > 0

  return Object.values(value).some(item => {
    if (Array.isArray(item)) return item.length > 0
    if (!item || typeof item !== 'object') return item !== '' && item !== undefined
    return Object.values(item).some(nested => nested !== '' && nested !== undefined)
  })
}
