import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';
import { ContentCopyRounded } from '@mui/icons-material';

import { POST_FORM_TEMPLATES, PUT_FORM_TEMPLATES } from '@/modules/@common/acl/constants';
import { TYPE_ERROR } from '@/modules/@common/notify/constants';
import {
  FORM_PREVIEW_WIDGET_ID,
  FORM_SUBMIT_MODE_CREATE,
  FORM_SUBMIT_MODE_DUPLICATE,
  FORM_SUBMIT_MODE_UPDATE,
} from '@/modules/forms/constants';
import {
  ALLOWED_IMAGE_EXT,
  FIELD_MAX_LENGTH_DESCRIPTION,
  FIELD_MAX_LENGTH_NAME,
  FIELD_MAX_LENGTH_PPTEXT,
  FIELD_MAX_LENGTH_SKIPBUTTONTEXT,
  FIELD_MAX_LENGTH_SUBMITTEXT,
  FIELD_MAX_LENGTH_TCTEXT,
  FIELD_MAX_LENGTH_TITLE,
  MAX_LOGO_SIZE_IN_BYTES,
} from '@/modules/forms/editor/constants';

import { getFormMetadataCalculation } from '../../helpers/calculationsFromState';
import * as selectors from '../../redux/selectors';
import {
  getAccountOptionsAction,
  getCategoryOptionsAction,
  removeErrorByPropAction,
  setFieldAction,
  uploadBannerAction,
  uploadLogoAction,
} from '../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import copyToClipboard from '@/modules/@common/helpers/copy';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserAccountIdSelector, getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';
import useFormSubmitMode from '@/modules/forms/helpers/useFormSubmitMode';
import { showNotificationAction } from '@/modules/layout/redux/slices';

import {
  FormGroup,
  FormImageUploader,
  FormRow,
  FormRowItem,
  FormSection,
  useFormSettings,
} from '@/modules/@common/Form';
import FormPreview from '@/modules/forms/common/components/FormPreview';
import RichEditor from '@/modules/forms/common/components/RichEditor/RichEditor';
import DynamicFields from '../../../common/components/DynamicFields';
import StylesSettings from '../../../common/components/StylesSettings';
import { Autocomplete, Chip, IconButton, InputAdornment, MenuItem, Select, Switch, TextField } from '@/mui/components';

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

