import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { VIDEO_ACCESS_TARGETING } from '@/modules/@common/acl/constants';
import { TYPE_INTELLIGENT, TYPE_INTELLIGENT_AMP, TYPE_VERTICAL } from '@/modules/@common/constants/playerTypes';
import { REDUX_ERROR_PROP_NAME } from '@/modules/@common/Form/constants';
import { TYPE_WARNING } from '@/modules/@common/notify/constants';
import {
  ALL_FEEDS_ID,
  ALL_FEEDS_NAME,
  ALL_LANGUAGES_NAME,
  ALL_LANGUAGES_VALUE,
} from '@/modules/players/Editor/constants';

import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import { notifyAction } from '@/modules/@common/notify/redux/slices';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';
import { isStoriesTypes } from '@/modules/players/Editor/helpers';
import * as playerSelectors from '@/modules/players/Editor/redux/selectors';
import {
  getPlayerFeedsOptionsAction,
  removeErrorByPropAction,
  setAction,
  setActiveTabIdAction,
  setErrorByPropAction,
  setScrollToFieldNameAction,
  validateSingleField,
} from '@/modules/players/Editor/redux/slices';

import { FormRow, FormSection, useFormSettings } from '@/modules/@common/Form';
import TagsFilter from './TagsFilter/TagsFilter';
import { Autocomplete, Divider, List, ListItem, Switch, TextField } from '@/mui/components';

