import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch } from 'react-redux';
import {
  FormatAlignCenterRounded,
  FormatAlignLeftRounded,
  FormatAlignRightRounded,
  PaletteRounded,
} from '@mui/icons-material';

import { TYPE_ERROR } from '@/modules/@common/notify/constants';
import {
  ALIGN_ITEMS_CENTER,
  ALIGN_ITEMS_LEFT,
  ALIGN_ITEMS_RIGHT,
  ALLOWED_IMAGE_EXT,
  FONTS_OPTIONS,
  MAX_BANNER_SIZE_IN_BYTES,
} from '@/modules/forms/editor/constants';

import { showNotificationAction } from '@/modules/layout/redux/slices';

import { FormGroup, FormRow, FormRowItem, useFormSettings } from '@/modules/@common/Form';
import ColorPicker from './components/ColorPicker';
import UploadImage from './components/UploadImage';
import UploadPictureBanner from './components/UploadPictureBanner';
import {
  Accordion,
  AccordionDetails,
  AccordionSummary,
  MenuItem,
  Select,
  Stack,
  ToggleButton,
  ToggleButtonGroup,
  Typography,
} from '@/mui/components';

function StylesSettings({ disabled = false, ...props }) {
  const { size } = useFormSettings();
  const dispatch = useDispatch();

  const [open, setOpen] = useState(true);
  const [file, setFile] = useState('');
  const [isOpenUploadImageBanner, setIsOpenUploadImageBanner] = useState(false);
  const [LOGO, BANNER] = props.image;

  const preUploadImage = (fileImage) => {
    const fileExt = fileImage.name.split('.').pop();
    const fileSize = fileImage.size;
    const fileName = fileImage.name;

    setIsOpenUploadImageBanner(false);

    if (!ALLOWED_IMAGE_EXT.includes(fileExt.toLowerCase())) {
      dispatch(
        showNotificationAction({
          type: TYPE_ERROR,
          message: `Invalid file extension, valid only (${ALLOWED_IMAGE_EXT.join(',')})`,
        }),
      );
    } else if (fileSize > MAX_BANNER_SIZE_IN_BYTES) {
      dispatch(
        showNotificationAction({
          type: TYPE_ERROR,
          message: 'File size exceeded the maximum size permitted.',
        }),
      );
    } else {
      const reader = new FileReader();

      reader.addEventListener('load', () => {
        props.uploadBanner({ image: props.image, file: reader.result, fileName });
      });

      reader.readAsDataURL(fileImage);
    }
  };

  useEffect(() => {
    if (file) {
      fetch(file.src)
        .then((res) => res.blob())
        .then((blob) => {
          const fileData = new File([blob], file.src, {
            type: blob.type,
          });
          preUploadImage(fileData);
        });
    }
  }, [file]);

  const handleBannerUploadChange = ({ target }) => {
    preUploadImage(target.files[0]);
  };

  const handleBannerDelete = () => {
    props.setField({
      image: [LOGO, null],
    });
  };

  return (
    <FormRow fullWidth>
      <Accordion expanded={open} onChange={(_, expanded) => setOpen(expanded)}>
        <AccordionSummary>
          <Stack direction="row" flexWrap="wrap" spacing={1} alignItems="center">
            <PaletteRounded fontSize={size} htmlColor="info" />
            <Typography variant="body2" color="text.primary" fontWeight={400}>
              Form Styles
            </Typography>
          </Stack>
        </AccordionSummary>
        <AccordionDetails>
          <FormGroup component="div" elevation={0}>
            <FormRow label="Background" fullWidth>
              <ColorPicker
                disabled={disabled}
                color={props.style.bgColor}
                onChange={(hex) => props.onChange({ bgColor: hex })}
              />
            </FormRow>
            <FormRow label="Alignment">
              <ToggleButtonGroup
                equalWidth
                size={size}
                color="primary"
                variant="outlined"
                shape="rounded"
                disabled={disabled}
                value={props.style.alignItems}
              >
                {[
                  {
                    id: ALIGN_ITEMS_LEFT,
                    Icon: FormatAlignLeftRounded,
                  },
                  {
                    id: ALIGN_ITEMS_CENTER,
                    Icon: FormatAlignCenterRounded,
                  },
                  {
                    id: ALIGN_ITEMS_RIGHT,
                    Icon: FormatAlignRightRounded,
                  },
                ].map(({ id, Icon }) => (
                  <ToggleButton
                    key={id}
                    value={id}
                    onClick={() =>
                      props.onChange({
                        alignItems: id,
                      })
                    }
                  >
                    <Icon />
                  </ToggleButton>
                ))}
              </ToggleButtonGroup>
            </FormRow>
            <FormRow label="Label Font">
              <Select
                size={size}
                value={props.style.fontFamily}
                disabled={disabled}
                onChange={({ target }) => props.onChange({ fontFamily: target.value })}
              >
                {FONTS_OPTIONS.map((item) => (
                  <MenuItem value={item.value} key={item.value}>
                    {item.label}
                  </MenuItem>
                ))}
              </Select>
              <FormRowItem itemsInRow={4}>
                <Select
                  size={size}
                  value={props.style.fontSize}
                  disabled={disabled}
                  onChange={({ target }) => props.onChange({ fontSize: target.value })}
                >
                  {new Array(23).fill(null).map((v, i) => {
                    const value = i + 10;
                    return (
                      <MenuItem value={value} key={value}>
                        {value}
                      </MenuItem>
                    );
                  })}
                </Select>
              </FormRowItem>
              <Stack>
                <ColorPicker
                  color={props.style.fontColor}
                  onChange={(hex) => props.onChange({ fontColor: hex })}
                  hideLabel
                  disabled={disabled}
                />
              </Stack>
            </FormRow>
            <FormRow label="Button Color">
              <ColorPicker
                color={props.style.submitButtonBgColor}
                onChange={(hex) => props.onChange({ submitButtonBgColor: hex })}
                title="Background"
                disabled={disabled}
              />
              <ColorPicker
                color={props.style.submitButtonFontColor}
                onChange={(hex) => props.onChange({ submitButtonFontColor: hex })}
                title="Font"
                disabled={disabled}
              />
            </FormRow>
            <FormRow
              label="Banner Image"
              tooltip={
                <>
                  Image types: {ALLOWED_IMAGE_EXT.map((item) => item.toUpperCase()).join(', ')}
                  <br />
                  Maximum file size: {`${MAX_BANNER_SIZE_IN_BYTES / 1024}kb.`}
                  <br />
                  <br />
                  Recommended resolution:
                  <br />
                  1280px X 80px
                </>
              }
            >
              <UploadImage
                image={BANNER || ''}
                accept={ALLOWED_IMAGE_EXT}
                size={MAX_BANNER_SIZE_IN_BYTES / 1024}
                fileUpload={false}
                uploadLogoTerm={false}
                onClick={() => setIsOpenUploadImageBanner(true)}
                onChange={handleBannerUploadChange}
                onDelete={handleBannerDelete}
                disabled={!!disabled}
              />
            </FormRow>
          </FormGroup>
        </AccordionDetails>
      </Accordion>
      <div>
        <UploadPictureBanner
          accept={ALLOWED_IMAGE_EXT}
          isOpen={isOpenUploadImageBanner}
          onChange={handleBannerUploadChange}
          onChoose={setFile}
          onClose={() => setIsOpenUploadImageBanner(false)}
          disabled={!!disabled}
        />
      </div>
    </FormRow>
  );
}

StylesSettings.propTypes = {
  image: PropTypes.arrayOf(PropTypes.string).isRequired,
  style: PropTypes.shape({
    bgColor: PropTypes.string.isRequired,
    alignItems: PropTypes.string.isRequired,
    fontFamily: PropTypes.string.isRequired,
    fontSize: PropTypes.number.isRequired,
    fontColor: PropTypes.string.isRequired,
    submitButtonBgColor: PropTypes.string.isRequired,
    submitButtonFontColor: PropTypes.string.isRequired,
  }).isRequired,
  onChange: PropTypes.func.isRequired,
  setField: PropTypes.func.isRequired,
  uploadBanner: PropTypes.func.isRequired,
  disabled: PropTypes.bool,
};

export default StylesSettings;
