"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(DEFAULT_COUNTRY) const [localDigits, setLocalDigits] = useState("") 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) => { const raw = event.target.value const digits = extractDigits(raw).slice(0, selectedCountry.maxDigits) setLocalDigits(digits) const stored = formatStoredValue(selectedCountry, digits) onChange?.(stored) } return (
) } 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() }