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

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

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

type InputType = {
  key: 'r' | 'g' | 'b' | 'a';
  value: string;
  onChange: (color: string) => void;
  min: number;
  step: number;
  max: number;
};

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

function RgbaInput({ color, disableAlpha, onChange }: Props) {
  const stateColor = colord(color).toRgb();
  const [r, setR] = useState(`${stateColor.r}`);
  const [g, setG] = useState(`${stateColor.g}`);
  const [b, setB] = useState(`${stateColor.b}`);
  const [a, setA] = useState(`${stateColor.a}`);

  useEffect(() => {
    const rgb = colord(color).toRgb();

    setR(`${rgb.r}`);
    setG(`${rgb.g}`);
    setB(`${rgb.b}`);
    setA(`${rgb.a}`);
  }, [color]);

  const inputs: InputType[] = [
    {
      key: 'r',
      value: r,
      onChange: setR,
      min: 0,
      step: 1,
      max: 255,
    },
    {
      key: 'g',
      value: g,
      onChange: setG,
      min: 0,
      step: 1,
      max: 255,
    },
    {
      key: 'b',
      value: b,
      onChange: setB,
      min: 0,
      step: 1,
      max: 255,
    },
  ];

  if (!disableAlpha) {
    inputs.push({
      key: 'a',
      value: a,
      onChange: setA,
      min: 0,
      step: 0.01,
      max: 1,
    });
  }

  return (
    <Stack spacing={1} direction="row" alignItems="flex-start" flex={1}>
      {inputs.map((input) => {
        const onChangeInput = (value: number) => {
          let resValue = value;

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

          input.onChange(`${resValue}`);

          onChange(
            colord({
              ...colord(stateColor).toRgb(),
              [input.key]: resValue,
            }).toRgbString(),
          );
        };

        return (
          <Stack key={input.key} spacing={1} justifyContent="center" flex={1}>
            <TextField
              margin="none"
              textAlign="center"
              type="number"
              size="small"
              shape={SHAPE_ROUNDED}
              inputProps={{
                min: input.min,
                step: input.step,
                max: input.max,
              }}
              value={input.value}
              onChange={(event) => onChangeInput(+event.target.value)}
            />
            <Typography align="center" color="text.primary" variant="caption">
              {input.key.toUpperCase()}
            </Typography>
          </Stack>
        );
      })}
    </Stack>
  );
}

export default RgbaInput;
