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

import { TYPE_ERROR } from '@/modules/@common/notify/constants';
import { FORM_PREVIEW_WIDGET_ID } 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,
  FORM_SUBMIT_MODE_UPDATE,
  MAX_LOGO_SIZE_IN_BYTES,
  PERIOD_DAILY,
  PERIOD_MONTHLY,
  PERIOD_WEEKLY,
  SCHEDULE_REPORT_PERIOD_OPTIONS,
  STATUS_DISABLED,
} from '@/modules/forms/editor/constants';

import { getFormMetadataCalculation } from '../../helpers/calculationsFromState';
import { getErrorMessageForEmail } from '../../helpers/validationRules';
import * as selectors from '../../redux/selectors';
import {
  getPlayerOptionsAction,
  getSiteOptionsAction,
  removeErrorByPropAction,
  sendTestEmailAction,
  setFieldAction,
  uploadBannerAction,
  uploadLogoAction,
} from '../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import copyToClipboard from '@/modules/@common/helpers/copy';
import useFormSubmitMode from '@/modules/forms/helpers/useFormSubmitMode';
import useGetReadOnlyStatus from '@/modules/forms/helpers/useGetReadOnlyStatus';
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 PlayerPreview from './components/PlayerPreview';
import {
  Autocomplete,
  Button,
  Checkbox,
  Chip,
  FormControlLabel,
  IconButton,
  InputAdornment,
  MenuItem,
  Select,
  Stack,
  Switch,
  TextField,
  Tooltip,
} from '@/mui/components';

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

const getPeriodHint = (type) => {
  const hints = {
    [PERIOD_DAILY]: 'Email will be sent daily at 9:00 AM UTC',
    [PERIOD_WEEKLY]: 'Email will be sent every Monday at 9:00 AM',
    [PERIOD_MONTHLY]: 'Email will be sent on the 1st of every month at 9:00 AM UTC',
  };
  return hints[type];
};