function DetailsTab() {
  const { size } = useFormSettings();
  const dispatch = useDispatch();
  const router = useRouter();
  const formSubmitMode = useFormSubmitMode(router);
  const id = useSelector(selectors.idSelector);
  const name = useSelector(selectors.nameSelector);
  const account = useSelector(selectors.accountSelector);
  const category = useSelector(selectors.categorySelector);
  const categoryOptions = useSelector(selectors.categoryOptionsSelector);
  const image = useSelector(selectors.imageSelector);
  const title = useSelector(selectors.titleSelector);
  const description = useSelector(selectors.descriptionSelector);
  const submitButton = useSelector(selectors.submitButtonSelector);
  const privacyPolicy = useSelector(selectors.privacyPolicySelector);
  const termsConditions = useSelector(selectors.termsConditionsSelector);
  const skipButton = useSelector(selectors.skipButtonSelector);
  const style = useSelector(selectors.styleSelector);
  const dynamicFields = useSelector(selectors.dynamicFieldsSelector);
  const autocomplete = useSelector(selectors.autocompleteSelector);
  const scheme = useSelector(selectors.schemeSelector);
  const userPermissions = useSelector(getUserPermissionsSelector);
  const userAccountId = useSelector(getUserAccountIdSelector);
  const formMetadata = useSelector(getFormMetadataCalculation);

  const readOnly =
    (formSubmitMode === FORM_SUBMIT_MODE_UPDATE && !hasPermission(PUT_FORM_TEMPLATES, userPermissions)) ||
    ([FORM_SUBMIT_MODE_CREATE, FORM_SUBMIT_MODE_DUPLICATE].includes(formSubmitMode) &&
      !hasPermission(POST_FORM_TEMPLATES, userPermissions));

  useEffect(() => {
    dispatch(getCategoryOptionsAction());
  }, []);

  const setField = (o) => dispatch(setFieldAction(o));
  const getAccountOptions = (o) => dispatch(getAccountOptionsAction(o));
  const uploadLogo = (o) => dispatch(uploadLogoAction(o));
  const uploadBanner = (o) => dispatch(uploadBannerAction(o));

  const [LOGO, BANNER] = image;

  const shouldShowFormId = id && formSubmitMode === FORM_SUBMIT_MODE_UPDATE;

  return (
    <>
      <FormSection>
        <FormRow label="Name">
          <TextField
            size={size}
            value={name}
            placeholder="Enter Name"
            inputProps={{ maxLength: FIELD_MAX_LENGTH_NAME }}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  <Chip label={`${name.length} / ${FIELD_MAX_LENGTH_NAME}`} variant="text" size={size} />
                </InputAdornment>
              ),
            }}
            disabled={readOnly}
            onChange={({ target }) => setField({ name: target.value })}
            {...getInputPropsByName(scheme, ['name'])}
            onFocus={() => dispatch(removeErrorByPropAction(['name']))}
          />
          {shouldShowFormId && (
            <FormRowItem itemsInRow={4}>
              <TextField
                size={size}
                value={id}
                placeholder="Form Id"
                label="ID"
                inputProps={{
                  readOnly: true,
                }}
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <IconButton onClick={() => copyToClipboard(id)}>
                        <ContentCopyRounded />
                      </IconButton>
                    </InputAdornment>
                  ),
                }}
              />
            </FormRowItem>
          )}
        </FormRow>
        <FormRow label="Category">
          <Select
            size={size}
            placeholder="Category"
            value={category}
            disabled={readOnly}
            onChange={({ target }) =>
              setField({
                category: target.value,
              })
            }
          >
            {categoryOptions.map((category$) => (
              <MenuItem value={category$.value} key={category$.value}>
                {category$.label}
              </MenuItem>
            ))}
          </Select>
        </FormRow>
        {!userAccountId && (
          <FormRow label="Account">
            <Autocomplete
              value={account}
              disableClearable
              loading={!autocomplete.textOptions}
              options={autocomplete.textOptions || []}
              size={size}
              disabled={readOnly || (id && formSubmitMode !== FORM_SUBMIT_MODE_DUPLICATE)}
              onChange={(e, account$) =>
                setField({
                  account: account$,
                })
              }
              onOpen={() => {
                setField({
                  autocomplete: {
                    ...autocomplete,
                    textOptions: null,
                  },
                });
                getAccountOptions('');
              }}
              renderInput={(params) => (
                <TextField
                  {...params}
                  value=""
                  placeholder="Account"
                  {...getInputPropsByName(scheme, ['account'])}
                  onChange={({ target }) => getAccountOptions(target.value)}
                  onFocus={() => dispatch(removeErrorByPropAction(['account']))}
                />
              )}
            />
          </FormRow>
        )}
        <FormRow label="Logo">
          <FormImageUploader
            image={LOGO}
            accept="image/png, image/jpeg, image/jpg, image/webp"
            restrictionMessage={`${ALLOWED_IMAGE_EXT.map((item) => item.toUpperCase()).join(
              ', ',
            )}. Max File Size ${MAX_LOGO_SIZE_IN_BYTES / 1024}kb`}
            disabled={readOnly}
            onValidate={(file) => {
              const fileExt = file.name.split('.').pop();

              if (!ALLOWED_IMAGE_EXT.includes(fileExt.toLowerCase())) {
                dispatch(
                  showNotificationAction({
                    type: TYPE_ERROR,
                    message: `Invalid file extension, valid only (${ALLOWED_IMAGE_EXT.join(',')})`,
                  }),
                );

                return false;
              }
              if (file.size > MAX_LOGO_SIZE_IN_BYTES) {
                dispatch(
                  showNotificationAction({
                    type: TYPE_ERROR,
                    message: 'File size exceeded the maximum size permitted.',
                  }),
                );

                return false;
              }

              return true;
            }}
            onLoad={(event, file, readerResult) => {
              uploadLogo({
                image,
                file: readerResult,
                fileName: file.name,
              });
            }}
            onRemove={() => {
              setField({
                image: [null, BANNER],
              });
            }}
          />
        </FormRow>
        <FormRow label="Title" />
        <FormRow fullWidth>
          <RichEditor
            value={title}
            type="title"
            maxLength={FIELD_MAX_LENGTH_TITLE}
            disabled={readOnly}
            onChange={(content) => {
              setField({
                title: content,
              });
            }}
            {...getInputPropsByName(scheme, ['title'])}
            onFocus={() => dispatch(removeErrorByPropAction(['title']))}
          />
        </FormRow>
        <FormRow label="Description" />
        <FormRow fullWidth>
          <RichEditor
            value={description}
            type="description"
            maxLength={FIELD_MAX_LENGTH_DESCRIPTION}
            disabled={readOnly}
            onChange={(content) => {
              setField({
                description: content,
              });
            }}
            {...getInputPropsByName(scheme, ['description'])}
            label=""
            onFocus={() => dispatch(removeErrorByPropAction(['description']))}
          />
        </FormRow>
        <FormRow label="Fields" />
        <FormRow fullWidth>
          <DynamicFields
            fields={dynamicFields}
            disabled={readOnly}
            scheme={scheme}
            onSetField={setField}
            removeErrorByPropAction={(keyArray) => dispatch(removeErrorByPropAction(keyArray))}
          />
        </FormRow>
        <FormRow label="Submit Button">
          <TextField
            size={size}
            value={submitButton.title}
            placeholder="Enter Value"
            disabled={readOnly}
            inputProps={{ maxLength: FIELD_MAX_LENGTH_SUBMITTEXT }}
            onChange={({ target }) =>
              setField({
                submitButton: { title: target.value },
              })
            }
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  <Chip
                    label={`${submitButton.title.length} / ${FIELD_MAX_LENGTH_SUBMITTEXT}`}
                    variant="text"
                    size={size}
                  />
                </InputAdornment>
              ),
            }}
            {...getInputPropsByName(scheme, ['submitButton.title'])}
            onFocus={() => dispatch(removeErrorByPropAction(['submitButton.title']))}
          />
        </FormRow>
        <FormGroup>
          <FormRow
            label="Privacy Policy"
            tooltip="You must include a link to your site’s privacy policy as per existing privacy regulations"
            fullWidth
          />
          <FormRow label="Caption">
            <TextField
              size={size}
              value={privacyPolicy.title}
              placeholder="Enter Value"
              disabled={readOnly}
              inputProps={{ maxLength: FIELD_MAX_LENGTH_PPTEXT }}
              onChange={({ target }) =>
                setField({
                  privacyPolicy: {
                    ...privacyPolicy,
                    title: target.value,
                  },
                })
              }
              InputProps={{
                endAdornment: (
                  <InputAdornment position="end">
                    <Chip
                      label={`${privacyPolicy.title.length} / ${FIELD_MAX_LENGTH_PPTEXT}`}
                      variant="text"
                      size={size}
                    />
                  </InputAdornment>
                ),
              }}
              {...getInputPropsByName(scheme, ['privacyPolicy.title'])}
              onFocus={() => dispatch(removeErrorByPropAction(['privacyPolicy.title']))}
            />
          </FormRow>
        </FormGroup>
        <FormRow label="Terms & Conditions">
          <Switch
            size={size}
            color="primary"
            checked={termsConditions.isActive}
            disabled={readOnly}
            onChange={({ target }) =>
              setField({
                termsConditions: {
                  ...termsConditions,
                  isActive: target.checked,
                },
              })
            }
          />
        </FormRow>
        {termsConditions.isActive && (
          <FormGroup>
            <FormRow label="Caption">
              <TextField
                size={size}
                value={termsConditions.title}
                placeholder="Enter Value"
                disabled={readOnly || !termsConditions.isActive}
                inputProps={{ maxLength: FIELD_MAX_LENGTH_TCTEXT }}
                onChange={({ target }) =>
                  setField({
                    termsConditions: {
                      ...termsConditions,
                      title: target.value,
                    },
                  })
                }
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <Chip
                        label={`${termsConditions.title.length} / ${FIELD_MAX_LENGTH_TCTEXT}`}
                        variant="text"
                        size={size}
                        disabled={readOnly || !termsConditions.isActive}
                      />
                    </InputAdornment>
                  ),
                }}
                {...getInputPropsByName(scheme, ['termsConditions.title'])}
                onFocus={() => dispatch(removeErrorByPropAction(['termsConditions.title']))}
              />
            </FormRow>
          </FormGroup>
        )}
        <FormRow
          label="Include Skip Button"
          tooltip={
            'If you disable the skip button, your viewers will not be able\n' +
            'to continue watching the video without filling in the form'
          }
        >
          <Switch
            size={size}
            color="primary"
            checked={skipButton.isActive}
            disabled={readOnly}
            onChange={({ target }) =>
              setField({
                skipButton: {
                  ...skipButton,
                  isActive: target.checked,
                },
              })
            }
          />
        </FormRow>
        {skipButton.isActive && (
          <FormGroup>
            <FormRow label="Caption">
              <TextField
                size={size}
                value={skipButton.title}
                placeholder="Enter Value"
                disabled={readOnly || !skipButton.isActive}
                inputProps={{
                  maxLength: FIELD_MAX_LENGTH_SKIPBUTTONTEXT,
                }}
                onChange={({ target }) =>
                  setField({
                    skipButton: {
                      ...skipButton,
                      title: target.value,
                    },
                  })
                }
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <Chip
                        label={`${skipButton.title.length} / ${FIELD_MAX_LENGTH_SKIPBUTTONTEXT}`}
                        variant="text"
                        size={size}
                      />
                    </InputAdornment>
                  ),
                }}
                {...getInputPropsByName(scheme, ['skipButton.title'])}
                onFocus={() => dispatch(removeErrorByPropAction(['skipButton.title']))}
              />
            </FormRow>
          </FormGroup>
        )}
      </FormSection>
      <FormSection>
        <StylesSettings
          style={style}
          image={image}
          disabled={readOnly}
          setField={setField}
          uploadBanner={uploadBanner}
          onChange={(value) =>
            setField({
              style: {
                ...style,
                ...value,
              },
            })
          }
        />
        <FormGroup intent={false} className={styles.StickyItem} component="div">
          <FormRow fullWidth>
            <div className={styles.PreviewWrapper} id={FORM_PREVIEW_WIDGET_ID}>
              <FormPreview metadata={formMetadata} />
            </div>
          </FormRow>
        </FormGroup>
      </FormSection>
    </>
  );
}

export default DetailsTab;
