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

import { TYPE_E } from '../../Carousel/constants';
import { REDUX_ERROR_PROP_NAME } from '@/modules/@common/Form/constants';
import { TYPE_WARNING } from '@/modules/@common/notify/constants';
import {
  DISABLED_FLOW_TERM_OPTION,
  DISABLED_FLOW_TERM_OPTION_ID,
  EDITORIAL_TYPE_DEFAULT,
  EDITORIAL_TYPE_ONLY,
  PLAYBACK_MODE_CLICK_TO_PLAY,
  PLAYBACK_MODE_SCROLL_TO_PLAY,
  PLAYBACK_TAB,
} from '@/modules/players/Editor/constants';

import * as playerSelectors from '../../../redux/selectors';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import { notifyAction } from '@/modules/@common/notify/redux/slices';
import { castToInt, isAmpTypes, isStoriesTypes, isVerticalType } from '@/modules/players/Editor/helpers';
import {
  getPlayerEditorialPlaylistsOptionsAction,
  removeErrorByPropAction,
  setAction,
  setActiveTabIdAction,
  setErrorByPropAction,
  setScrollToFieldNameAction,
  validateSingleField,
} from '@/modules/players/Editor/redux/slices';

import { FormGroup, FormRow, FormSection, useFormSettings } from '@/modules/@common/Form';
import Carousel from '../../Carousel/component/Carousel';
import { Autocomplete, List, ListItem, MenuItem, Select, Stack, Switch, TextField, Tooltip } from '@/mui/components';

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

  const activeTabId = useSelector(playerSelectors.activeTabIdSelector);
  const autoplayOptions = useSelector(playerSelectors.autoplayOptionsSelector);
  const autoplayDesktop = useSelector(playerSelectors.autoplayDesktopSelector);
  const autoplayMobile = useSelector(playerSelectors.autoplayMobileSelector);

  const startWithSoundOptions = useSelector(playerSelectors.startWithSoundOptionsSelector);
  const startWithSound = useSelector(playerSelectors.startWithSoundSelector);
  const startWithSoundMobile = useSelector(playerSelectors.startWithSoundMobileSelector);

  const playlistLimit = useSelector(playerSelectors.playlistLimitSelector);

  const flowTermId = useSelector(playerSelectors.flowTermIdSelector);
  const flowTermsOptions = useSelector(playerSelectors.flowTermsOptionsSelector);

  const playInLoop = useSelector(playerSelectors.playInLoopSelector);
  const playInLoopOptions = useSelector(playerSelectors.playInLoopOptionsSelector);

  const clipAutomaticSkipOptions = useSelector(playerSelectors.clipAutomaticSkipOptionsSelector);
  const clipAutomaticSkipEnabled = useSelector(playerSelectors.clipAutomaticSkipEnabledSelector);
  const clipAutomaticSkipTimeToPresent = useSelector(playerSelectors.clipAutomaticSkipTimeToPresentSelector);
  const clipAutomaticSkipTimeToSkip = useSelector(playerSelectors.clipAutomaticSkipTimeToSkipSelector);

  const shufflePlaylist = useSelector(playerSelectors.shufflePlaylistSelector);

  const publisher = useSelector(playerSelectors.publisherSelector);
  const playerEditorialPlaylist = useSelector(playerSelectors.playerEditorialPlaylistSelector);
  const playerEditorialPlaylistsOptions = useSelector(playerSelectors.playerEditorialPlaylistsOptionsSelector);

  const playerType = useSelector(playerSelectors.playerTypeSelector);
  const scheme = useSelector(playerSelectors.schemeSelector);

  const flowTermsOptionsState = useMemo(() => [...flowTermsOptions, DISABLED_FLOW_TERM_OPTION], [flowTermsOptions]);

  const [fallbackPlaylistDropDownOpen, setFallbackPlaylistDropDownOpen] = useState(false);

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

  useEffect(() => {
    if ((isStories || isVertical) && !id && !copyFromId) {
      dispatch(setAction({ playInLoop: 0, loopPlaylist: 1, adsOnLoopOff: 1 })); // Enabled
    }
  }, [playInLoopOptions]);

  const showDesktopSettings = !isAmp;
  const showStartWithSound = !isStories;
  const showPlaylistType = !isStories;
  const showFallbackPlaylist = !isStories;
  const showShuffleVideo = !isStories;
  const disabledRepeatPlaylist = isVertical;

  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="Playback Mode">
        {showDesktopSettings && (
          <Select
            size={size}
            value={autoplayDesktop}
            onChange={({ target }) => {
              const { value } = target;
              handleSetState({
                autoplayDesktop: value,
                ...(value !== PLAYBACK_MODE_SCROLL_TO_PLAY && { startWithSound: 0 }),
              });
            }}
          >
            {autoplayOptions.map(({ id: id$, termUi }) => (
              <MenuItem key={id$} value={id$}>
                {termUi}
              </MenuItem>
            ))}
          </Select>
        )}
        <Select
          size={size}
          value={autoplayMobile}
          onChange={({ target }) => {
            const { value } = target;
            handleSetState({
              autoplayMobile: value,
              ...(value !== PLAYBACK_MODE_SCROLL_TO_PLAY && { startWithSoundMobile: 0 }),
            });
          }}
        >
          {autoplayOptions.map(({ id: id$, termUi }) => (
            <MenuItem key={id$} value={id$}>
              {termUi}
            </MenuItem>
          ))}
        </Select>
      </FormRow>
      {showStartWithSound && (
        <FormRow label="Start with Sound" tooltip="Can work only when Playback mode is set to “Click to Play”.">
          {showDesktopSettings && (
            <Select
              size={size}
              disabled={autoplayDesktop !== PLAYBACK_MODE_CLICK_TO_PLAY}
              variant="outlined"
              value={startWithSound}
              onChange={({ target }) => {
                handleSetState({
                  startWithSound: target.value,
                });
              }}
            >
              {startWithSoundOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          )}
          <Select
            size={size}
            disabled={autoplayMobile !== PLAYBACK_MODE_CLICK_TO_PLAY}
            value={startWithSoundMobile}
            onChange={({ target }) => {
              handleSetState({
                startWithSoundMobile: target.value,
              });
            }}
          >
            {startWithSoundOptions.map(({ value, label }) => (
              <MenuItem key={value} value={value}>
                {label}
              </MenuItem>
            ))}
          </Select>
        </FormRow>
      )}
      <FormRow label="Playlist Length">
        <TextField
          size={size}
          value={playlistLimit} // 1-200
          onChange={({ target }) => handleSetState({ playlistLimit: target.value })}
          onBlur={({ target }) => handleSetState({ playlistLimit: castToInt(target.value) })}
          {...getInputPropsByName(scheme, ['playlistLimit'])}
          onFocus={() => dispatch(removeErrorByPropAction(['playlistLimit']))}
        />
      </FormRow>
      {showPlaylistType && (
        <FormRow label="Playlist Type">
          <Select
            size={size}
            value={flowTermId === null ? DISABLED_FLOW_TERM_OPTION_ID : flowTermId}
            onChange={({ target }) =>
              handleSetState({
                flowTermId: target.value,
                editorialEnabled: target.value === DISABLED_FLOW_TERM_OPTION_ID ? 1 : 0,
                editorialType:
                  target.value === DISABLED_FLOW_TERM_OPTION_ID ? EDITORIAL_TYPE_ONLY : EDITORIAL_TYPE_DEFAULT,
              })
            }
          >
            {flowTermsOptionsState.map(({ id: id$, termUiSelfServe }) => (
              <MenuItem key={id$} value={id$}>
                {termUiSelfServe}
              </MenuItem>
            ))}
          </Select>
        </FormRow>
      )}
      <FormRow label="Repeat Playlist">
        <Select
          size={size}
          disabled={disabledRepeatPlaylist}
          value={playInLoop}
          onChange={({ target }) =>
            handleSetState({
              playInLoop: target.value,
              loopPlaylist: target.value === 0 ? 1 : 0,
              adsOnLoopOff: target.value === 1 ? 0 : 1,
            })
          }
        >
          {playInLoopOptions.map(({ value, label }) => (
            <MenuItem key={value} value={value}>
              {label}
            </MenuItem>
          ))}
        </Select>
      </FormRow>
      {showShuffleVideo && (
        <FormRow
          label="Shuffle Video"
          tooltip="Can work only when Playlist type is set to “Recent Videos” or ”Fallback Playlist”."
        >
          <Switch
            size={size}
            color="primary"
            checked={shufflePlaylist}
            onChange={({ target }) =>
              handleSetState({
                shufflePlaylist: target.checked ? 1 : 0,
              })
            }
          />
        </FormRow>
      )}
      <FormRow
        label="Automatic Skip"
        tooltip={
          <div>
            {"Enable Automatic Skip to show ‘Next' and ‘Stay' buttons after a set ‘Wait Time’. "}
            {'Buttons appear for a specified duration (’Appearance Time’) before auto-skipping to the next clip.\n'}
            {"For the best ad-related user experience, enable 'True Pre-Roll' "}
            {"with a minimum Timeout of 8000 ms in the 'Video ads' tab."}
          </div>
        }
      >
        <Switch
          size={size}
          color="primary"
          checked={!!clipAutomaticSkipEnabled}
          onChange={({ target }) => {
            handleSetState({
              clipAutomaticSkipEnabled: target.checked ? 1 : 0,
              ...(!target.checked && {
                clipAutomaticSkipTimeToPresent: clipAutomaticSkipOptions.clipAutomaticSkipTimeToPresent.defaultValue,
                clipAutomaticSkipTimeToSkip: clipAutomaticSkipOptions.clipAutomaticSkipTimeToSkip.defaultValue,
              }),
            });
            if (!target.checked) {
              dispatch(removeErrorByPropAction(['clipAutomaticSkipTimeToPresent']));
              dispatch(removeErrorByPropAction(['clipAutomaticSkipTimeToSkip']));
            }
          }}
        />
      </FormRow>
      {!!clipAutomaticSkipEnabled && (
        <FormGroup>
          <FormRow label="Wait Time (seconds)">
            <TextField
              size={size}
              value={clipAutomaticSkipTimeToPresent}
              onChange={({ target }) => handleSetState({ clipAutomaticSkipTimeToPresent: target.value })}
              onBlur={({ target }) => handleSetState({ clipAutomaticSkipTimeToPresent: castToInt(target.value) })}
              {...getInputPropsByName(scheme, ['clipAutomaticSkipTimeToPresent'])}
              onFocus={() => dispatch(removeErrorByPropAction(['clipAutomaticSkipTimeToPresent']))}
            />
          </FormRow>
          <FormRow label="Appearance Time (seconds)">
            <TextField
              size={size}
              value={clipAutomaticSkipTimeToSkip}
              onChange={({ target }) => handleSetState({ clipAutomaticSkipTimeToSkip: target.value })}
              onBlur={({ target }) => handleSetState({ clipAutomaticSkipTimeToSkip: castToInt(target.value) })}
              {...getInputPropsByName(scheme, ['clipAutomaticSkipTimeToSkip'])}
              onFocus={() => dispatch(removeErrorByPropAction(['clipAutomaticSkipTimeToSkip']))}
            />
          </FormRow>
        </FormGroup>
      )}
      {showFallbackPlaylist && (
        <>
          <FormRow
            label="Fallback Playlist"
            tooltip={
              <>
                The Playlist should be pre-created in the “Studio” section. The playlist will be used in any of the
                following cases:
                <List listStyle="initial" disablePadding dense>
                  <ListItem disablePadding dense>
                    “Fallback Playlist” was chosen as the Playlist method.
                  </ListItem>
                  <ListItem disablePadding dense>
                    There aren’t enough relevant/recent Videos to fill the chosen carousel length.
                  </ListItem>
                </List>
              </>
            }
          >
            <Autocomplete
              size={size}
              open={fallbackPlaylistDropDownOpen}
              value={playerEditorialPlaylist}
              options={playerEditorialPlaylistsOptions || []}
              loading={!playerEditorialPlaylistsOptions}
              onOpen={() => {
                const validation = validateSingleField('publisher', publisher);

                if (validation[REDUX_ERROR_PROP_NAME]) {
                  dispatch(setErrorByPropAction([validation]));
                  dispatch(setActiveTabIdAction(validation.tabId));
                  dispatch(setScrollToFieldNameAction(validation.fieldName));
                  dispatch(
                    notifyAction({
                      type: TYPE_WARNING,
                      message: 'Please select a Hub from the list',
                    }),
                  );
                } else {
                  setFallbackPlaylistDropDownOpen(true);
                  dispatch(
                    getPlayerEditorialPlaylistsOptionsAction({
                      publisherId: publisher?.id,
                      searchText: '',
                    }),
                  );
                }
              }}
              onBlur={() => {
                setFallbackPlaylistDropDownOpen(false);
              }}
              onChange={(_, selected) => {
                handleSetState({
                  editorialPlaylist: selected,
                  playerEditorialPlaylistId: selected?.id ?? null,
                });
                setFallbackPlaylistDropDownOpen(false);
              }}
              onInputChange={(_, searchText) => {
                if (activeTabId === PLAYBACK_TAB) {
                  dispatch(
                    getPlayerEditorialPlaylistsOptionsAction({
                      publisherId: publisher?.id,
                      searchText,
                    }),
                  );
                }
              }}
              optionLabelKey="title"
              optionValueKey="id"
              renderInput={(params) => <TextField {...params} value="" />}
            />
          </FormRow>
          {!!playerEditorialPlaylist?.clips?.length && (
            <FormRow label fullWidth>
              <Carousel slideDimensions={TYPE_E} playlist={playerEditorialPlaylist?.clips} slidesToShow={4} />
            </FormRow>
          )}
        </>
      )}
    </FormSection>
  );
}

export default PlaybackTab;
