"use client"

import * as React from "react"
import { usePathname, useRouter, useSearchParams } from "next/navigation"

import { useT } from "@/components/locale-provider"
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
} from "@/components/ui/input-group"
import { IconSearch, IconX } from "@tabler/icons-react"

/**
 * Finding one person among 193.
 *
 * The url is the state, so the query runs on the server and a narrowed list is
 * a link somebody can send. Typing replaces rather than pushes, so Back does
 * not undo letters one at a time.
 */
export function PeopleSearch() {
  const t = useT()
  const router = useRouter()
  const pathname = usePathname()
  const params = useSearchParams()

  const query = params.get("q") ?? ""

  // Local state so the field stays responsive under the fingers, realigned when
  // the url changes without it, which is the Back button. Adjusting during
  // render rather than in an effect: an effect renders once with the old value
  // and again with the new one.
  const [text, setText] = React.useState(query)
  const [seen, setSeen] = React.useState(query)
  if (query !== seen) {
    setSeen(query)
    setText(query)
  }

  const pending = React.useRef<ReturnType<typeof setTimeout> | null>(null)
  React.useEffect(
    () => () => {
      if (pending.current) clearTimeout(pending.current)
    },
    [],
  )

  const onType = (value: string) => {
    setText(value)
    if (pending.current) clearTimeout(pending.current)
    pending.current = setTimeout(() => {
      const next = new URLSearchParams(params.toString())
      if (value) next.set("q", value)
      else next.delete("q")
      router.replace(next.size ? `${pathname}?${next}` : pathname, {
        scroll: false,
      })
    }, 250)
  }

  return (
    <InputGroup className="h-10 w-full sm:w-80">
      <InputGroupAddon>
        <IconSearch />
      </InputGroupAddon>
      <InputGroupInput
        placeholder={t("people.search")}
        value={text}
        onChange={(e) => onType(e.target.value)}
        aria-label={t("people.search")}
      />
      {text ? (
        <InputGroupAddon align="inline-end">
          <InputGroupButton
            aria-label={t("action.clear")}
            onClick={() => onType("")}
          >
            <IconX />
          </InputGroupButton>
        </InputGroupAddon>
      ) : null}
    </InputGroup>
  )
}
