"use client"

import { useEffect, useRef, useState } from "react"
import { ChevronDown, Search } from "lucide-react"

import { cn } from "@/src/lib/utils"
import { Input } from "@/src/components/ui/input"
import { countries } from "@/src/utils/constants"
import type { Country } from "@/src/types/constant"

interface PhoneInputProps {
  value?: string
  onChange?: (fullPhoneNumber: string) => void
  onBlur?: () => void
  placeholder?: string
  className?: string
  disabled?: boolean
  defaultCountry?: string
}

export default function PhoneInput({
  value = "",
  onChange,
  onBlur,
  placeholder = "76 123 456",
  className,
  disabled = false,
  defaultCountry = "BF",
}: PhoneInputProps) {
  const defaultCountryData = countries.find((c) => c.code === defaultCountry) ?? countries[0]

  const [selectedCountry, setSelectedCountry] = useState<Country>(defaultCountryData)
  const [phoneNumber, setPhoneNumber] = useState("")
  const [isOpen, setIsOpen] = useState(false)
  const [searchQuery, setSearchQuery] = useState("")
  const [dropdownPosition, setDropdownPosition] = useState<"bottom" | "top">("bottom")

  const dropdownRef = useRef<HTMLDivElement>(null)
  const containerRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (value && value !== `${selectedCountry.dialCode}${phoneNumber}`) {
      const matchingCountry = countries.find((c) => value.startsWith(c.dialCode))
      if (matchingCountry) {
        setSelectedCountry(matchingCountry)
        setPhoneNumber(value.slice(matchingCountry.dialCode.length))
      } else {
        setPhoneNumber(value)
      }
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value])

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setIsOpen(false)
        setSearchQuery("")
      }
    }
    document.addEventListener("mousedown", handleClickOutside)
    return () => document.removeEventListener("mousedown", handleClickOutside)
  }, [])

  useEffect(() => {
    if (isOpen && containerRef.current) {
      const rect = containerRef.current.getBoundingClientRect()
      const spaceBelow = window.innerHeight - rect.bottom
      setDropdownPosition(spaceBelow < 240 && rect.top > 240 ? "top" : "bottom")
    }
  }, [isOpen])

  const filteredCountries = countries.filter(
    (c) =>
      c.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
      c.dialCode.includes(searchQuery),
  )

  const handleCountrySelect = (country: Country) => {
    setSelectedCountry(country)
    setIsOpen(false)
    setSearchQuery("")
    onChange?.(`${country.dialCode}${phoneNumber}`)
  }

  const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const digits = e.target.value.replace(/\D/g, "")
    setPhoneNumber(digits)
    onChange?.(digits ? `${selectedCountry.dialCode}${digits}` : "")
  }

  return (
    <div className={cn("relative", className)} ref={containerRef}>
      <div className="flex rounded-lg border border-input bg-transparent">
        <button
          type="button"
          disabled={disabled}
          onClick={() => !disabled && setIsOpen((v) => !v)}
          className="flex items-center gap-1.5 border-r px-3 hover:bg-muted transition-colors disabled:cursor-not-allowed disabled:opacity-50 rounded-l-lg"
        >
          <span className="text-base">{selectedCountry.flag}</span>
          <ChevronDown className="size-3.5 text-muted-foreground" />
        </button>

        <div className="flex flex-1 items-center">
          <span className="pl-2.5 text-sm text-muted-foreground shrink-0">
            {selectedCountry.dialCode}
          </span>
          <Input
            type="tel"
            value={phoneNumber}
            onChange={handlePhoneChange}
            onBlur={onBlur}
            placeholder={placeholder}
            disabled={disabled}
            maxLength={12}
            className="border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-2"
          />
        </div>
      </div>

      {isOpen && (
        <div
          ref={dropdownRef}
          className={cn(
            "absolute left-0 z-50 w-full overflow-hidden rounded-lg border bg-background shadow-lg",
            dropdownPosition === "top" ? "bottom-full mb-1" : "top-full mt-1",
          )}
        >
          <div className="p-2 border-b">
            <div className="relative">
              <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground" />
              <Input
                placeholder="Rechercher un pays..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                className="pl-8"
                onClick={(e) => e.stopPropagation()}
              />
            </div>
          </div>
          <div className="max-h-48 overflow-y-auto">
            {filteredCountries.map((country) => (
              <button
                key={country.code}
                type="button"
                onClick={(e) => {
                  e.preventDefault()
                  e.stopPropagation()
                  handleCountrySelect(country)
                }}
                className="flex w-full items-center justify-between px-3 py-2 text-left hover:bg-muted transition-colors"
              >
                <div className="flex items-center gap-2.5">
                  <span className="text-base">{country.flag}</span>
                  <span className="text-sm">{country.name}</span>
                </div>
                <span className="text-sm text-muted-foreground">{country.dialCode}</span>
              </button>
            ))}
            {filteredCountries.length === 0 && (
              <p className="px-3 py-2 text-sm text-muted-foreground">Aucun pays trouvé</p>
            )}
          </div>
        </div>
      )}
    </div>
  )
}
