import React, { ComponentProps, CSSProperties, useEffect, useState } from 'react';
import classNames from 'clsx';
import dayjs from 'dayjs';
import type { InputBaseComponentProps, TypographyVariant } from '@mui/material';
import { AccessTimeRounded } from '@mui/icons-material';

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

import { getInputStyleCssVariables, useInputStyles } from '../helpers';
import { useInputWidth } from './helpers';

import IconButton from '../../../IconButton/IconButton';
import InputAdornment from '../../../InputAdornment/InputAdornment';
import TimePicker from '../../../TimePicker/TimePicker';

import styles from './DateTimePicker.module.scss';

type Props = ComponentProps<typeof TimePicker> & {
  variant?: TypographyVariant;
  format?: string;
  fontWeight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
  editable?: boolean;
  readOnly?: boolean;
};

function InlineEditTimePicker({
  variant = 'body2',
  format = 'hh:mm A',
  fontWeight: initialFontWeight,
  editable: initialEditable,
  readOnly: initialReadOnly,
  disabled,
  value,
  onChange,
  ...props
}: Props) {
  const canBeEdit = !disabled && !initialReadOnly;
  const [stateValue, setValue] = useState(value);
  const [editable, setEditState] = useState(!!initialEditable && canBeEdit);

  useEffect(() => setValue(value), [value]);

  useEffect(() => setEditState(!!initialEditable && canBeEdit), [initialEditable, canBeEdit]);

  const { fontSize, fontWeight, lineHeight, letterSpacing } = useInputStyles(variant, initialFontWeight);

  const inputWidth = useInputWidth(
    stateValue ? dayjs(stateValue).format(format) : format,
    fontSize,
    fontWeight as number,
  );

  const inputProps: InputBaseComponentProps = {
    placeholder: format,
    readOnly: !value || initialReadOnly,
  };

  if (!value) {
    inputProps.value = '';
  }

  return (
    <TimePicker
      {...props}
      disabled={disabled}
      open={editable}
      value={stateValue}
      format={format}
      readOnly={!canBeEdit}
      onChange={(value$, context) => {
        setValue(value$);

        if (onChange) {
          onChange(value$, context);
        }
      }}
      onClose={() => {
        setEditState(false);
      }}
      slotProps={{
        textField: {
          variant: 'filled',
          size: SIZE_MEDIUM,
          fullWidth: false,
          classes: {
            root: styles.TextFieldWrapper,
          },
          style: {
            ...getInputStyleCssVariables(fontSize, fontWeight, lineHeight, letterSpacing),
            '--internal-input-width': inputWidth,
          } as CSSProperties,
          InputProps: {
            onClick: () => {
              if (canBeEdit) {
                setEditState(true);
              }
            },
            classes: {
              root: classNames(styles.InputRoot, {
                [styles.InputRoot___readOnly]: !canBeEdit,
                [styles.InputRoot___view]: !editable,
              }),
              input: styles.Input,
            },
            startAdornment: (
              <InputAdornment position="start" className={styles.InputAdornment}>
                <IconButton
                  size="small"
                  disableRipple={!canBeEdit}
                  disableFocusRipple={!canBeEdit}
                  className={classNames(styles.IconWrapper, {
                    [styles.IconWrapper___readOnly]: !canBeEdit,
                  })}
                >
                  <AccessTimeRounded fontSize="small" />
                </IconButton>
              </InputAdornment>
            ),
            endAdornment: (
              // eslint-disable-next-line react/jsx-no-useless-fragment
              <></>
            ),
          },
          inputProps,
        },
      }}
    />
  );
}

export default InlineEditTimePicker;
