import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';

import { TYPE_ERROR } from '@/modules/@common/notify/constants';

import * as selectors from '../../../redux/selectors';
import { getHubOptionsAction, removeErrorByPropAction, setAction } from '../../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import { showNotificationAction } from '@/modules/layout/redux/slices';

import { FormGroupTitle, FormImageUploader, FormRow, useFormSettings } from '@/modules/@common/Form';
import { Autocomplete, Stack, TextField } from '@/mui/components';

const NAME_MAX_LENGTH = 40;
const IMAGE_MAX_SIZE = 1024 * 1024 * 5; // 5 MB
const IMAGE_MIN_WIDTH = 141;
const IMAGE_MIN_HEIGHT = 141;

async function validateImageDimensions(file) {
  return new Promise((resolve) => {
    const img = new Image();
    const reader = new FileReader();

    reader.onload = (e) => {
      img.src = e.target.result;
    };

    img.onload = () => {
      const width = img.naturalWidth;
      const height = img.naturalHeight;
      const isValid = !(width < IMAGE_MIN_WIDTH || height < IMAGE_MIN_HEIGHT);
      resolve(isValid);
    };

    reader.readAsDataURL(file);
  });
}

function GeneralTab() {
  const { size } = useFormSettings();
  const dispatch = useDispatch();
  const router = useRouter();

  // selectors
  const name = useSelector(selectors.nameSelector);
  const hub = useSelector(selectors.hubSelector);
  const hubOptions = useSelector(selectors.hubOptionsSelector);
  const title = useSelector(selectors.titleSelector);
  const image = useSelector(selectors.imageSelector);
  const buttonLabel1 = useSelector(selectors.buttonLabel1Selector);
  const buttonUrl1 = useSelector(selectors.buttonUrl1Selector);
  const buttonLabel2 = useSelector(selectors.buttonLabel2Selector);
  const buttonUrl2 = useSelector(selectors.buttonUrl2Selector);

  const scheme = useSelector(selectors.schemeSelector);

  const id = parseInt(router.query.id, 10);

  // handlers
  const handleSetState = (state) => dispatch(setAction(state));

  return (
    <>
      <FormRow label="Hub">
        <Stack fullWidth>
          <Autocomplete
            fullWidth
            value={hub}
            options={hubOptions || []}
            optionValueKey="id"
            optionLabelKey="name"
            loading={!hubOptions}
            size={size}
            filterSelectedOptions
            disableClearable
            disabled={!!id}
            onChange={(e, selected) => {
              handleSetState({
                hub: selected,
              });
            }}
            onOpen={() => {
              dispatch(getHubOptionsAction(''));
            }}
            onInputChange={(e, searchText) => dispatch(getHubOptionsAction(searchText))}
            renderInput={(params) => (
              <TextField
                {...params}
                value=""
                placeholder="Select Hub"
                {...getInputPropsByName(scheme, ['hub'])}
                onFocus={() => dispatch(removeErrorByPropAction(['hub']))}
              />
            )}
          />
        </Stack>
      </FormRow>

      <FormRow label="Name">
        <TextField
          size={size}
          placeholder="Name"
          value={name}
          inputProps={{ maxLength: NAME_MAX_LENGTH }}
          onChange={(e) => handleSetState({ name: e.target.value })}
          {...getInputPropsByName(scheme, ['name'])}
          onFocus={() => dispatch(removeErrorByPropAction(['name']))}
        />
      </FormRow>

      <FormGroupTitle>Creative Elements</FormGroupTitle>

      <FormRow label="Title">
        <TextField
          size={size}
          placeholder="Title"
          value={title}
          inputProps={{ maxLength: NAME_MAX_LENGTH }}
          onChange={(e) => handleSetState({ title: e.target.value })}
          {...getInputPropsByName(scheme, ['title'])}
          onFocus={() => dispatch(removeErrorByPropAction(['title']))}
        />
      </FormRow>

      <FormRow label="Image">
        <FormImageUploader
          image={image}
          accept=".jpeg, .jpg, .png"
          restrictionMessage="JPEG, PNG. Image is required"
          onValidateAsync={async (file) => {
            const allowedFormats = ['image/jpeg', 'image/jpg', 'image/png'];

            // Check image dimensions
            const isValidDimensions = await validateImageDimensions(file);
            if (!isValidDimensions) {
              dispatch(
                showNotificationAction({
                  key: 'Invalid image dimensions',
                  type: TYPE_ERROR,
                  message: `File has the wrong dimensions. 
                Image dimensions must be at least ${IMAGE_MIN_WIDTH}px by ${IMAGE_MIN_HEIGHT}px`,
                }),
              );
              return false;
            }

            if (!allowedFormats.includes(file.type)) {
              dispatch(
                showNotificationAction({
                  key: 'The file type is not supported',
                  type: TYPE_ERROR,
                  message: 'Invalid image file, the image must be either a PNG or JPG file',
                }),
              );
              return false;
            }

            if (file.size >= IMAGE_MAX_SIZE) {
              dispatch(
                showNotificationAction({
                  key: 'File is too large!',
                  type: TYPE_ERROR,
                  message: 'File is too large! Max size is 5Mb',
                }),
              );
              return false;
            }

            return true;
          }}
          onLoad={(event, file, fileResult) => {
            handleSetState({
              image: fileResult,
            });
          }}
          onError={(event, file, error) => {
            dispatch(
              showNotificationAction({
                key: error,
                type: TYPE_ERROR,
                message: error,
              }),
            );
          }}
          onRemove={() => {
            handleSetState({
              image: '',
            });
          }}
        />
      </FormRow>

      <FormRow label="Button 1 Label">
        <TextField
          size={size}
          placeholder="Button 1 Label"
          value={buttonLabel1}
          inputProps={{ maxLength: NAME_MAX_LENGTH }}
          onChange={(e) => handleSetState({ buttonLabel1: e.target.value })}
          {...getInputPropsByName(scheme, ['buttonLabel1'])}
          onFocus={() => dispatch(removeErrorByPropAction(['buttonLabel1']))}
        />
      </FormRow>

      <FormRow label="Button 1 Click URL">
        <TextField
          size={size}
          placeholder="Button 1 Click URL"
          value={buttonUrl1}
          onChange={(e) => handleSetState({ buttonUrl1: e.target.value })}
          {...getInputPropsByName(scheme, ['buttonUrl1'])}
          onFocus={() => dispatch(removeErrorByPropAction(['buttonUrl1']))}
        />
      </FormRow>

      <FormRow label="Button 2 Label">
        <TextField
          size={size}
          placeholder="Button 2 Label"
          value={buttonLabel2}
          inputProps={{ maxLength: NAME_MAX_LENGTH }}
          onChange={(e) => handleSetState({ buttonLabel2: e.target.value })}
        />
      </FormRow>

      <FormRow label="Button 2 Click URL">
        <TextField
          size={size}
          placeholder="Button 2 Click URL"
          value={buttonUrl2}
          onChange={(e) => handleSetState({ buttonUrl2: e.target.value })}
          {...getInputPropsByName(scheme, ['buttonUrl2'])}
          onFocus={() => dispatch(removeErrorByPropAction(['buttonUrl2']))}
          label=""
        />
      </FormRow>
    </>
  );
}

export default GeneralTab;