function DetailsTab() {
  const dispatch = useDispatch();
  const { size } = useFormSettings();
  const router = useRouter();
  const formMetadata = useSelector(getFormMetadataCalculation);
  const image = useSelector(selectors.imageSelector);
  const id = useSelector(selectors.idSelector);
  const name = useSelector(selectors.nameSelector);
  const site = useSelector(selectors.siteSelector);
  const autocomplete = useSelector(selectors.autocompleteSelector);
  const trigger = useSelector(selectors.triggerSelector);
  const scheduleReport = useSelector(selectors.scheduleReportSelector);
  const enableInstantDelivery = useSelector(selectors.enableInstantDeliverySelector);
  const title = useSelector(selectors.titleSelector);
  const description = useSelector(selectors.descriptionSelector);
  const dynamicFields = useSelector(selectors.dynamicFieldsSelector);
  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 status = useSelector(selectors.statusSelector);
  const scheme = useSelector(selectors.schemeSelector);
  const [playerPreview, togglePlayerPreview] = useState(false);
  const formSubmitMode = useFormSubmitMode(router);
  const readOnly = useGetReadOnlyStatus(status);
  const [LOGO, BANNER] = image;

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

  // check if autocomplete.textOptions has player based on playerAspectRatio props
  // flow:
  // 1. user select hub
  // 2. call to getPlayers API and result assign to textOptions
  const siteHasPlayers = !!(site && autocomplete.textOptions?.some((option) => option.playerAspectRatio));

  useEffect(() => {
    if (site) {
      dispatch(
        setFieldAction({
          autocomplete: {
            ...autocomplete,
            textOptions: null,
          },
        }),
      );
      dispatch(getPlayerOptionsAction(''));
    }
  }, [site]);

  const setField = (o) => dispatch(setFieldAction(o));
  const getSiteOptions = (o) => dispatch(getSiteOptionsAction(o));
  const uploadLogo = (o) => dispatch(uploadLogoAction(o));
  const uploadBanner = (o) => dispatch(uploadBannerAction(o));
  const sendTestEmail = (o) => dispatch(sendTestEmailAction(o));

  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}
            {...getInputPropsByName(scheme, ['name'])}
            onFocus={() => dispatch(removeErrorByPropAction(['name']))}
            onChange={({ target }) => setField({ name: target.value })}
          />
          {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="Hub">
          <Autocomplete
            value={site}
            loading={!autocomplete.textOptions}
            options={autocomplete.textOptions || []}
            size={size}
            disabled={readOnly}
            onChange={(e, site$) =>
              setField({
                site: site$,
                status: site$ ? status : STATUS_DISABLED,
                trigger: {
                  ...trigger,
                  isActive: site$ ? trigger.isActive : false,
                  watch: null,
                  watchChannel: null,
                  playerName: null,
                  domains: [],
                },
              })
            }
            onOpen={() => {
              setField({
                autocomplete: {
                  ...autocomplete,
                  textOptions: null,
                },
              });
              getSiteOptions('');
            }}
            renderInput={(params) => (
              <TextField
                {...params}
                value=""
                placeholder="Hub"
                {...getInputPropsByName(scheme, ['site'])}
                onFocus={() => dispatch(removeErrorByPropAction(['site']))}
                onChange={({ target }) => getSiteOptions(target.value)}
              />
            )}
            renderOption={(props$, option) => (
              <li {...props$} key={option.value}>
                {option.label}
              </li>
            )}
          />
        </FormRow>
        <FormRow label="Schedule Report" multiline>
          <TextField
            size={size}
            value={scheduleReport.email}
            placeholder="Enter Email"
            disabled={readOnly}
            {...getInputPropsByName(scheme, ['scheduleReport.email'])}
            onFocus={() => dispatch(removeErrorByPropAction(['scheduleReport.email']))}
            onChange={({ target }) =>
              setField({
                scheduleReport: {
                  ...scheduleReport,
                  email: target.value,
                },
              })
            }
          />
          <Stack spacing={2} direction="row" fullWidth>
            <Select
              size={size}
              value={scheduleReport.period}
              disabled={readOnly}
              onChange={({ target }) =>
                setField({
                  scheduleReport: {
                    ...scheduleReport,
                    period: target.value,
                  },
                })
              }
            >
              {SCHEDULE_REPORT_PERIOD_OPTIONS.map((item) => (
                <MenuItem value={item.value} key={item.value}>
                  <Stack spacing={1} fullWidth direction="row" alignItems="center" justifyContent="space-between">
                    <div>{item.label}</div>
                    <Tooltip title={getPeriodHint(item.value)}>
                      <IconButton readOnly color="info" size={size} component="span">
                        <InfoOutlined />
                      </IconButton>
                    </Tooltip>
                  </Stack>
                </MenuItem>
              ))}
            </Select>
            <Button
              size={size}
              variant="outlined"
              color="neutral"
              disabled={readOnly || !!getErrorMessageForEmail(scheduleReport.email)}
              onClick={() => sendTestEmail(scheduleReport.email)}
            >
              Test Email
            </Button>
          </Stack>
          <Stack fullWidth>
            <FormControlLabel
              size={size}
              control={
                <Checkbox
                  size={size}
                  color="primary"
                  checked={enableInstantDelivery}
                  disabled={readOnly}
                  onChange={({ target }) =>
                    setField({
                      enableInstantDelivery: target.checked,
                    })
                  }
                />
              }
              label="Receive an email for each response"
            />
          </Stack>
        </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}
            required={false}
            error={false}
            helperText=""
            onChange={(content) => {
              setField({
                description: content,
              });
            }}
            {...getInputPropsByName(scheme, ['description'])}
            label=""
            onFocus={() => dispatch(removeErrorByPropAction(['description']))}
          />
        </FormRow>
        <FormRow label="Fields" required />
        <FormRow fullWidth>
          <DynamicFields
            fields={dynamicFields}
            disabled={readOnly}
            scheme={scheme}
            removeErrorByPropAction={(keyArray) => dispatch(removeErrorByPropAction(keyArray))}
            onSetField={setField}
          />
        </FormRow>
        <FormRow label="Submit Button">
          <TextField
            size={size}
            value={submitButton.title}
            placeholder="Enter Value"
            disabled={readOnly}
            inputProps={{ maxLength: FIELD_MAX_LENGTH_SUBMITTEXT }}
            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(['name']))}
            onChange={({ target }) =>
              setField({
                submitButton: { title: target.value },
              })
            }
          />
        </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 }}
              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']))}
              onChange={({ target }) =>
                setField({
                  privacyPolicy: {
                    ...privacyPolicy,
                    title: target.value,
                  },
                })
              }
            />
          </FormRow>
          <FormRow label="URL">
            <TextField
              size={size}
              value={privacyPolicy.src}
              placeholder="https://"
              disabled={readOnly}
              {...getInputPropsByName(scheme, ['privacyPolicy.src'])}
              onFocus={() => dispatch(removeErrorByPropAction(['privacyPolicy.src']))}
              onChange={({ target }) =>
                setField({
                  privacyPolicy: {
                    ...privacyPolicy,
                    src: target.value,
                  },
                })
              }
            />
          </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 }}
                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']))}
                onChange={({ target }) =>
                  setField({
                    termsConditions: {
                      ...termsConditions,
                      title: target.value,
                    },
                  })
                }
              />
            </FormRow>
            <FormRow label="URL">
              <TextField
                size={size}
                value={termsConditions.src}
                placeholder="https://"
                disabled={readOnly || !termsConditions.isActive}
                {...getInputPropsByName(scheme, ['termsConditions.src'])}
                onFocus={() => dispatch(removeErrorByPropAction(['termsConditions.src']))}
                onChange={({ target }) =>
                  setField({
                    termsConditions: {
                      ...termsConditions,
                      src: target.value,
                    },
                  })
                }
              />
            </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,
                }}
                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']))}
                onChange={({ target }) =>
                  setField({
                    skipButton: {
                      ...skipButton,
                      title: target.value,
                    },
                  })
                }
              />
            </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 label="Form preview" justifyContent="flex-end" fullWidth>
            <Button
              variant="text"
              size={size}
              color="neutral"
              label="Click Me"
              startIcon={<PlayCircleFilledRounded />}
              onClick={() => togglePlayerPreview(true)}
              disabled={readOnly || !siteHasPlayers}
            >
              Player Preview
            </Button>
          </FormRow>
          <FormRow fullWidth>
            <div className={styles.PreviewWrapper} id={FORM_PREVIEW_WIDGET_ID}>
              {siteHasPlayers && <FormPreview metadata={formMetadata} />}
            </div>
          </FormRow>
        </FormGroup>
      </FormSection>
      {playerPreview && siteHasPlayers && (
        <PlayerPreview
          playerOptions={autocomplete.textOptions}
          onClose={() => togglePlayerPreview(false)}
          metadata={formMetadata}
        />
      )}
    </>
  );
}

export default DetailsTab;
