"use client"

import { ChangeEvent, useEffect, useMemo, useState } from "react"

import { cn } from "@/lib/utils"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"

export type CountryOption = {
  code: string
  label: string
  dialCode: string
  flag: string
  maxDigits: number
  formatLocal: (digits: string) => string
}

const COUNTRY_OPTIONS: CountryOption[] = [
  {
    code: "BR",
    label: "Brasil",
    dialCode: "+55",
    flag: "🇧🇷",
    maxDigits: 11,
    formatLocal: formatBrazilPhone,
  },
  {
    code: "US",
    label: "Estados Unidos",
    dialCode: "+1",
    flag: "🇺🇸",
    maxDigits: 10,
    formatLocal: formatUsPhone,
  },
]

const DEFAULT_COUNTRY = COUNTRY_OPTIONS[0]

function formatBrazilPhone(digits: string): string {
  const cleaned = digits.slice(0, 11)
  if (!cleaned) return ""
  const area = cleaned.slice(0, 2)
  const rest = cleaned.slice(2)
  if (cleaned.length <= 2) return `(${cleaned}`
  if (rest.length <= 4) return `(${area}) ${rest}`
  if (rest.length <= 8) return `(${area}) ${rest.slice(0, 4)}-${rest.slice(4)}`
  return `(${area}) ${rest.slice(0, 5)}-${rest.slice(5)}`
}

function formatUsPhone(digits: string): string {
  const cleaned = digits.slice(0, 10)
  if (!cleaned) return ""
  const area = cleaned.slice(0, 3)
  const rest = cleaned.slice(3)
  if (cleaned.length <= 3) return `(${cleaned}`
  if (rest.length <= 3) return `(${area}) ${rest}`
  return `(${area}) ${rest.slice(0, 3)}-${rest.slice(3)}`
}

function extractDigits(value?: string | null): string {
  return (value ?? "").replace(/\D+/g, "")
}

function findCountryByValue(value?: string | null): CountryOption {
  const digits = extractDigits(value)
  return (
    COUNTRY_OPTIONS.find((option) => {
      const dialDigits = extractDigits(option.dialCode)
      return digits.startsWith(dialDigits) && digits.length > dialDigits.length
    }) ?? DEFAULT_COUNTRY
  )
}

function toLocalDigits(value: string | null | undefined, country: CountryOption): string {
  const digits = extractDigits(value)
  const dialDigits = extractDigits(country.dialCode)
  return digits.startsWith(dialDigits) ? digits.slice(dialDigits.length) : digits
}

function formatStoredValue(country: CountryOption, localDigits: string): string {
  const trimmed = localDigits.trim()
  if (!trimmed) return ""
  const formattedLocal = country.formatLocal(trimmed)
  if (!formattedLocal) return country.dialCode
  return `${country.dialCode} ${formattedLocal}`.trim()
}

function placeholderFor(country: CountryOption): string {
  if (country.code === "BR") return "(11) 91234-5678"
  if (country.code === "US") return "(555) 123-4567"
  return "Número de telefone"
}

export function PhoneInput({ value, onChange, className }: PhoneInputProps) {
  const [selectedCountry, setSelectedCountry] = useState<CountryOption>(DEFAULT_COUNTRY)
  const [localDigits, setLocalDigits] = useState<string>("")

  useEffect(() => {
    const country = findCountryByValue(value)
    setSelectedCountry(country)
    setLocalDigits(toLocalDigits(value, country).slice(0, country.maxDigits))
  }, [value])

  const displayValue = useMemo(() => selectedCountry.formatLocal(localDigits), [selectedCountry, localDigits])

  const handleCountryChange = (code: string) => {
    const country = COUNTRY_OPTIONS.find((option) => option.code === code) ?? DEFAULT_COUNTRY
    setSelectedCountry(country)
    const limitedDigits = localDigits.slice(0, country.maxDigits)
    setLocalDigits(limitedDigits)
    const stored = formatStoredValue(country, limitedDigits)
    onChange?.(stored)
  }

  const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    const raw = event.target.value
    const digits = extractDigits(raw).slice(0, selectedCountry.maxDigits)
    setLocalDigits(digits)
    const stored = formatStoredValue(selectedCountry, digits)
    onChange?.(stored)
  }

  return (
    <div className={cn("flex flex-col gap-2 sm:flex-row sm:items-center", className)}>
      <Select value={selectedCountry.code} onValueChange={handleCountryChange}>
        <SelectTrigger className="w-40">
          <SelectValue>
            <span className="inline-flex items-center gap-2">
              <span>{selectedCountry.flag}</span>
              <span className="text-sm font-medium text-foreground">{selectedCountry.dialCode}</span>
            </span>
          </SelectValue>
        </SelectTrigger>
        <SelectContent>
          {COUNTRY_OPTIONS.map((option) => (
            <SelectItem key={option.code} value={option.code}>
              <span className="inline-flex items-center gap-2">
                <span>{option.flag}</span>
                <span>{option.label}</span>
                <span className="text-muted-foreground">{option.dialCode}</span>
              </span>
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
      <Input
        type="tel"
        value={displayValue}
        onChange={handleInputChange}
        placeholder={placeholderFor(selectedCountry)}
        inputMode="tel"
      />
    </div>
  )
}

export type PhoneInputProps = {
  value?: string | null
  onChange?: (value: string) => void
  className?: string
}

export function formatPhoneDisplay(rawValue?: string | null): string | null {
  const trimmed = rawValue?.trim()
  if (!trimmed) return null
  const country = findCountryByValue(trimmed)
  const localDigits = toLocalDigits(trimmed, country)
  const formattedLocal = country.formatLocal(localDigits)
  if (!formattedLocal) return `${country.dialCode}`.trim()
  return `${country.dialCode} ${formattedLocal}`.trim()
}
