import React, { useEffect, useMemo } 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 { TYPE_ERROR } from '@/modules/@common/notify/constants';
import {
  ASPECT_RATIO,
  PLAYER_LOGO_INVALID_FILE_TYPE,
  PLAYER_LOGO_MAX_FILE_SIZE,
  PLAYER_WIDTH_UNITS_PERCENT,
  VERTICAL_FULLSCREEN_TITLE_TIMELINE_OPTIONS,
  VERTICAL_FULLSCREEN_TITLE_TIMELINE_VISIBILITY_ALWAYS,
} from '@/modules/players/Editor/constants';

import * as playerSelectors from '../../../redux/selectors';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import { isValidUrl } from '@/modules/@common/helpers/string';
import { showNotificationAction } from '@/modules/layout/redux/slices';
import {
  getCreateControlsOptions,
  getCreateSocialFeaturesOptions,
  multiSelectHandler,
  setStateHandler,
} from '@/modules/players/Editor/components/Tabs/LookAndFeelTab/helpers/handlers';
import {
  castToInt,
  isAmpTypes,
  isIntelligentAmpType,
  isIntelligentType,
  isStoriesTypes,
  isVerticalType,
} from '@/modules/players/Editor/helpers';
import {
  removeErrorByPropAction,
  setAction,
  setObjectValuesAction,
  setOppositeAction,
} from '@/modules/players/Editor/redux/slices';

