import { type MouseEvent, useRef, useState } from 'react';

import CroppingModal from '@composed-components/CroppingModal';
import { useModal } from '@hooks/useModal';
import { type IconInterface } from '@src/types/icons';

import {
  DEFAULT_CROP_HEIGHT,
  DEFAULT_CROP_WIDTH,
  DEFAULT_MENU_WIDTH,
  DEFAULT_TABS,
} from './constants';
import IconPickerButton from './IconPickerButton';
import IconPickerMenu from './IconPickerMenu';
import { type IconPickerProps } from './types';

const IconPicker = ({
  value,
  onChange,
  imageOptions = [],
  onUpload,
  text,
  tabs = DEFAULT_TABS,
  disabled = false,
  renderIcon,
  sx,
  slotProps,
}: IconPickerProps) => {
  const anchorRef = useRef<HTMLButtonElement | null>(null);
  const [open, setOpen] = useState(false);

  const handleToggle = () => {
    if (!disabled) setOpen(prev => !prev);
  };

  const handleClose = () => setOpen(false);

  const handleSelect = (icon: IconInterface) => {
    onChange(icon);
    handleClose();
  };

  const handleCropSave = (
    file: File,
    _event: MouseEvent<HTMLButtonElement>,
  ) => {
    onUpload?.(file);
  };

  const {
    modal: croppingModal,
    showModal: showCroppingModal,
    closeModal,
  } = useModal(
    CroppingModal,
    { fullWidth: true, maxWidth: 'md', sx: { zIndex: 1600 } },
    {
      onSave: handleCropSave,
      onClose: () => closeModal(),
      recommendedWidth: DEFAULT_CROP_WIDTH,
      recommendedHeight: DEFAULT_CROP_HEIGHT,
      title: text.cropTitle,
      saveLabel: text.cropSave,
      cancelLabel: text.cropCancel,
    },
  );

  const handleFileUpload = (file: File) => {
    showCroppingModal({ file });
  };

  return (
    <>
      {croppingModal}
      <IconPickerButton
        value={value}
        open={open}
        onClick={handleToggle}
        buttonRef={anchorRef}
        disabled={disabled}
        sx={sx}
        renderIcon={renderIcon}
      />
      <IconPickerMenu
        open={open}
        anchorEl={anchorRef.current}
        onClose={handleClose}
        onSelect={handleSelect}
        imageOptions={imageOptions}
        selectedValue={value}
        onUpload={onUpload ? handleFileUpload : undefined}
        width={slotProps?.menu?.width ?? DEFAULT_MENU_WIDTH}
        text={text}
        tabs={tabs}
      />
    </>
  );
};

export default IconPicker;
