"use client"

import { useEffect, useRef, useState } from "react"
import { useEntrySearch } from "@/lib/queries/use-entry-search"
import { useUserInterfaceStore } from "@/lib/stores/user-interface-store"

function getMatchSnippet(text: string, query: string): string | null {
  const stripped = text.replace(/<[^>]*>/g, "")
  const lowerStripped = stripped.toLowerCase()
  const matchIndex = lowerStripped.indexOf(query)
  if (matchIndex === -1) return null
  const start = Math.max(0, matchIndex - 40)
  const end = Math.min(stripped.length, matchIndex + query.length + 80)
  const prefix = start > 0 ? "\u2026" : ""
  const suffix = end < stripped.length ? "\u2026" : ""
  return prefix + stripped.slice(start, end) + suffix
}

function highlightText(text: string, query: string): React.ReactNode {
  if (!query) return text
  const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  const parts = text.split(new RegExp(`(${escapedQuery})`, "gi"))
  return parts.map((part, index) =>
    part.toLowerCase() === query.toLowerCase() ? (
      <mark key={index} className="bg-[rgba(234,179,8,0.18)] text-text-primary">
        {part}
      </mark>
    ) : (
      part
    )
  )
}

interface SearchOverlayProperties {
  onClose: () => void
}

export function SearchOverlay({ onClose }: SearchOverlayProperties) {
  const [searchQuery, setSearchQuery] = useState("")
  const [selectedResultIndex, setSelectedResultIndex] = useState(-1)
  const inputReference = useRef<HTMLInputElement>(null)
  const resultListReference = useRef<HTMLDivElement>(null)
  const { data: results, isLoading } = useEntrySearch(searchQuery)
  const setSelectedEntryIdentifier = useUserInterfaceStore(
    (state) => state.setSelectedEntryIdentifier
  )

  useEffect(() => {
    inputReference.current?.focus()
  }, [])

  useEffect(() => {
    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === "Escape") {
        onClose()
      }
    }

    document.addEventListener("keydown", handleKeyDown)

    return () => document.removeEventListener("keydown", handleKeyDown)
  }, [onClose])

  function handleSelectEntry(entryIdentifier: string) {
    setSelectedEntryIdentifier(entryIdentifier)
    onClose()
  }

  function handleInputKeyDown(event: React.KeyboardEvent) {
    if (event.key === "Backspace" && searchQuery === "") {
      onClose()
      return
    }

    if (!results || results.length === 0) return

    if (event.key === "ArrowDown") {
      event.preventDefault()
      setSelectedResultIndex((previous) => {
        const nextIndex = previous < results.length - 1 ? previous + 1 : 0
        scrollResultIntoView(nextIndex)
        return nextIndex
      })
    } else if (event.key === "ArrowUp") {
      event.preventDefault()
      setSelectedResultIndex((previous) => {
        const nextIndex = previous > 0 ? previous - 1 : results.length - 1
        scrollResultIntoView(nextIndex)
        return nextIndex
      })
    } else if (event.key === "Enter" && selectedResultIndex >= 0) {
      event.preventDefault()
      handleSelectEntry(results[selectedResultIndex].entryIdentifier)
    }
  }

  function scrollResultIntoView(index: number) {
    const container = resultListReference.current
    if (!container) return
    const items = container.querySelectorAll("[data-result-item]")
    items[index]?.scrollIntoView({ block: "nearest" })
  }

  function handleBackdropClick(event: React.MouseEvent) {
    if (event.target === event.currentTarget) {
      onClose()
    }
  }

  return (
    <div
      className="fixed inset-0 z-50 flex items-start justify-center bg-black/50 pt-[15vh]"
      onClick={handleBackdropClick}
    >
      <div className="w-full max-w-lg border border-border bg-background-primary shadow-lg">
        <div className="border-b border-border px-4 py-3">
          <input
            ref={inputReference}
            type="text"
            value={searchQuery}
            onChange={(event) => {
              setSearchQuery(event.target.value)
              setSelectedResultIndex(-1)
            }}
            onKeyDown={handleInputKeyDown}
            placeholder="search entries..."
            className="w-full bg-transparent text-text-primary outline-none placeholder:text-text-dim"
          />
        </div>
        <div ref={resultListReference} className="max-h-80 overflow-auto">
          {isLoading && searchQuery.trim().length >= 2 && (
            <p className="px-4 py-3 text-text-dim">searching...</p>
          )}
          {!isLoading &&
            searchQuery.trim().length >= 2 &&
            results?.length === 0 && (
              <p className="px-4 py-3 text-text-dim">no results</p>
            )}
          {results?.map((entry, index) => {
            const query = searchQuery.trim().toLowerCase()
            const titleMatches = (entry.entryTitle ?? "").toLowerCase().includes(query)
            const summarySnippet = !titleMatches && entry.summary
              ? getMatchSnippet(entry.summary, query)
              : null

            return (
              <button
                key={entry.entryIdentifier}
                type="button"
                data-result-item
                onClick={() => handleSelectEntry(entry.entryIdentifier)}
                className={`block w-full px-4 py-2 text-left transition-colors hover:bg-background-tertiary ${
                  index === selectedResultIndex
                    ? "bg-background-tertiary"
                    : ""
                }`}
              >
                <p className="truncate text-text-primary">
                  {titleMatches
                    ? highlightText(entry.entryTitle ?? "", query)
                    : entry.entryTitle}
                </p>
                <p className="truncate text-[0.6875rem] text-text-dim">
                  {entry.customTitle ?? entry.feedTitle}
                  {entry.author && ` \u00b7 ${entry.author}`}
                </p>
                {summarySnippet && (
                  <p className="mt-0.5 line-clamp-2 text-[0.6875rem] text-text-secondary">
                    {highlightText(summarySnippet, query)}
                  </p>
                )}
              </button>
            )
          })}
        </div>
      </div>
    </div>
  )
}
