import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';
import { Monitor, PhoneIphone } from '@mui/icons-material';

import {
  DELAY_CLOSE_ICON_ENABLE_DEFAULT,
  FLOATING_DISABLED,
  FLOATING_MODE_DISABLED,
  FLOATING_MODE_DISABLED_LABEL,
  FLOATING_STANDARD,
} from '@/modules/players/Editor/constants';

import * as playerSelectors from '../../../redux/selectors';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import {
  castToInt,
  getDefaultFloatingMobilePosition,
  getDependentFieldsDefaultValuesObj,
  isAmpTypes,
  isIntelligentAmpType,
  isIntelligentType,
  isOutstreamType,
  isStoriesTypes,
  isVerticalType,
} from '@/modules/players/Editor/helpers';
import { removeErrorByPropAction, setAction } from '@/modules/players/Editor/redux/slices';

import { FormRow, FormSection, useFormSettings } from '@/modules/@common/Form';
import { MenuItem, Select, Stack, TextField, Tooltip } from '@/mui/components';

function FloatingTab({ playerPreview = null }) {
  const { size } = useFormSettings();
  const dispatch = useDispatch();
  const router = useRouter();

  const floatingDesktopEnabled = useSelector(playerSelectors.floatingDesktopEnabledSelector);
  const floatingDesktopEnabledOptions = useSelector(playerSelectors.floatingDesktopEnabledOptionsSelector);
  const floatingDesktopMode = useSelector(playerSelectors.floatingDesktopModeSelector);
  const floatingDesktopModeOptions = useSelector(playerSelectors.floatingDesktopModeOptionsSelector);
  const floatingDesktopPosition = useSelector(playerSelectors.floatingDesktopPositionSelector);
  const floatingDesktopPositionOptions = useSelector(playerSelectors.floatingDesktopPositionOptionsSelector);
  const floatingDesktopWidth = useSelector(playerSelectors.floatingDesktopWidthSelector);
  const floatingDesktopWidthVerticalDefault = useSelector(playerSelectors.floatingDesktopWidthVerticalSelector);
  const floatingDesktopDelay = useSelector(playerSelectors.floatingDesktopDelaySelector);

  const floatingMobileEnabled = useSelector(playerSelectors.floatingMobileEnabledSelector);
  const floatingMobileEnabledOptions = useSelector(playerSelectors.floatingMobileEnabledOptionsSelector);
  const floatingMobileMode = useSelector(playerSelectors.floatingMobileModeSelector);
  const floatingMobileModeOptions = useSelector(playerSelectors.floatingMobileModeOptionsSelector);
  const floatingMobilePosition = useSelector(playerSelectors.floatingMobilePositionSelector);
  const floatingMobilePositionOptions = useSelector(playerSelectors.floatingMobilePositionOptionsSelector);
  const floatingMobileWidth = useSelector(playerSelectors.floatingMobileWidthSelector);
  const floatingMobileWidthVerticalDefault = useSelector(playerSelectors.floatingMobileWidthVerticalSelector);
  const floatingMobileDelay = useSelector(playerSelectors.floatingMobileDelaySelector);
  const playerType = useSelector(playerSelectors.playerTypeSelector);
  const scheme = useSelector(playerSelectors.schemeSelector);

  const [floatingMobileEnabledOptionsState, setFloatingMobileEnabledOptionsState] =
    useState(floatingMobileEnabledOptions);

  const [floatingMobileAmpModeOptionsState, setFloatingMobileAmpModeOptionsState] = useState([
    {
      value: FLOATING_DISABLED,
      label: FLOATING_MODE_DISABLED_LABEL,
      dependentFieldsDefaults: {
        delayCloseIconEnabledMobile: DELAY_CLOSE_ICON_ENABLE_DEFAULT,
      },
    },
  ]);

  const [floatingDesktopEnabledPrevious, setFloatingDesktopEnabledPrevious] = useState(1);
  const [floatingMobileEnabledPrevious, setFloatingMobileEnabledPrevious] = useState(1);

  const id = parseInt(router.query.params[1], 10) || null;
  const copyFromId = parseInt(router.query.copy, 10) || null;
  const playerTypeId = playerType?.id;
  const isIntelligent = isIntelligentType(playerTypeId);
  const isStories = isStoriesTypes(playerTypeId);
  const isIntelligentAmp = isIntelligentAmpType(playerTypeId);
  const isVertical = isVerticalType(playerTypeId);
  const isAmp = isAmpTypes(playerTypeId);
  const isOutstream = isOutstreamType(playerTypeId);

  useEffect(() => {
    if (isOutstream && !id) {
      dispatch(
        setAction({
          floatingMobileMode: floatingMobileModeOptions.find((mode) => mode.forOutstream)?.value,
          floatingDesktopMode: floatingDesktopModeOptions.find((mode) => mode.forOutstream)?.value,
        }),
      );
    }

    if (!floatingMobileEnabledOptions.length) return;

    let filteredOptions = [];
    if (isAmp) {
      filteredOptions = floatingMobileEnabledOptions.filter((o) => o.forAmp);
    } else if (isOutstream) {
      filteredOptions = floatingMobileEnabledOptions.filter((o) => o.forOutstream);
    }

    if (isAmp) {
      if (!id && !copyFromId) {
        dispatch(setAction({ floatingMobileEnabled: FLOATING_DISABLED }));
      }
      setFloatingMobileAmpModeOptionsState([...floatingMobileAmpModeOptionsState, ...filteredOptions]);
    } else {
      setFloatingMobileEnabledOptionsState(filteredOptions);
    }
  }, [floatingMobileEnabledOptions, playerTypeId, id, copyFromId]);

  useEffect(() => {
    if (!id && isVertical && !copyFromId) {
      dispatch(
        setAction({
          floatingDesktopWidth: floatingDesktopWidthVerticalDefault,
          floatingMobileWidth: floatingMobileWidthVerticalDefault,
        }),
      );
    }
  }, [playerTypeId, floatingDesktopWidthVerticalDefault, floatingMobileWidthVerticalDefault]);

  const showDesktopSettings = !isAmp;

  const showStyle = !isStories && !isVertical && !isIntelligentAmp;

  const showPosition = !isAmp;
  const showWidth = !isAmp;
  const showDelay = !isAmp && !isOutstream;

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

  return (
    <>
      <FormSection>
        <FormRow label>
          {showDesktopSettings && (
            <Tooltip title="Desktop">
              <Stack fullWidth alignItems="center">
                <Monitor fontSize="large" htmlColor="neutral" />
              </Stack>
            </Tooltip>
          )}
          <Tooltip title="Mobile">
            <Stack fullWidth alignItems="center">
              <PhoneIphone fontSize="large" htmlColor="neutral" />
            </Stack>
          </Tooltip>
        </FormRow>
        <FormRow label="Floating Mode">
          {showDesktopSettings && (
            <Select
              size={size}
              value={floatingDesktopEnabled === FLOATING_DISABLED ? FLOATING_MODE_DISABLED : floatingDesktopMode}
              onChange={({ target }) => {
                const { value } = target;
                if (value === FLOATING_MODE_DISABLED) {
                  handleSetState({
                    floatingDesktopEnabled: 0,
                  });
                } else {
                  handleSetState({
                    floatingDesktopMode: value,
                    floatingDesktopEnabled: floatingDesktopEnabledPrevious,
                  });
                }
              }}
            >
              {floatingDesktopModeOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          )}
          {isAmp ? (
            <Select
              size={size}
              value={floatingMobileEnabled}
              onChange={({ target }) => {
                const { value } = target;
                handleSetState({
                  floatingMobileEnabled: value,
                  ...getDependentFieldsDefaultValuesObj(value, floatingMobileAmpModeOptionsState),
                });
              }}
            >
              {floatingMobileAmpModeOptionsState.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          ) : (
            <Select
              size={size}
              value={floatingMobileEnabled === FLOATING_DISABLED ? FLOATING_MODE_DISABLED : floatingMobileMode}
              onChange={({ target }) => {
                const { value } = target;
                if (value === FLOATING_MODE_DISABLED) {
                  handleSetState({
                    floatingMobileEnabled: 0,
                    delayCloseIconEnabledMobile: DELAY_CLOSE_ICON_ENABLE_DEFAULT,
                  });
                } else {
                  handleSetState({
                    floatingMobileMode: value,
                    floatingMobileEnabled: floatingMobileEnabledPrevious,
                    ...getDependentFieldsDefaultValuesObj(floatingMobileEnabledPrevious, floatingMobileEnabledOptions),
                  });
                }
              }}
            >
              {floatingMobileModeOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          )}
        </FormRow>
        {showStyle && (
          <FormRow label="Style">
            {showDesktopSettings && (
              <Select
                displayEmpty
                disabled
                size={size}
                value={
                  floatingDesktopEnabled !== null && !floatingDesktopEnabled
                    ? floatingDesktopEnabledPrevious
                    : floatingDesktopEnabled
                }
                onChange={({ target }) => {
                  setFloatingDesktopEnabledPrevious(target.value);
                  handleSetState({
                    floatingDesktopEnabled: target.value,
                  });
                }}
              >
                {floatingDesktopEnabledOptions.map(({ value, label }) => (
                  <MenuItem key={value} value={value}>
                    {label}
                  </MenuItem>
                ))}
              </Select>
            )}
            <Select
              disabled={floatingMobileEnabled !== null && !floatingMobileEnabled}
              size={size}
              value={
                floatingMobileEnabled !== null && !floatingMobileEnabled
                  ? floatingMobileEnabledPrevious
                  : floatingMobileEnabled
              }
              onChange={({ target }) => {
                const defaultWidth = floatingMobileEnabledOptions.find((option) => option.isDefault)?.width;
                setFloatingMobileEnabledPrevious(target.value);
                if (target !== FLOATING_STANDARD) {
                  handleSetState({
                    floatingMobileWidth: defaultWidth,
                  });
                  dispatch(removeErrorByPropAction(['floatingMobileWidth']));
                }

                handleSetState({
                  floatingMobileEnabled: target.value,
                  ...(isIntelligent || isOutstream
                    ? {
                        floatingMobilePosition: getDefaultFloatingMobilePosition(
                          +target.value,
                          floatingMobilePositionOptions,
                        ),
                      }
                    : {}),
                  ...getDependentFieldsDefaultValuesObj(+target.value, floatingMobileEnabledOptions),
                });
              }}
            >
              {floatingMobileEnabledOptionsState.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          </FormRow>
        )}
        {showPosition && (
          <FormRow label="Position">
            {showDesktopSettings && (
              <Select
                disabled={floatingDesktopEnabled !== null && !floatingDesktopEnabled}
                size={size}
                value={floatingDesktopPosition}
                onChange={({ target }) =>
                  handleSetState({
                    floatingDesktopPosition: target.value,
                  })
                }
              >
                {floatingDesktopPositionOptions.map(({ value, label }) => (
                  <MenuItem key={value} value={value}>
                    {label}
                  </MenuItem>
                ))}
              </Select>
            )}
            <Select
              disabled={floatingMobileEnabled !== null && !floatingMobileEnabled}
              size={size}
              value={floatingMobilePosition}
              onChange={({ target }) => handleSetState({ floatingMobilePosition: target.value })}
            >
              {floatingMobilePositionOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          </FormRow>
        )}
        {showWidth && (
          <FormRow label="Width">
            {showDesktopSettings && (
              <TextField
                disabled={floatingDesktopEnabled !== null && !floatingDesktopEnabled}
                size={size}
                value={floatingDesktopWidth}
                onChange={({ target }) =>
                  handleSetState({
                    floatingDesktopWidth: target.value,
                  })
                }
                onBlur={({ target }) =>
                  handleSetState({
                    floatingDesktopWidth: castToInt(target.value),
                  })
                }
                {...getInputPropsByName(scheme, ['floatingDesktopWidth'])}
                onFocus={() => dispatch(removeErrorByPropAction(['floatingDesktopWidth']))}
              />
            )}
            <TextField
              disabled={
                (floatingMobileEnabled !== null && !floatingMobileEnabled) ||
                floatingMobileEnabled !== FLOATING_STANDARD
              }
              placeholder="Full Width"
              size={size}
              value={floatingMobileEnabled === FLOATING_STANDARD ? floatingMobileWidth : ''}
              onChange={({ target }) =>
                handleSetState({
                  floatingMobileWidth: target.value,
                })
              }
              onBlur={({ target }) =>
                handleSetState({
                  floatingMobileWidth: castToInt(target.value),
                })
              }
              {...getInputPropsByName(scheme, ['floatingMobileWidth'])}
              onFocus={() => dispatch(removeErrorByPropAction(['floatingMobileWidth']))}
            />
          </FormRow>
        )}
        {showDelay && (
          <FormRow
            label="Delay (sec)"
            tooltip="This setting controls the time delay before the video player appears in its floating position.
             Enter a value in seconds to determine how long the player will wait before becoming visible.
             A delay of 0 seconds means the player will instantly appear when triggered."
          >
            {showDesktopSettings && (
              <TextField
                disabled={floatingDesktopEnabled !== null && !floatingDesktopEnabled}
                size={size}
                value={floatingDesktopDelay}
                onChange={({ target }) => handleSetState({ floatingDesktopDelay: target.value })}
                onBlur={({ target }) => handleSetState({ floatingDesktopDelay: castToInt(target.value) })}
                {...getInputPropsByName(scheme, ['floatingDesktopDelay'])}
                onFocus={() => dispatch(removeErrorByPropAction(['floatingDesktopDelay']))}
              />
            )}
            <TextField
              disabled={floatingMobileEnabled !== null && !floatingMobileEnabled}
              size={size}
              value={floatingMobileDelay}
              onChange={({ target }) => handleSetState({ floatingMobileDelay: target.value })}
              onBlur={({ target }) => handleSetState({ floatingMobileDelay: castToInt(target.value) })}
              {...getInputPropsByName(scheme, ['floatingMobileDelay'])}
              onFocus={() => dispatch(removeErrorByPropAction(['floatingMobileDelay']))}
            />
          </FormRow>
        )}
      </FormSection>
      {playerPreview}
    </>
  );
}

FloatingTab.propTypes = {
  playerPreview: PropTypes.node,
};

export default FloatingTab;