import {
  FormGroup,
  FormGroupTitle,
  FormImageUploader,
  FormRow,
  FormRowItem,
  FormSection,
  useFormSettings,
} from '@/modules/@common/Form';
import {
  Autocomplete,
  List,
  ListItem,
  MenuItem,
  Select,
  Switch,
  TextField,
  TextFieldColorPicker,
  ToggleButton,
  ToggleButtonGroup,
  Typography,
} from '@/mui/components';

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

  const playerType = useSelector(playerSelectors.playerTypeSelector);
  const playerLreLogo = useSelector(playerSelectors.playerLreLogoSelector);

  const playerWidthUnitOptions = useSelector(playerSelectors.playerWidthUnitOptionsSelector);
  const playerWidthUnit = useSelector(playerSelectors.playerWidthUnitSelector);
  const playerWidth = useSelector(playerSelectors.playerWidthSelector);
  const playerWidthMobileUnit = useSelector(playerSelectors.playerWidthMobileUnitSelector);
  const playerWidthMobile = useSelector(playerSelectors.playerWidthMobileSelector);

  const playerAspectRatio = useSelector(playerSelectors.playerAspectRatioSelector);
  const playerAspectRatioOptions = useSelector(playerSelectors.playerAspectRatioOptionsSelector);
  const playerDynamicAspectRatioOptions = useSelector(playerSelectors.playerDynamicAspectRatioOptionsSelector);

  const brandingLeft = useSelector(playerSelectors.brandingLeftSelector);

  const carouselEnabled = useSelector(playerSelectors.carouselEnabledSelector);
  const carouselEnabledMobile = useSelector(playerSelectors.carouselEnabledMobileSelector);

  const carouselOrientation = useSelector(playerSelectors.carouselOrientationSelector);
  const carouselOrientationOptions = useSelector(playerSelectors.carouselOrientationOptionsSelector);

  const brandingRight = useSelector(playerSelectors.brandingRightSelector);
  const brandingRightDefault = useSelector(playerSelectors.brandingRightDefaultSelector);

  const closedCaptioning = useSelector(playerSelectors.closedCaptioningSelector);
  const closedCaptioningOptions = useSelector(playerSelectors.closedCaptioningOptionsSelector);

  const verticalFullscreenTitleTimelineVisibility = useSelector(
    playerSelectors.verticalFullscreenTitleTimelineVisibilitySelector,
  );

  const swipeAnimation = useSelector(playerSelectors.swipeAnimationSelector);

  const swipeAnimationMaxVisits = useSelector(playerSelectors.swipeAnimationMaxVisitsSelector);
  const swipeAnimationDuration = useSelector(playerSelectors.swipeAnimationDurationSelector);

  const videoResolutionControl = useSelector(playerSelectors.videoResolutionControlSelector);
  const playbackSpeedControl = useSelector(playerSelectors.playbackSpeedControlSelector);
  const fullScreen = useSelector(playerSelectors.fullScreenSelector);
  const chapteringMenuNavigation = useSelector(playerSelectors.chapteringMenuNavigationSelector);
  const theaterMode = useSelector(playerSelectors.theaterModeSelector);
  const ffRewind = useSelector(playerSelectors.ffRewindSelector);

  const socialViewButton = useSelector(playerSelectors.socialViewButtonSelector);
  const socialLikeButton = useSelector(playerSelectors.socialLikeButtonSelector);

  const xRayCampaignsEnabled = useSelector(playerSelectors.xRayCampaignsEnabledSelector);

  const leftBrandingColor = useSelector(playerSelectors.leftBrandingColorSelector);
  const leftBrandingSize = useSelector(playerSelectors.leftBrandingSizeSelector);
  const leftBrandingSizeOptions = useSelector(playerSelectors.leftBrandingSizeOptionsSelector);
  const progressBarColor = useSelector(playerSelectors.progressBarColorSelector);
  const timestampTooltipColor = useSelector(playerSelectors.timestampTooltipColorSelector);
  const volumeBarColor = useSelector(playerSelectors.volumeBarColorSelector);
  const settingsMenuHighlightColor = useSelector(playerSelectors.settingsMenuHighlightColorSelector);

  const scheme = useSelector(playerSelectors.schemeSelector);

  const carouselValues = useMemo(() => {
    const state = { carouselEnabled, carouselEnabledMobile };
    return Object.entries(state)
      .filter(([, value]) => value !== null && value)
      .map(([key]) => key);
  }, [carouselEnabled, carouselEnabledMobile]);

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

  useEffect(() => {
    if (!id && !copyFromId && isVertical) {
      dispatch(
        setAction({
          playerAspectRatio: playerAspectRatioOptions.find((ratio) => ratio.isDefaultForVertical)?.value,
          carouselEnabled: 0,
          carouselEnabledMobile: 0,
        }),
      );
    }
  }, [playerTypeId, playerAspectRatioOptions]);

  useEffect(() => {
    if (!id && !copyFromId && isStories) {
      dispatch(
        setAction({
          brandingLeft: '',
          brandingRight: '',
        }),
      );
    }
  }, [playerTypeId, brandingRightDefault]);

  const showSocialFeatures = !isStories;
  const showOnlyFullScreenControl = isStories;
  const showBranding = !isStories;
  const showClosedCaptions = !isStories;
  const showPlayerControls = !isStories;
  const showColorAndSizeCustomization = !isStories;
  const showCarousel = !isStories && !isIntelligentAmp && !isVertical;
  const showXRayCampaigns = !isStories && !isIntelligentAmp;
  const showTheaterMode = !isIntelligentAmp && !isVertical;
  const showPlayerMobileSize = isVertical || isIntelligen;

  const disabledPlayerWithUnit = isAmp;
  const disabledAspectRatio = isVertical;

  const disabledCarousel = !playerAspectRatioOptions.find(
    (option) => option.value === playerAspectRatio && option.withCarousel,
  );

  const handleSetState = (fieldName, value, additionalData) =>
    setStateHandler(fieldName, value, dispatch, additionalData);

  const handleMultiSelect = (selectedArr, options) => multiSelectHandler(selectedArr, options, dispatch);
  const handleChangeColor = (fieldName, { rgb, hex }) => {
    const color$ = rgb.a === 1 ? hex : `rgba(${rgb.r},${rgb.g},${rgb.b},${rgb.a})`;
    handleSetState(fieldName, color$);
  };

  const controlsOptions = getCreateControlsOptions({
    ...(!showOnlyFullScreenControl && { videoResolutionControl }),
    ...(!showOnlyFullScreenControl && { playbackSpeedControl }),
    fullScreen,
    ...(!showOnlyFullScreenControl && { chapteringMenuNavigation }),
    ...(!showOnlyFullScreenControl && { ffRewind }),
    ...(showTheaterMode && !showOnlyFullScreenControl && { theaterMode }),
  });

  const socialFeaturesOptions = getCreateSocialFeaturesOptions({
    socialViewButton,
    socialLikeButton,
  });

  return (
    <>
      <FormSection>
        <FormRow
          label="Player Logo"
          tooltip="The AnyClip Logo will be shown as a default at the top right of the player,
          leading to anyclip.com upon a click on it. If replaced, your logo will be presented as a 40X40 image."
        >
          <FormImageUploader
            image={playerLreLogo?.file}
            accept=".jpeg, .jpg, .png"
            restrictionMessage={'JPEG, PNG. Max file size 500kb.\nMin dimensions: 141x141'}
            onValidate={(file) => {
              const allowedFormats = ['image/jpeg', 'image/png'];

              if (!allowedFormats.includes(file.type)) {
                dispatch(
                  showNotificationAction({
                    key: PLAYER_LOGO_INVALID_FILE_TYPE,
                    type: TYPE_ERROR,
                    message: PLAYER_LOGO_INVALID_FILE_TYPE,
                  }),
                );
                return false;
              }

              const maxFileSize = 500 * 1024; // 500KB
              if (file.size > maxFileSize) {
                dispatch(
                  showNotificationAction({
                    key: PLAYER_LOGO_MAX_FILE_SIZE,
                    type: TYPE_ERROR,
                    message: PLAYER_LOGO_MAX_FILE_SIZE,
                  }),
                );

                return false;
              }

              return true;
            }}
            onLoad={(event, file, fileResult) => {
              dispatch(
                setObjectValuesAction({
                  playerLreLogo: {
                    file: fileResult,
                    enabled: 1,
                  },
                }),
              );
            }}
            onError={(event, file, error) => {
              dispatch(
                showNotificationAction({
                  key: error,
                  type: TYPE_ERROR,
                  message: error,
                }),
              );
            }}
            onRemove={() => {
              const linkShouldBeRemoved = playerLreLogo?.link && !isValidUrl(playerLreLogo?.link);
              dispatch(removeErrorByPropAction(['playerLreLogo.link']));
              dispatch(
                setObjectValuesAction({
                  playerLreLogo: {
                    enabled: 0,
                    file: '',
                    ...(linkShouldBeRemoved && { link: '' }),
                  },
                }),
              );
            }}
          />
        </FormRow>
        <FormRow label="Logo Landing URL">
          <TextField
            size={size}
            placeholder="Enter Logo Landing URL"
            value={playerLreLogo?.link}
            onChange={({ target }) =>
              handleSetState('link', target.value?.trim(), {
                playerLreLogo,
                objectName: 'playerLreLogo',
              })
            }
            {...getInputPropsByName(scheme, ['playerLreLogo.link'], playerLreLogo?.file ? 'Required' : '')}
            onFocus={() => dispatch(removeErrorByPropAction(['playerLreLogo.link']))}
          />
        </FormRow>
        <FormRow label={showPlayerMobileSize ? 'Player Size Desktop' : 'Player Size'}>
          <Select
            size={size}
            disabled={disabledPlayerWithUnit}
            value={playerWidthUnit}
            onChange={({ target }) =>
              handleSetState('playerWidthUnit', target.value, {
                playerWidthUnitOptions,
              })
            }
          >
            {playerWidthUnitOptions.map(({ value, label }) => (
              <MenuItem key={value} value={value}>
                {label}
              </MenuItem>
            ))}
          </Select>
          <FormRowItem>
            <Typography variant="body2">Width</Typography>
          </FormRowItem>
          <FormRowItem itemsInRow={1}>
            <TextField
              value={playerWidth}
              size={size}
              disabled={playerWidthUnit === PLAYER_WIDTH_UNITS_PERCENT}
              onChange={({ target }) =>
                dispatch(
                  setAction({
                    playerWidth: target.value,
                  }),
                )
              }
              onBlur={({ target }) =>
                dispatch(
                  setAction({
                    playerWidth: castToInt(target.value),
                  }),
                )
              }
              {...getInputPropsByName(scheme, ['playerWidth'])}
              onFocus={() => dispatch(removeErrorByPropAction(['playerWidth']))}
            />
          </FormRowItem>
        </FormRow>
        {showPlayerMobileSize && (
          <>
            <FormRow label="Player Size Mobile">
              <Select
                size={size}
                disabled={disabledPlayerWithUnit}
                value={playerWidthMobileUnit}
                onChange={({ target }) =>
                  handleSetState('playerWidthMobileUnit', target.value, {
                    playerWidthUnitOptions,
                  })
                }
              >
                {playerWidthUnitOptions.map(({ value, label }) => (
                  <MenuItem key={value} value={value}>
                    {label}
                  </MenuItem>
                ))}
              </Select>
              <FormRowItem>
                <Typography variant="body2">Width</Typography>
              </FormRowItem>
              <FormRowItem itemsInRow={1}>
                <TextField
                  value={playerWidthMobile}
                  size={size}
                  disabled={playerWidthMobileUnit === PLAYER_WIDTH_UNITS_PERCENT}
                  onChange={({ target }) =>
                    dispatch(
                      setAction({
                        playerWidthMobile: target.value,
                      }),
                    )
                  }
                  onBlur={({ target }) =>
                    dispatch(
                      setAction({
                        playerWidthMobile: castToInt(target.value),
                      }),
                    )
                  }
                  {...getInputPropsByName(scheme, ['playerWidthMobile'])}
                  onFocus={() => dispatch(removeErrorByPropAction(['playerWidthMobile']))}
                />
              </FormRowItem>
            </FormRow>
            <FormRow
              label="Aspect Ratio"
              tooltip="Selecting 'Dynamic Aspect Ratio' allows the player to automatically use horizontal layout on desktop and vertical on mobile. Recommended only when both content formats are available."
            >
              <Select
                size={size}
                value={playerAspectRatio}
                onChange={({ target }) =>
                  handleSetState('playerAspectRatio', target.value, {
                    playerDynamicAspectRatioOptions,
                    carouselOrientationOptions,
                  })
                }
              >
                {isVertical
                  ? playerDynamicAspectRatioOptions
                      .filter(({ value }) => [ASPECT_RATIO.RATIO_9_16, ASPECT_RATIO.DYNAMIC].includes(value))
                      .map(({ value, label }) => (
                        <MenuItem key={value} value={value}>
                          {label}
                        </MenuItem>
                      ))
                  : playerDynamicAspectRatioOptions.map(({ value, label }) => (
                      <MenuItem key={value} value={value}>
                        {label}
                      </MenuItem>
                    ))}
              </Select>
            </FormRow>
          </>
        )}
        {!showPlayerMobileSize && (
          <FormRow label="Aspect Ratio">
            <Select
              size={size}
              disabled={disabledAspectRatio}
              value={playerAspectRatio}
              onChange={({ target }) =>
                handleSetState('playerAspectRatio', target.value, {
                  playerAspectRatioOptions,
                  carouselOrientationOptions,
                })
              }
            >
              {playerAspectRatioOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          </FormRow>
        )}
        {showBranding && (
          <FormRow
            label="Player Title"
            tooltip="This line appears above the top-left corner of the player. Can be left empty."
          >
            <TextField
              size={size}
              value={brandingLeft}
              onChange={({ target }) => handleSetState('brandingLeft', target.value)}
            />
          </FormRow>
        )}
        {showCarousel && (
          <>
            <FormRow label="Carousel" tooltip="Carousel is supported for Aspect Ratio ‘16:9’ only.">
              <ToggleButtonGroup
                disabled={disabledCarousel}
                exclusive
                size={size}
                onChange={(_, newValue) => {
                  dispatch(setOppositeAction({ [newValue]: newValue }));
                }}
                value={carouselValues}
              >
                <ToggleButton value="carouselEnabled">
                  <Monitor />
                </ToggleButton>
                <ToggleButton value="carouselEnabledMobile">
                  <PhoneIphone />
                </ToggleButton>
              </ToggleButtonGroup>
            </FormRow>
            <FormRow label="Desktop Carousel Type">
              <Select
                size={size}
                disabled={!carouselEnabled}
                value={carouselOrientation}
                onChange={({ target }) => handleSetState('carouselOrientation', target.value)}
              >
                {carouselOrientationOptions.map(({ value, label }) => (
                  <MenuItem key={value} value={value}>
                    {label}
                  </MenuItem>
                ))}
              </Select>
            </FormRow>
          </>
        )}
        {showBranding && (
          <FormRow
            label="Powered by AnyClip"
            tooltip="This line appears above the top-right corner of the player. Can be disabled"
          >
            <Switch
              color="primary"
              size={size}
              checked={!!brandingRight}
              onChange={({ target }) => handleSetState('brandingRight', target.checked ? brandingRightDefault : '')}
            />
          </FormRow>
        )}
        {showClosedCaptions && (
          <FormRow label="Closed Captions">
            <Select
              size={size}
              value={closedCaptioning}
              onChange={({ target }) => handleSetState('closedCaptioning', target.value)}
            >
              {closedCaptioningOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          </FormRow>
        )}
        {showPlayerControls && (
          <FormRow
            label="Player Controls"
            tooltip={
              <>
                Please note the following limitations for two features:
                <List listStyle="initial" disablePadding dense>
                  <ListItem disablePadding dense>
                    Chaptering is accessible exclusively for videos in which the feature has been activated.
                  </ListItem>
                  <ListItem disablePadding dense>
                    Theater Mode is exclusively compatible with desktop devices.
                  </ListItem>
                </List>
              </>
            }
          >
            <Autocomplete
              size={size}
              id="controls"
              multiple
              filterSelectedOptions
              value={controlsOptions.filter((control) => control.value)}
              options={controlsOptions}
              onChange={(_, selected) => handleMultiSelect(selected, controlsOptions)}
              renderInput={(params) => <TextField {...params} />}
            />
          </FormRow>
        )}
        {showSocialFeatures && (
          <FormRow label="Social Features">
            <Autocomplete
              size={size}
              id="features"
              multiple
              filterSelectedOptions
              value={socialFeaturesOptions.filter((feature) => feature.value)}
              options={socialFeaturesOptions}
              onChange={(_, selected) => handleMultiSelect(selected, socialFeaturesOptions)}
              renderInput={(params) => <TextField {...params} />}
            />
          </FormRow>
        )}
        {isVertical && (
          <FormRow
            label="Title & Timeline Visibility"
            tooltip="This setting applies to the visibility of the title and timeline in full-screen mode only"
          >
            <Select
              size={size}
              value={verticalFullscreenTitleTimelineVisibility || VERTICAL_FULLSCREEN_TITLE_TIMELINE_VISIBILITY_ALWAYS}
              onChange={({ target }) => {
                handleSetState('verticalFullscreenTitleTimelineVisibility', target.value);
              }}
            >
              {VERTICAL_FULLSCREEN_TITLE_TIMELINE_OPTIONS.map(({ label, value }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          </FormRow>
        )}

        {isVertical && (
          <>
            <FormRow
              label='"Swipe Up for More" Animation'
              tooltip="Displays a brief 'Swipe Up for More' animation in full-screen mode on mobile devices, guiding users to swipe up for more videos. This animation appears only for the first few visits, based on the set limit."
            >
              <Switch
                size={size}
                color="primary"
                checked={!!swipeAnimation}
                onChange={({ target }) => {
                  const isChecked = target.checked;

                  handleSetState('swipeAnimation', target.checked);

                  if (isChecked) {
                    if (!swipeAnimationMaxVisits) {
                      handleSetState('swipeAnimationMaxVisits', 3);
                    }

                    if (!swipeAnimationDuration) {
                      handleSetState('swipeAnimationDuration', 5);
                    }
                  } else {
                    dispatch(removeErrorByPropAction(['swipeAnimationMaxVisits']));
                    dispatch(removeErrorByPropAction(['swipeAnimationDuration']));
                  }
                }}
              />
            </FormRow>

            {!!swipeAnimation && (
              <FormGroup>
                <FormRow label="Number of Visits">
                  <TextField
                    size={size}
                    value={swipeAnimationMaxVisits}
                    onChange={({ target }) => handleSetState('swipeAnimationMaxVisits', target.value)}
                    // onChange={({ target }) => handleSetState({
                    //   'swipeAnimationMaxVisits', target.value
                    // })}
                    onBlur={({ target }) => handleSetState('swipeAnimationMaxVisits', castToInt(target.value))}
                    {...getInputPropsByName(scheme, ['swipeAnimationMaxVisits'])}
                    onFocus={() => dispatch(removeErrorByPropAction(['swipeAnimationMaxVisits']))}
                  />
                </FormRow>

                <FormRow label="Animation Duration (Seconds)">
                  <TextField
                    size={size}
                    value={swipeAnimationDuration}
                    onChange={({ target }) => handleSetState('swipeAnimationDuration', target.value)}
                    onBlur={({ target }) => handleSetState('swipeAnimationDuration', castToInt(target.value))}
                    {...getInputPropsByName(scheme, ['swipeAnimationDuration'])}
                    onFocus={() => dispatch(removeErrorByPropAction(['swipeAnimationDuration']))}
                  />
                </FormRow>
              </FormGroup>
            )}
          </>
        )}

        {showXRayCampaigns && (
          <FormRow
            label="X-Ray Campaigns"
            tooltip={
              'Showcase multiple offers or calls-to-action with custom\n' +
              'graphic overlays and click-through capability in both live and on-demand video.\n' +
              'The campaigns should be created in the interaction section in the UI.\n' +
              'Please reach out to your AnyClip Customer Success Manager for more details.'
            }
          >
            <Switch
              color="primary"
              size={size}
              checked={!!xRayCampaignsEnabled}
              onChange={({ target }) => handleSetState('xRayCampaignsEnabled', target.checked ? 1 : 0)}
            />
          </FormRow>
        )}
        {showColorAndSizeCustomization && (
          <>
            <FormGroupTitle>Color & Size Customization</FormGroupTitle>
            <FormRow label="Player Title">
              <FormRowItem itemsInRow={4}>
                <Select
                  size={size}
                  value={leftBrandingSize}
                  onChange={({ target }) => handleSetState('leftBrandingSize', target.value)}
                >
                  {leftBrandingSizeOptions.map((size$) => (
                    <MenuItem key={`${size$}`} value={size$}>
                      {size$}
                      px
                    </MenuItem>
                  ))}
                </Select>
              </FormRowItem>
              <TextFieldColorPicker
                size={size}
                disableAlpha
                value={leftBrandingColor}
                onPickerChange={(color) => handleChangeColor('leftBrandingColor', color)}
              />
            </FormRow>
            <FormRow label="Progress Bar">
              <TextFieldColorPicker
                size={size}
                disableAlpha
                value={progressBarColor}
                onPickerChange={(color) => handleChangeColor('progressBarColor', color)}
              />
            </FormRow>
            <FormRow label="Timestamp Tooltip">
              <TextFieldColorPicker
                size={size}
                disableAlpha
                value={timestampTooltipColor}
                onPickerChange={(color) => handleChangeColor('timestampTooltipColor', color)}
              />
            </FormRow>
            <FormRow label="Volume line">
              <TextFieldColorPicker
                size={size}
                disableAlpha
                value={volumeBarColor}
                onPickerChange={(color) => handleChangeColor('volumeBarColor', color)}
              />
            </FormRow>
            <FormRow label="Settings Menu Highlight">
              <TextFieldColorPicker
                size={size}
                disableAlpha
                value={settingsMenuHighlightColor}
                onPickerChange={(color) => handleChangeColor('settingsMenuHighlightColor', color)}
              />
            </FormRow>
          </>
        )}
      </FormSection>
      {playerPreview}
    </>
  );
}

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

export default LookAndFeelTab;
