import * as React from 'react';
import { cn } from '@/lib/utils';
import { Label } from '@/components/ui/label';
import PhoneInputLib, { type Country } from 'react-phone-number-input';
import flags from 'react-phone-number-input/flags';

type PhoneValue = string | undefined;

interface PhoneInputProps {
    value?: PhoneValue;
    onChange?: (value: PhoneValue) => void;
    onBlur?: () => void;
    defaultCountry?: Country;
    disabled?: boolean;
    placeholder?: string;
    className?: string;
    error?: boolean;
    international?: boolean;
    countryCallingCodeEditable?: boolean;
}

const CustomInput = React.forwardRef<HTMLInputElement, React.ComponentProps<'input'> & { error?: boolean }>(
    ({ className, error, ...props }, ref) => {
        return (
            <input
                ref={ref}
                className={cn(
                    'flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none',
                    'placeholder:text-gray-400',
                    'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
                    'disabled:cursor-not-allowed disabled:opacity-50',
                    error && 'border-destructive focus-visible:border-destructive focus-visible:ring-destructive/20',
                    className
                )}
                {...props}
            />
        );
    }
);

CustomInput.displayName = 'CustomInput';

const PhoneInput = React.forwardRef<HTMLInputElement, PhoneInputProps>(
    (
        {
            value,
            onChange,
            onBlur,
            defaultCountry = 'US',
            disabled = false,
            placeholder = 'Enter phone number',
            className,
            error = false,
            international = true,
            countryCallingCodeEditable = false,
        },
        ref
    ) => {
        const handleChange = (val: PhoneValue) => {
            if (onChange) {
                onChange(val);
            }
        };

        return (
            <div className={cn('relative phone-input-container', className)}>
                <PhoneInputLib
                    ref={ref as any}
                    international={international}
                    countryCallingCodeEditable={countryCallingCodeEditable}
                    defaultCountry={defaultCountry}
                    value={value || ''}
                    onChange={handleChange}
                    onBlur={onBlur}
                    disabled={disabled}
                    placeholder={placeholder}
                    flags={flags}
                    inputComponent={CustomInput}
                    className={cn('phone-input-wrapper', error && 'phone-input-error')}
                    style={
                        {
                            '--PhoneInputCountryFlag-height': '1.125rem',
                            '--PhoneInput-color--focus': 'hsl(var(--ring))',
                        } as React.CSSProperties
                    }
                />
            </div>
        );
    }
);

PhoneInput.displayName = 'PhoneInput';

interface PhoneInputFieldProps extends PhoneInputProps {
    label?: string;
    name?: string;
    required?: boolean;
    errorMessage?: string;
    helperText?: string;
    labelClassName?: string;
}

const PhoneInputField = React.forwardRef<HTMLInputElement, PhoneInputFieldProps>(
    ({ label, name, required, errorMessage, helperText, labelClassName, className, error, ...props }, ref) => {
        const hasError = error || !!errorMessage;

        return (
            <div className="space-y-2">
                {label && (
                    <Label htmlFor={name} className={cn('text-sm font-medium text-foreground', labelClassName)}>
                        {label}
                        {required && <span className="ml-1 text-destructive">*</span>}
                    </Label>
                )}
                <PhoneInput ref={ref} error={hasError} className={className} {...props} />
                {helperText && !errorMessage && <p className="text-sm text-muted-foreground">{helperText}</p>}
                {errorMessage && <p className="text-sm text-destructive">{errorMessage}</p>}
            </div>
        );
    }
);

PhoneInputField.displayName = 'PhoneInputField';

export { PhoneInput, PhoneInputField };