function ContentFiltersTab() {
  const { size } = useFormSettings();
  const dispatch = useDispatch();

  const userPermissions = useSelector(getUserPermissionsSelector);

  const id = useSelector(playerSelectors.idSelector);

  const playerType = useSelector(playerSelectors.playerTypeSelector);

  const publisher = useSelector(playerSelectors.publisherSelector);

  const useDefaultContentOwner = useSelector(playerSelectors.useDefaultContentOwnerSelector);

  const playerContentOwnerFeeds = useSelector(playerSelectors.playerContentOwnerFeedsSelector);
  const playerContentOwnerFeedsOptions = useSelector(playerSelectors.playerContentOwnerFeedsOptionsSelector);
  const allFeeds = useSelector(playerSelectors.allFeedsSelector);

  const playerFeedLanguages = useSelector(playerSelectors.playerFeedLanguagesSelector);
  const feedLanguagesOptions = useSelector(playerSelectors.feedLanguagesOptionsSelector);

  const playerBrandSafeties = useSelector(playerSelectors.playerBrandSafetiesSelector);
  const brandSafetiesOptions = useSelector(playerSelectors.playerBrandSafetiesOptionsSelector);
  const enableVideoTargeting = useSelector(playerSelectors.enableVideoTargetingSelector);
  const videoFormatByDevice = useSelector(playerSelectors.videoFormatByDeviceSelector);

  const scheme = useSelector(playerSelectors.schemeSelector);

  const [sourcesDropDownOpen, setSourcesDropDownOpen] = useState(false);

  const showOnlySources = isStoriesTypes(playerType?.id);

  const isEnableVideoTargetingActive = hasPermission(VIDEO_ACCESS_TARGETING, userPermissions);
  const shouldShowEnableVideoTargetingControl = [TYPE_INTELLIGENT, TYPE_INTELLIGENT_AMP, TYPE_VERTICAL].includes(
    playerType?.id,
  );

  const autoSelectVideoLayooutByDevice = [TYPE_INTELLIGENT, TYPE_VERTICAL].includes(playerType?.id);

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

  const isActiveSyndicatedContent = () =>
    publisher && (publisher.includePublicContent || publisher.publisherContentOwners?.length);

  const handleChangeFeeds = (selected) => {
    if (!allFeeds && selected.some((f) => f.id === ALL_FEEDS_ID)) {
      handleSetState({
        allFeeds: 1, // true
        playerContentOwnerFeeds: [{ name: ALL_FEEDS_NAME, id: ALL_FEEDS_ID }],
        playerContentOwnerFeedsOptions: playerContentOwnerFeeds.filter((f) => f.id !== ALL_FEEDS_ID),
      });
    } else {
      const filteredSelected = selected.filter((f) => f.id !== ALL_FEEDS_ID);
      handleSetState({
        playerContentOwnerFeeds: filteredSelected,
        allFeeds: 0,
      });
    }
  };

  const isAllLanguagesSelected = playerFeedLanguages.length === feedLanguagesOptions.length;
  const feedLanguagesMultiSelectValue = isAllLanguagesSelected
    ? [{ name: ALL_LANGUAGES_NAME, value: ALL_LANGUAGES_VALUE }]
    : playerFeedLanguages;
  const feedLanguagesMultiSelectOptions = [
    ...(!isAllLanguagesSelected ? [{ name: ALL_LANGUAGES_NAME, value: ALL_LANGUAGES_VALUE }] : []),
    ...feedLanguagesOptions,
  ];

  const handleChangeLanguages = (selected) => {
    if (!isAllLanguagesSelected && selected.some((l) => l.value === ALL_LANGUAGES_VALUE)) {
      handleSetState({ playerFeedLanguages: feedLanguagesOptions });
    } else {
      const filteredSelected = selected.filter((l) => l.value !== ALL_LANGUAGES_VALUE);
      handleSetState({ playerFeedLanguages: filteredSelected });
    }
  };

  // set default enabledVideoTargetingFlag state
  // when user create player and has access to video target in account
  useEffect(() => {
    if (!id && isEnableVideoTargetingActive && shouldShowEnableVideoTargetingControl) {
      dispatch(setAction({ enableVideoTargeting: true }));
    }
  }, [id, isEnableVideoTargetingActive, shouldShowEnableVideoTargetingControl]);

  return (
    <FormSection>
      {!showOnlySources && (
        <FormRow label="Use AnyClip`s Syndicated content" tooltip="Use AnyClip’s Library.">
          <Switch
            color="primary"
            size={size}
            disabled={!isActiveSyndicatedContent()}
            checked={!!useDefaultContentOwner}
            onChange={({ target }) => {
              handleSetState({
                useDefaultContentOwner: target.checked ? 1 : 0,
              });
              if (target.checked) {
                dispatch(removeErrorByPropAction(['playerContentOwnerFeeds']));
              }
            }}
          />
        </FormRow>
      )}
      <FormRow label="Account Sources">
        <Autocomplete
          open={sourcesDropDownOpen}
          size={size}
          multiple
          filterSelectedOptions
          disableCloseOnSelect
          value={allFeeds ? [{ name: ALL_FEEDS_NAME, id: ALL_FEEDS_ID }] : playerContentOwnerFeeds}
          options={playerContentOwnerFeedsOptions}
          loading={!playerContentOwnerFeedsOptions}
          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 {
              setSourcesDropDownOpen(true);
              dispatch(
                getPlayerFeedsOptionsAction({
                  search: '',
                  publisherId: publisher?.id,
                  includePublicContent: publisher?.includePublicContent,
                }),
              );
            }
          }}
          onChange={(_, selected) => handleChangeFeeds(selected)}
          onBlur={() => {
            setSourcesDropDownOpen(false);
          }}
          onInputChange={(_, searchText) =>
            dispatch(
              getPlayerFeedsOptionsAction({
                search: searchText,
                publisherId: publisher?.id,
                includePublicContent: publisher?.includePublicContent,
              }),
            )
          }
          optionLabelKey="name"
          optionValueKey="id"
          renderInput={(params) => (
            <TextField
              {...params}
              {...getInputPropsByName(scheme, ['playerContentOwnerFeeds'], useDefaultContentOwner ? '' : 'Required')}
              onFocus={() => dispatch(removeErrorByPropAction(['playerContentOwnerFeeds']))}
            />
          )}
        />
      </FormRow>
      {!showOnlySources && (
        <>
          <FormRow
            label="Allowed Brand Safety Categories"
            tooltip={
              'Videos with the selected brand safety categories would\n' +
              'be eligible to play. If left empty, any video with any type of brand\n' +
              'safety category flag would be blocked from playing. This does not\n' +
              ' apply for videos that were chosen for a manually curated playlist.'
            }
          >
            <Autocomplete
              size={size}
              multiple
              filterSelectedOptions
              disableCloseOnSelect
              value={playerBrandSafeties ?? []}
              options={brandSafetiesOptions}
              optionLabelKey="termUi"
              optionValueKey="termId"
              onChange={(_, selected) => handleSetState({ playerBrandSafeties: selected })}
              renderInput={(params) => (
                <TextField {...params} variant="outlined" placeholder="Choose allowed brand safety categories" />
              )}
            />
          </FormRow>

          <FormRow label="Allowed Languages" fullWidth>
            <Autocomplete
              size={size}
              multiple
              filterSelectedOptions
              disableCloseOnSelect
              value={feedLanguagesMultiSelectValue}
              options={feedLanguagesMultiSelectOptions}
              optionLabelKey="name"
              optionValueKey="lang"
              onChange={(_, selected) => handleChangeLanguages(selected)}
              renderInput={(params) => (
                <TextField
                  {...params}
                  value=""
                  variant="outlined"
                  {...getInputPropsByName(scheme, ['playerFeedLanguages'])}
                  onFocus={() => dispatch(removeErrorByPropAction(['playerFeedLanguages']))}
                />
              )}
            />
          </FormRow>

          {shouldShowEnableVideoTargetingControl && (
            <FormRow
              label="Video Targeting"
              tooltip="Video targeting must be enabled so videos with active
            targeting rules will be eligible to play on this player."
            >
              <Switch
                color="primary"
                size={size}
                disabled={!isEnableVideoTargetingActive}
                checked={enableVideoTargeting}
                onChange={({ target }) => {
                  handleSetState({
                    enableVideoTargeting: target.checked,
                  });
                }}
              />
            </FormRow>
          )}
          {autoSelectVideoLayooutByDevice && (
            <FormRow
              label="Auto-Select Video Format by Device"
              tooltip="Auto-selects vertical or horizontal content based on device, if both formats are available.
              For best results, use with 'Dynamic Aspect Ratio'"
            >
              <Switch
                color="primary"
                size={size}
                checked={videoFormatByDevice}
                onChange={({ target }) => {
                  handleSetState({
                    videoFormatByDevice: target.checked,
                  });
                }}
              />
            </FormRow>
          )}
          <FormRow
            label=" Tags Filter"
            tooltip={
              <>
                Use this tool to filter in/out videos based on the system and custom tags. Relationship between tags in
                the table:
                <List listStyle="initial" disablePadding dense>
                  <ListItem disablePadding dense>
                    Within the same Tag Type:
                    <List listStyle="initial" disablePadding dense>
                      <ListItem disablePadding dense>
                        If you have multiple tags set to &apos;Include&apos;, the relationship is &apos;OR&apos;. In
                        other words, at least one tag needs to exist for the video to be eligible to play.
                      </ListItem>
                      <ListItem disablePadding dense>
                        If you have multiple tags set to &apos;Exclude&apos;, the relationship is &apos;AND&apos;. This
                        means that if at least one tag exists, the video would not be eligible to play.
                      </ListItem>
                      <ListItem disablePadding dense>
                        If you have both &apos;Include&apos; and &apos;Exclude&apos; tags in the same category, all
                        &apos;Exclude&apos; tags must be respected, and at least one &apos;Include&apos; tag needs to
                        exist for the video to be eligible to play.
                      </ListItem>
                    </List>
                  </ListItem>
                  <ListItem disablePadding dense>
                    Between different Tag Types:
                    <List listStyle="initial" disablePadding dense>
                      <ListItem disablePadding dense>
                        The relationship is always &apos;AND&apos;. This means that only videos that meet the above
                        criteria in each of the types would be eligible to play.
                      </ListItem>
                    </List>
                  </ListItem>
                </List>
              </>
            }
          />
          <Divider flexItem />
          <TagsFilter categories />
        </>
      )}
    </FormSection>
  );
}

export default ContentFiltersTab;
