export const WATCHLIST_STORAGE_KEY = 'explorerWatchlist'

const addressPattern = /^0x[a-f0-9]{40}$/i

export function normalizeWatchlistAddress(value: string) {
  const trimmed = value.trim()
  return addressPattern.test(trimmed) ? `0x${trimmed.slice(2)}` : ''
}

export function sanitizeWatchlistEntries(input: unknown) {
  if (!Array.isArray(input)) {
    return [] as string[]
  }

  const seen = new Set<string>()
  const next: string[] = []

  for (const entry of input) {
    if (typeof entry !== 'string') {
      continue
    }

    const normalized = normalizeWatchlistAddress(entry)
    if (!normalized) {
      continue
    }

    const key = normalized.toLowerCase()
    if (seen.has(key)) {
      continue
    }

    seen.add(key)
    next.push(normalized)
  }

  return next
}

export function parseStoredWatchlist(raw: string | null) {
  if (!raw) {
    return [] as string[]
  }

  try {
    return sanitizeWatchlistEntries(JSON.parse(raw))
  } catch {
    return []
  }
}

export function readWatchlistFromStorage(storage: Pick<Storage, 'getItem'>) {
  return parseStoredWatchlist(storage.getItem(WATCHLIST_STORAGE_KEY))
}

export function writeWatchlistToStorage(
  storage: Pick<Storage, 'setItem'>,
  entries: string[],
) {
  storage.setItem(
    WATCHLIST_STORAGE_KEY,
    JSON.stringify(sanitizeWatchlistEntries(entries)),
  )
}

export function isWatchlistEntry(entries: string[], address: string) {
  const normalized = normalizeWatchlistAddress(address)
  if (!normalized) {
    return false
  }

  return entries.some((entry) => entry.toLowerCase() === normalized.toLowerCase())
}

export function toggleWatchlistEntry(entries: string[], address: string) {
  const normalized = normalizeWatchlistAddress(address)
  if (!normalized) {
    return sanitizeWatchlistEntries(entries)
  }

  if (isWatchlistEntry(entries, normalized)) {
    return entries.filter((entry) => entry.toLowerCase() !== normalized.toLowerCase())
  }

  return sanitizeWatchlistEntries([...entries, normalized])
}
