import { useEffect, useState } from 'react'
import { isAbortError } from '../lib/api'
import { searchUsers } from '../services/userService'
import type { UserSearchItem } from '../types/user'
import styles from './UserSearchInput.module.css'

const DEFAULT_MIN_CHARS = 2

export interface UserSearchInputProps {
  id?: string
  label?: string
  placeholder?: string
  disabled?: boolean
  minChars?: number
  selectedUser: UserSearchItem | null
  onSelect: (user: UserSearchItem | null) => void
}

export function UserSearchInput({
  id = 'user-search',
  label = 'User',
  placeholder = 'Search by name, email, or phone',
  disabled = false,
  minChars = DEFAULT_MIN_CHARS,
  selectedUser,
  onSelect,
}: UserSearchInputProps) {
  const [query, setQuery] = useState(selectedUser?.label ?? '')
  const [results, setResults] = useState<UserSearchItem[]>([])
  const [searching, setSearching] = useState(false)

  useEffect(() => {
    setQuery(selectedUser?.label ?? '')
  }, [selectedUser])

  useEffect(() => {
    if (query.trim().length < minChars || selectedUser) {
      setResults([])
      setSearching(false)
      return
    }

    const controller = new AbortController()
    const timer = setTimeout(() => {
      setSearching(true)
      void searchUsers(query.trim(), 20, controller.signal)
        .then((result) => {
          if (!controller.signal.aborted) setResults(result.items)
        })
        .catch((err) => {
          if (!isAbortError(err) && !controller.signal.aborted) {
            setResults([])
          }
        })
        .finally(() => {
          if (!controller.signal.aborted) setSearching(false)
        })
    }, 300)

    return () => {
      clearTimeout(timer)
      controller.abort()
    }
  }, [query, minChars, selectedUser])

  const showDropdown = query.trim().length >= minChars && !selectedUser

  function handleQueryChange(value: string) {
    setQuery(value)
    if (selectedUser && value !== selectedUser.label) {
      onSelect(null)
    }
  }

  function pickUser(user: UserSearchItem) {
    onSelect(user)
    setQuery(user.label)
    setResults([])
  }

  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <div className={styles.wrap}>
        <input
          id={id}
          value={query}
          onChange={(e) => handleQueryChange(e.target.value)}
          placeholder={placeholder}
          autoComplete="off"
          disabled={disabled}
        />
        {showDropdown && (
          <div className={styles.dropdown}>
            {searching ? (
              <div className={styles.empty}>Searching...</div>
            ) : results.length === 0 ? (
              <div className={styles.empty}>No users found.</div>
            ) : (
              results.map((user) => (
                <button
                  key={user.id}
                  type="button"
                  className={styles.item}
                  onClick={() => pickUser(user)}
                >
                  {user.label}
                </button>
              ))
            )}
          </div>
        )}
      </div>
      {query.trim().length > 0 && query.trim().length < minChars && (
        <div className={styles.hint}>Type at least {minChars} characters to search.</div>
      )}
      {selectedUser && <div className={styles.selected}>Selected: {selectedUser.label}</div>}
    </div>
  )
}
