import { useEffect, useRef, useCallback } from 'react';
import { Box, InputBase, InputAdornment, Typography } from '@mui/material';
import { defaultCountries, usePhoneInput } from 'react-international-phone';
import { useMount } from 'ahooks';

import CountrySelect from './country-select';
import { isValidCountry } from '../libs/util';
import { getPhoneUtil } from '../libs/phone-validator';

export interface PhoneFieldProps {
  value: string;
  country: string;
  onChange: (phone: string) => void;
  onCountryChange: (country: string) => void;
  label: string;
  error?: string;
  onBlur?: () => void;
}

/**
 * Phone input with country flag + dial code selector.
 * Standalone version of V1 PhoneInput — no react-hook-form dependency.
 */
export default function PhoneField({
  value,
  country: externalCountry,
  onChange,
  onCountryChange,
  label,
  error = undefined,
  onBlur = undefined,
}: PhoneFieldProps) {
  const isUpdatingRef = useRef(false);

  const safeUpdate = useCallback((callback: () => void) => {
    if (isUpdatingRef.current) return;
    try {
      isUpdatingRef.current = true;
      callback();
    } finally {
      requestAnimationFrame(() => {
        isUpdatingRef.current = false;
      });
    }
  }, []);

  const { phone, handlePhoneValueChange, inputRef, country, setCountry } = usePhoneInput({
    defaultCountry: isValidCountry(externalCountry) ? externalCountry : 'us',
    value: value || '',
    countries: defaultCountries,
    onChange: (data) => {
      safeUpdate(() => {
        onChange(data.phone);
        onCountryChange(data.country);
      });
    },
  });

  // Preload phone validator (matches V1 behavior)
  useMount(() => {
    getPhoneUtil().catch((err) => {
      console.error('Failed to preload phone validator:', err);
    });
  });

  // Sync external country changes (e.g. from postal code CountrySelect)
  useEffect(() => {
    if (!externalCountry || externalCountry === country) return;
    safeUpdate(() => {
      setCountry(externalCountry);
    });
  }, [externalCountry, country, setCountry, safeUpdate]);

  const handleCountryChange = useCallback(
    (v: string) => {
      safeUpdate(() => {
        setCountry(v);
        onCountryChange(v);
      });
    },
    [setCountry, safeUpdate, onCountryChange]
  );

  return (
    <Box sx={{ mb: 1.5 }}>
      <Typography sx={{ fontSize: 13, fontWeight: 600, color: 'text.primary', mb: 0.5 }}>{label}</Typography>
      <InputBase
        fullWidth
        value={phone}
        onChange={handlePhoneValueChange}
        onBlur={onBlur}
        type="tel"
        inputRef={inputRef}
        startAdornment={
          <InputAdornment position="start" sx={{ mr: 0.25, ml: -0.5 }}>
            <CountrySelect
              value={country}
              onChange={handleCountryChange}
              sx={{
                '.MuiOutlinedInput-notchedOutline': { borderColor: 'transparent !important' },
                '& .MuiSelect-select': { py: 0, pr: '20px !important' },
              }}
              showDialCode
            />
          </InputAdornment>
        }
        sx={{
          bgcolor: (theme) => (theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.06)' : 'grey.50'),
          borderRadius: '8px',
          px: 1.5,
          py: 0.75,
          fontSize: 14,
          '& .MuiInputBase-input': { p: 0 },
        }}
      />
      {error && <Typography sx={{ fontSize: 12, color: 'error.main', mt: 0.25 }}>{error}</Typography>}
    </Box>
  );
}
