import type { Token } from '@lifi/sdk';
import type { CardProps } from '@mui/material';
import type { ChangeEvent, ReactNode } from 'react';
import { useCallback, useEffect, useLayoutEffect, useRef } from 'react';
import { useToken } from '../../hooks/useToken.js';
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
import { FormKeyHelper, type FormTypeProps } from '../../stores/form/types.js';
import { useFieldController } from '../../stores/form/useFieldController.js';
import { useFieldValues } from '../../stores/form/useFieldValues.js';
import { DisabledUI } from '../../types/widget.js';
import { formatInputAmount, formatTokenAmount } from '../../utils/format.js';
import { fitInputText } from '../../utils/input.js';
import { CardTitle } from '../Card/CardTitle.js';
import { InputCard } from '../Card/InputCard.js';
import {
  FormContainer,
  FormControl,
  Input,
  maxInputFontSize,
  minInputFontSize,
} from '../AmountInput/AmountInput.style.js';
import { AmountInputEndAdornment } from '../AmountInput/AmountInputEndAdornment.js';
// import { AmountInputStartAdornment } from './AmountInputStartAdornment.js';
import { PriceFormHelperTextCustom } from './PriceFormHelperTextCustom.js';
import { AmountInputCustom } from '../AmountInputCustom/AmountInputCustom.js';
import { useRoutes } from '../../hooks/useRoutes.js';
import { getProgressValue } from '../ProgressToNextUpdate.js';

export const AmountInput: React.FC<FormTypeProps & CardProps> = ({
  formType,
  ...props
}) => {
  const { routes } = useRoutes();
  const currentRoute = routes?.[0];

  const { disabledUI } = useWidgetConfig();

  const [chainId, tokenAddress] = useFieldValues(
    FormKeyHelper.getChainKey(formType),
    FormKeyHelper.getTokenKey(formType),
  );

  const { token } = useToken(chainId, tokenAddress);
  const disabled =
    disabledUI?.includes(DisabledUI.FromAmount) || formType === 'to';

  return (
    <AmountInputBase
      formType={formType}
      token={token as any}
      endAdornment={
        !disabled ? <AmountInputEndAdornment formType={formType} /> : undefined
      }
      bottomAdornment={
        <PriceFormHelperTextCustom formType={formType} route={currentRoute} />
      }
      route={currentRoute}
      disabled={disabled}
      {...props}
    />
  );
};

export const AmountInputBase: React.FC<
  FormTypeProps &
    CardProps & {
      token?: Token;
      startAdornment?: ReactNode;
      endAdornment?: ReactNode;
      bottomAdornment?: ReactNode;
      disabled?: boolean;
      route?: any;
    }
> = ({
  formType,
  token,
  startAdornment,
  endAdornment,
  bottomAdornment,
  disabled,
  route,
  ...props
}) => {
  const ref = useRef<HTMLInputElement>(null);
  const amountKey = FormKeyHelper.getAmountKey(formType);
  const { onChange, onBlur, value } = useFieldController({ name: amountKey });
  const { refetchTime, dataUpdatedAt, refetch } = useRoutes();
  const [fromAmount] = useFieldValues('fromAmount');
  const hasRefetched = useRef(false);

  const handleRefetch = useCallback(() => {
    const timeCountDown = getProgressValue(
      dataUpdatedAt || new Date().getTime(),
      refetchTime,
    );

    if (timeCountDown > 0) {
      refetch();
      hasRefetched.current = true;
    }
  }, [dataUpdatedAt, refetchTime, refetch]);

  useEffect(() => {
    if (fromAmount && !hasRefetched.current) {
      hasRefetched.current = false;
      handleRefetch();
    }
  }, [fromAmount, handleRefetch]);

  const handleChange = (
    event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    const { value } = event.target;
    const formattedAmount = formatInputAmount(value, token?.decimals, true);
    onChange(formattedAmount);
  };

  const handleBlur = (
    event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    const { value } = event.target;
    const formattedAmount = formatInputAmount(value, token?.decimals);
    onChange(formattedAmount);
    onBlur();
  };

  useLayoutEffect(() => {
    if (ref.current) {
      fitInputText(maxInputFontSize, minInputFontSize, ref.current);
    }
  }, [value, ref]);

  const { subvariant } = useWidgetConfig();

  const routeToken =
    subvariant === 'custom'
      ? { ...route?.fromToken, amount: BigInt(route?.fromAmount || 0) }
      : { ...route?.toToken, amount: BigInt(route?.toAmount || 0) };

  const tokenAmount = formatTokenAmount(routeToken.amount, routeToken.decimals);

  return (
    <InputCard {...props}>
      <CardTitle>{formType === 'from' ? 'You pay' : 'You receive'}</CardTitle>
      <FormContainer>
        <FormControl fullWidth>
          <Input
            inputRef={ref}
            size="small"
            autoComplete="off"
            placeholder="0"
            startAdornment={startAdornment}
            endAdornment={endAdornment}
            inputProps={{
              inputMode: 'decimal',
            }}
            onChange={handleChange}
            onBlur={handleBlur}
            value={formType === 'from' ? value : tokenAmount}
            autoFocus={formType === 'from'}
            name={amountKey}
            disabled={disabled}
            required
          />
          {bottomAdornment}
        </FormControl>
        <AmountInputCustom formType={formType} />
      </FormContainer>
    </InputCard>
  );
};
