import React, { useEffect, useState } from 'react';
import { colord } from 'colord';

import { SHAPE_ROUNDED } from '@/mui/constants';

import { toHex } from '../../helpers';

import Stack from '../../../../Stack/Stack';
import TextField from '../../../../TextField/TextField';
import Typography from '../../../../Typography/Typography';

const presetColor = (color: string, disableAlpha: boolean) => {
  const resColor = colord(color).toRgb();

  return {
    ...resColor,
    a: !disableAlpha ? resColor.a : 1,
  };
};

const alphaToPercentages = (n: number) => (n * 1000) / 10;
const min = 0;
const max = 100;

type Props = {
  color: string;
  disableAlpha: boolean;
  onChange: (color: string) => void;
};

function HexInput({ color, disableAlpha, onChange }: Props) {
  const [stateColor, setColor] = useState(toHex(color, disableAlpha));
  const [colorValue, setColorValue] = useState(toHex(color, true));
  const [alphaValue, setAlphaValue] = useState(alphaToPercentages(colord(color).toRgb().a));

  useEffect(() => {
    const nextColor = toHex(color, disableAlpha);

    setColor(nextColor);

    setColorValue(toHex(color, true));
    setAlphaValue(alphaToPercentages(colord(color).toRgb().a));
  }, [color]);

  const onApply = (value: string) => {
    let newColor = colord(value);

    if (newColor.isValid()) {
      newColor = colord({
        ...newColor.toRgb(),
        a: alphaValue,
      });
    } else {
      newColor = colord(color);
    }

    const hex = newColor.toHex();

    setColor(hex);
    onChange(hex);
    setColorValue(colord(presetColor(color, true)).toHex());
  };

  return (
    <Stack spacing={1} flex={1}>
      <Stack spacing={2} direction="row" alignItems="center" flex={1}>
        <Stack spacing={1} flex={1}>
          <TextField
            value={colorValue}
            size="small"
            margin="none"
            textAlign="center"
            shape={SHAPE_ROUNDED}
            onBlur={(event) => onApply(event.target.value)}
            onChange={(event) => {
              setColorValue(event.target.value);
            }}
            onKeyUp={(event) => {
              if (event.key === 'Enter') {
                onApply(colorValue);
              }
            }}
          />
          <Typography align="center" color="text.primary" variant="caption">
            HEX
          </Typography>
        </Stack>
        {!disableAlpha && (
          <Stack spacing={1} flex={0.3}>
            <TextField
              type="number"
              size="small"
              shape={SHAPE_ROUNDED}
              margin="none"
              textAlign="center"
              inputProps={{
                min,
                step: 1,
                max,
              }}
              value={alphaValue}
              onChange={(event) => {
                let parsedValue = +event.target.value;

                if (Number.isNaN(parsedValue) || parsedValue < min) {
                  parsedValue = min;
                } else if (parsedValue > max) {
                  parsedValue = max;
                }

                setAlphaValue(parsedValue);

                const newColor = colord(stateColor).toRgb();
                newColor.a = parsedValue / max;

                setColor(colord(newColor).toHex());
                onChange(colord(newColor).toHex());
              }}
            />
            <Typography align="center" color="text.primary" variant="caption">
              %
            </Typography>
          </Stack>
        )}
      </Stack>
    </Stack>
  );
}

export default HexInput;
