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

import { FormControl, Stack, Typography, useTheme } from '@mui/material';

import { getCurrentLocale } from '../../../../utils/languages';
import CustomHelperText from '../Base/CustomHelperText';
import CustomInput from '../Base/CustomInput';
import CustomLabel from '../Base/CustomLabel';
import CustomSelect from '../Base/CustomSelect';

import { type InputMoneyProps } from './types';
import { defaultTransform, getCurrencyOptions } from './utils';

const InputMoney = ({
  transform = defaultTransform(getCurrentLocale()),
  onChange,
  value,
  currencyOptions = getCurrencyOptions(),
  label,
  success,
  error,
  errorText,
  helperText,
  disabled,
  sx = {},
  fullWidth = true,
  defaultCurrencySymbol = '$',
  preventDecimals = false,
  selectCoin = true,
  ...inputProps
}: InputMoneyProps) => {
  const theme = useTheme();
  const containerRef = useRef<HTMLDivElement>(null);
  const [menuWidth, setMenuWidth] = useState<number>(350);

  useLayoutEffect(() => {
    if (containerRef.current) {
      const { width } = containerRef.current.getBoundingClientRect();
      setMenuWidth(width);
    }
  }, []);

  const findCurrencyOption = (optionValue?: string) => {
    return currencyOptions.find(opt => opt.value === optionValue);
  };

  return (
    <>
      <Stack>
        <CustomLabel label={label} />
      </Stack>

      <Stack
        ref={containerRef}
        sx={{
          flexDirection: 'row',
          alignItems: 'center',
          gap: theme.spacing(0.5),
          position: 'relative',
        }}
      >
        {selectCoin && (
          <Stack sx={{ width: '95px', minWidth: '95px' }}>
            <FormControl
              sx={sx}
              error={error}
              fullWidth={fullWidth}
              disabled={disabled}
            >
              <CustomSelect
                value={value.currencyCode ?? '-'}
                options={currencyOptions}
                onChange={newCurrency => {
                  onChange({ currencyCode: newCurrency, amount: value.amount });
                }}
                hideErrorAdornment
                disabled={disabled}
                success={success}
                MenuProps={{
                  PaperProps: {
                    sx: {
                      width: `${menuWidth}px`,
                      mt: theme.spacing(0.5),
                      maxHeight: '400px',
                    },
                  },
                  anchorOrigin: {
                    vertical: 'bottom',
                    horizontal: 'left',
                  },
                  transformOrigin: {
                    vertical: 'top',
                    horizontal: 'left',
                  },
                }}
                renderValue={option =>
                  findCurrencyOption(option.value.toString())?.value ||
                  option.value
                }
                renderOption={option => {
                  const currencyOption = findCurrencyOption(
                    option.value.toString(),
                  );

                  return (
                    <Stack
                      direction="row"
                      justifyContent="space-between"
                      width="100%"
                      p={theme.spacing(2)}
                    >
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                        color={theme.palette.new.text.neutral.default}
                      >
                        {option.label}
                      </Typography>
                      <Typography
                        variant="globalS"
                        color={theme.palette.new.text.neutral.default}
                      >
                        {currencyOption?.value || option.value}
                      </Typography>
                    </Stack>
                  );
                }}
              />
            </FormControl>
          </Stack>
        )}

        <FormControl
          sx={sx}
          error={error}
          fullWidth={fullWidth}
          disabled={disabled}
        >
          <CustomInput
            {...inputProps}
            value={transform.output(value.amount, preventDecimals)}
            onChange={newValue => {
              onChange({
                currencyCode: value.currencyCode,
                amount: transform.input(newValue, preventDecimals),
              });
            }}
            success={success}
            disabled={disabled}
            startAdornment={
              <Typography
                fontWeight="fontWeightSemiBold"
                sx={{
                  mr: 1,
                }}
              >
                {findCurrencyOption(value.currencyCode)?.symbol ??
                  defaultCurrencySymbol}
              </Typography>
            }
          />
        </FormControl>
      </Stack>
      <CustomHelperText
        helperText={error ? errorText : helperText}
        value={value.amount}
        success={success}
        error={error}
      />
    </>
  );
};

export type { InputMoneyProps };

export default InputMoney;
