import { useEffect, useRef, useState } from 'react';

import { Stack, useTheme } from '@mui/material';
import {
  IconAlertCircle,
  IconCheck,
  IconChevronDown,
  IconX,
} from '@tabler/icons-react';
import { MuiTelInput } from 'mui-tel-input';

import CustomLabel from '../Base/CustomLabel';

import { type InputPhoneProps } from './types';

const InputPhone = (props: InputPhoneProps) => {
  const {
    label,
    onChange,
    value,
    success,
    fullWidth = true,
    disabled = false,
    sx = {},
    defaultCountry = 'AR',
    preferredCountries = ['AR', 'MX'],
    helperText,
    ...telInputProps
  } = props;

  const theme = useTheme();

  // Resolve helperText if it's a function (Phone component doesn't support function helperText,
  // but we need to handle it for type compatibility)
  const resolvedHelperText =
    typeof helperText === 'function' ? undefined : helperText;

  // We keep an internal display value for MuiTelInput. The parent only ever sees the
  // "logical" value (empty string when no national number has been typed) so that
  // form validators like `required` keep working. But MuiTelInput needs to see the
  // calling code (e.g. "+52") to preserve the user's country selection across renders;
  // otherwise its internal effect re-parses an empty value and snaps the country back
  // to `defaultCountry`.
  const [internalValue, setInternalValue] = useState<string>(value ?? '');
  const lastReportedValue = useRef<string>(value ?? '');

  useEffect(() => {
    const next = value ?? '';
    if (next !== lastReportedValue.current) {
      setInternalValue(next);
      lastReportedValue.current = next;
    }
  }, [value]);

  const handleChange = (newValue: string, country: any) => {
    setInternalValue(newValue);
    const reportedValue = country.nationalNumber ? newValue : '';
    lastReportedValue.current = reportedValue;
    onChange?.(reportedValue, country?.countryCallingCode);
  };

  const reset = () => handleChange('', {});

  const valuesStrategies = {
    error: {
      phoneInputIcon: {
        display: 'flex',
        color: theme.palette.new.text.feedback.error,
        clickable: false,
        icon: <IconAlertCircle size={20} />,
      },
      border: theme.palette.new.border.states.error,
      focusedBorder: theme.palette.new.border.states.error,
      helperText: {
        color: theme.palette.new.text.feedback.error,
        icon: <IconAlertCircle size={16} />,
        marginLeft: 2.5,
      },
      label: {
        color: theme.palette.new.text.feedback.error,
      },
    },
    success: {
      phoneInputIcon: {
        display: 'flex',
        color: theme.palette.new.text.feedback.success,
        clickable: false,
        icon: <IconCheck size={20} />,
      },
      border: theme.palette.new.border.states.success,
      focusedBorder: theme.palette.new.border.states.success,
      helperText: {
        color: theme.palette.new.text.feedback.success,
        icon: <IconCheck size={16} />,
        marginLeft: 2.5,
      },
      label: {
        color: theme.palette.new.text.feedback.success,
      },
    },
    default: {
      phoneInputIcon: {
        display: value && !disabled ? 'flex' : 'none',
        color: theme.palette.new.text.neutral.default,
        clickable: !disabled,
        icon: (
          <Stack sx={{ mr: 2 }}>
            <IconX
              onClick={reset}
              size={20}
            />
          </Stack>
        ),
      },
      border: theme.palette.new.border.neutral.default,
      focusedBorder: theme.palette.new.border.neutral.brand,
      helperText: {
        color: theme.palette.new.text.neutral.lighter,
        icon: null,
        marginLeft: 0,
      },
      label: {
        color: theme.palette.new.text.neutral.default,
      },
    },
  };

  const uiValues =
    (telInputProps.error && valuesStrategies.error) ||
    (success && valuesStrategies.success) ||
    valuesStrategies.default;

  const countryCodeIcon = (
    <Stack
      sx={{
        left: 62,
        pointerEvents: 'none',
        position: 'absolute',
        top: 16,
        zIndex: 1,
        color: theme.palette.new.text.neutral.default,
      }}
    >
      <IconChevronDown size={24} />
    </Stack>
  );

  const phoneInputIcon = (
    <Stack
      sx={{
        display: uiValues.phoneInputIcon.display,
        position: 'absolute',
        top: 16,
        right: 8,
        width: 24,
        height: 24,
        alignItems: 'center',
        justifyContent: 'center',
        zIndex: 1,
        color: uiValues.phoneInputIcon.color,
        cursor: uiValues.phoneInputIcon.clickable ? 'pointer' : 'inherit',
      }}
    >
      {uiValues.phoneInputIcon.icon}
    </Stack>
  );

  const helperTextIcon = uiValues.helperText.icon && (
    <Stack
      sx={{
        display: resolvedHelperText ? 'flex' : 'none',
        position: 'absolute',
        bottom: 6,
        left: 0,
        width: 16,
        height: 16,
        alignItems: 'center',
        justifyContent: 'center',
        zIndex: 1,
        color: uiValues.helperText.color,
        cursor: 'inherit',
      }}
    >
      {uiValues.helperText.icon}
    </Stack>
  );

  return (
    <Stack>
      {label && (
        <Stack
          sx={{
            '& .MuiTypography-root': {
              color: uiValues.label.color,
            },
          }}
        >
          <CustomLabel
            label={label}
            success={success}
          />
        </Stack>
      )}
      <Stack sx={{ position: 'relative' }}>
        {countryCodeIcon}
        {phoneInputIcon}
        {helperTextIcon}
        <MuiTelInput
          {...telInputProps}
          value={internalValue}
          helperText={resolvedHelperText}
          onChange={handleChange}
          defaultCountry={defaultCountry}
          preferredCountries={preferredCountries}
          disabled={disabled}
          fullWidth={fullWidth}
          forceCallingCode
          MenuProps={{
            PaperProps: {
              sx: {
                maxHeight: '360px !important',
                '& .MuiList-root': {
                  padding: '0px !important',
                },
                '& .MuiMenuItem-root': {
                  minHeight: '72px',
                },
                '& .MuiListItemText-root .MuiTypography-root': {
                  ml: 1,
                  fontSize: '16px',
                  fontWeight: 500,
                },
                '& .MuiButtonBase-root .MuiTelInput-Typography-calling-code': {
                  fontSize: '16px',
                  fontWeight: 400,
                  color: theme.palette.new.text.neutral.default,
                },
                '& .MuiMenuItem-root .MuiTelInput-Flag': {
                  width: '100%',
                  height: '24px',
                  borderRadius: '4px',
                },
              },
            },
          }}
          sx={{
            ...sx,
            '&.MuiFormControl-root > div': {
              p: 0,
              '& fieldset': {
                '&,&:focus-visible,&:hover': {
                  border: 'none',
                  outline: 'none',
                },
              },
              '.MuiTelInput-IconButton': {
                boxSizing: 'border-box',
                p: 1,
                pr: '36px',
                minHeight: '56px',
                minWidth: '100px',
                backgroundColor: theme.palette.new.background.elements.default,
                '& .MuiTelInput-Flag': {
                  width: 36,
                  height: 24,
                },
              },

              // phone input
              '& input': {
                p: 1.2,
                ml: -0.5,
                fontSize: 16,
                fontWeight: 300,
                color: theme.palette.new.text.neutral.default,
                backgroundColor: theme.palette.new.background.elements.default,
                pr: 4,
                minHeight: '56px',
                boxSizing: 'border-box',
              },

              // country + phone inputs
              '.MuiInputAdornment-root .MuiTelInput-IconButton, & input': {
                '&.Mui-disabled': {
                  backgroundColor: disabled
                    ? theme.palette.new.background.elements.disabled
                    : theme.palette.new.background.elements.default,
                },
                '&:focus-visible,&[aria-expanded="true"]': {
                  borderColor: uiValues.focusedBorder,
                  boxShadow: 'none',
                },
                border: '1px solid',
                borderColor: uiValues.border,
                borderRadius: 1,
              },
            },

            '& .MuiFormHelperText-root': {
              marginLeft: uiValues.helperText.marginLeft,
              color: `${uiValues.helperText.color} !important`,
              fontColor: `${uiValues.helperText.color} !important`,
              fontWeight: 400,
              fontSize: '16px',
            },
          }}
        />
      </Stack>
    </Stack>
  );
};

export type { InputPhoneProps };

export default InputPhone;
