import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import dayjs from 'dayjs';
import customParseFormatPlugin from 'dayjs/plugin/customParseFormat';
import {
  ApiOutlined,
  FirstPageOutlined,
  FolderCopyOutlined,
  LastPageOutlined,
  LaunchOutlined,
  TimerOutlined,
} from '@mui/icons-material';

import { TYPE_WARNING } from '@/modules/@common/notify/constants';
import { EDITORIAL_PAGE } from '@/modules/@common/router/constants';
import {
  DEVICE_LIST,
  PLAYER_SIZE_LARGE,
  PLAYER_SIZE_MEDIUM,
  PLAYER_SIZE_SMALL,
  PLAYER_SIZE_X_SMALL,
  STATUS_ACTIVE,
  STATUS_DISABLED,
  TARGET_PLACEMENT_TYPE_PLAYER,
  TARGET_PLACEMENT_TYPE_VIDEO,
  TARGET_PLACEMENT_TYPE_WATCH,
  TRIGGER_API,
  TRIGGER_BEGINNING,
  TRIGGER_END,
  TRIGGER_OPTIONS,
  TRIGGER_PERIOD_OPTIONS,
  TRIGGER_TIMESTAMP,
} from '@/modules/forms/editor/constants';

import {
  getBrandSafetyOptionsAction,
  getBrandsOptionsAction,
  getDomainOptionsAction,
  getGeoOptionsAction,
  getKeywordsOptionsAction,
  getLabelOptionsAction,
  getPeopleOptionsAction,
  getPlayerOptionsAction,
  getVideoOptionsAction,
  getWatchOptionsAction,
  removeErrorByPropAction,
  setActiveTabIdAction,
  setErrorByPropAction,
  setFieldAction,
  setScrollToFieldNameAction,
  validateSingleField,
} from '../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import copyToClipboard from '@/modules/@common/helpers/copy';
import { notifyAction } from '@/modules/@common/notify/redux/slices';
import * as selectors from '@/modules/forms/editor/redux/selectors';
import useGetReadOnlyStatus from '@/modules/forms/helpers/useGetReadOnlyStatus';

import { FormGroup, FormGroupTitle, FormRow, FormRowItem, FormSection, useFormSettings } from '@/modules/@common/Form';
import ActionAutocomplete from './components/ActionAutocomplete';
import ActionIAB from './components/ActionIAB';
import {
  Autocomplete,
  Button,
  Chip,
  MenuItem,
  Select,
  Switch,
  TextField,
  TimePicker,
  ToggleButton,
  ToggleButtonGroup,
} from '@/mui/components';

dayjs.extend(customParseFormatPlugin);

const getApiScript = (id) => `anyclip.widgets[0].showForm(${id})`;

const TRIGGER_ICONS = {
  [TRIGGER_TIMESTAMP]: TimerOutlined,
  [TRIGGER_BEGINNING]: FirstPageOutlined,
  [TRIGGER_END]: LastPageOutlined,
  [TRIGGER_API]: ApiOutlined,
};

function TriggerTab() {
  const { size } = useFormSettings();
  const dispatch = useDispatch();
  const trigger = useSelector(selectors.triggerSelector);
  const autocomplete = useSelector(selectors.autocompleteSelector);
  const id = useSelector(selectors.idSelector);
  const status = useSelector(selectors.statusSelector);
  const scheme = useSelector(selectors.schemeSelector);
  const site = useSelector(selectors.siteSelector);

  const readOnly = useGetReadOnlyStatus(status);

  const isTriggerActionApi = trigger.triggerAction === TRIGGER_API;

  const handleSetField = (value) =>
    dispatch(
      setFieldAction({
        trigger: {
          ...trigger,
          ...value,
        },
      }),
    );

  const handleGetTextOptionsWhenOpen = (getOptionsAction) => {
    dispatch(
      setFieldAction({
        autocomplete: {
          ...autocomplete,
          textOptions: null,
        },
      }),
    );

    dispatch(getOptionsAction(''));
  };

  const handleWatchOptionsWhenOpen = (getOptionsAction) => {
    dispatch(
      setFieldAction({
        autocomplete: {
          ...autocomplete,
          watchOptions: null,
        },
      }),
    );

    dispatch(getOptionsAction(''));
  };

  const handleSetWatch = (watch) => {
    handleSetField({
      watch,
      watchChannel: null,
      playerName: null,
    });

    dispatch(
      setFieldAction({
        autocomplete: {
          ...autocomplete,
          watchChannelOptions: watch?.channels,
        },
      }),
    );
  };

  const handleSetWatchChannel = (watchChannel) => {
    handleSetField({
      watchChannel,
    });
  };

  const handleSetPlayer = (playerName) => {
    handleSetField({
      playerName,
      watch: null,
      watchChannel: null,
    });
  };

  useEffect(() => {
    if (trigger.watch && !autocomplete.watchOptions) {
      dispatch(getWatchOptionsAction(trigger.watch.label));
    } else if (trigger.watch && autocomplete.watchOptions && !autocomplete.watchChannelOptions) {
      const watch = autocomplete.watchOptions.find((entity) => entity.value === trigger.watch.value);
      dispatch(
        setFieldAction({
          autocomplete: {
            ...autocomplete,
            watchChannelOptions: watch.channels,
          },
        }),
      );
    }
  }, [trigger.watch, autocomplete.watchOptions, trigger.watchChannel, autocomplete.watchChannelOptions]);

  useEffect(() => {
    if (id && isTriggerActionApi) {
      handleSetField({
        triggerApiValue: getApiScript(id),
      });
    }
  }, [id, isTriggerActionApi]);

  return (
    <FormSection>
      <FormRow label="Enable Trigger">
        <Switch
          size={size}
          color="primary"
          checked={status === STATUS_ACTIVE}
          disabled={readOnly}
          onClick={() => {
            if (site) {
              dispatch(
                setFieldAction({
                  status: status !== STATUS_ACTIVE ? STATUS_ACTIVE : STATUS_DISABLED,
                }),
              );
            } else {
              const validation = validateSingleField('site', site);
              dispatch(setErrorByPropAction([validation]));
              dispatch(setActiveTabIdAction(validation.tabId));
              dispatch(setScrollToFieldNameAction(validation.fieldName));
              dispatch(
                notifyAction({
                  type: TYPE_WARNING,
                  message: 'Please select a Hub from the list',
                }),
              );
            }
          }}
        />
      </FormRow>
      {status === STATUS_ACTIVE && (
        <>
          <FormRow>
            <Select
              size={size}
              value={trigger.triggerAction}
              disabled={readOnly}
              onChange={({ target }) =>
                handleSetField({
                  triggerAction: target.value,
                })
              }
            >
              {TRIGGER_OPTIONS.map((option) => {
                const Icon = TRIGGER_ICONS[option.id];

                return (
                  <MenuItem value={option.id} key={option.id}>
                    <Chip variant="text" size={size} icon={<Icon />} color="neutral" label={option.name} />
                  </MenuItem>
                );
              })}
            </Select>
            {trigger.triggerAction === TRIGGER_TIMESTAMP && (
              <TimePicker
                slotProps={{
                  textField: {
                    size,
                  },
                }}
                // timer used as duration do not change behavior
                placeholder="00:00:00"
                value={dayjs(trigger.triggerTime, 'HH:mm:ss')}
                onChange={(triggerTime) => {
                  handleSetField({
                    triggerTime: dayjs(triggerTime).format('HH:mm:ss'),
                  });
                }}
                ampm={false}
                views={['hours', 'minutes', 'seconds']}
                format="HH:mm:ss"
                disabled={readOnly}
                {...getInputPropsByName(scheme, ['trigger.triggerTime'])}
              />
            )}
          </FormRow>
          <FormGroupTitle>{!isTriggerActionApi ? 'Select view limitations' : 'Copy to clipboard'}</FormGroupTitle>
          {isTriggerActionApi && (
            <FormRow justifyContent="flex-end">
              <TextField
                size={size}
                value={trigger.triggerApiValue}
                variant="outlined"
                multiline
                rows={6}
                placeholder="You need to save the form to enable the API"
                inputProps={{
                  readOnly: true,
                }}
                onChange={({ target }) => handleSetField({ triggerApiValue: target.value })}
              />
              <Button
                size={size}
                variant="text"
                color="neutral"
                disabled={readOnly || !id}
                onClick={() => copyToClipboard(trigger.triggerApiValue)}
                startIcon={<FolderCopyOutlined />}
              >
                Copy
              </Button>
            </FormRow>
          )}
          {!isTriggerActionApi && (
            <>
              <FormRow label="Do not display if the user already filled the form">
                <Switch
                  size={size}
                  color="primary"
                  checked={trigger.frequencyLimitsDisplayOnlyOnceSubmitted}
                  disabled={readOnly}
                  onChange={({ target }) =>
                    handleSetField({
                      frequencyLimitsDisplayOnlyOnceSubmitted: target.checked,
                    })
                  }
                />
              </FormRow>
              {[TRIGGER_END, TRIGGER_BEGINNING].includes(trigger.triggerAction) && (
                <FormRow
                  label="Display only once in a playlist or watch"
                  tooltip={
                    'Form will be displayed only once in a session to avoid showing\n' +
                    'it multiple times during a playlist or watch'
                  }
                >
                  <Switch
                    size={size}
                    color="primary"
                    checked={trigger.frequencyLimitsNotShowWhenOnceDisplayed}
                    disabled={readOnly}
                    onChange={({ target }) =>
                      handleSetField({
                        frequencyLimitsNotShowWhenOnceDisplayed: target.checked,
                      })
                    }
                  />
                </FormRow>
              )}
              <FormRow label="Limit the number of form views">
                <Switch
                  size={size}
                  color="primary"
                  checked={trigger.activateLimitsPeriod}
                  disabled={readOnly}
                  onChange={({ target }) => handleSetField({ activateLimitsPeriod: target.checked })}
                />
              </FormRow>
              {trigger.activateLimitsPeriod && (
                <FormGroup>
                  <FormRow label="Max form views per user">
                    <FormRowItem itemsInRow={4}>
                      <Select
                        size={size}
                        placeholder="Max View"
                        value={trigger.frequencyLimitsMaxViewPerUser}
                        disabled={readOnly}
                        onChange={({ target }) =>
                          handleSetField({
                            frequencyLimitsMaxViewPerUser: target.value,
                          })
                        }
                      >
                        {new Array(20).fill(1).map((item, index) => {
                          const value = index + 1;
                          return (
                            <MenuItem value={value} key={value}>
                              {value}
                            </MenuItem>
                          );
                        })}
                      </Select>
                    </FormRowItem>
                    <Select
                      size={size}
                      variant="outlined"
                      value={trigger.frequencyLimitsPeriod}
                      disabled={readOnly}
                      onChange={({ target }) => handleSetField({ frequencyLimitsPeriod: target.value })}
                    >
                      {TRIGGER_PERIOD_OPTIONS.map((item) => (
                        <MenuItem value={item.value} key={item.value}>
                          {item.label}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormRow>
                </FormGroup>
              )}
              <FormGroupTitle>Placement</FormGroupTitle>
              <FormRow label="Form targeting" tooltip="You must select at least a watch, a player or a video name">
                <ToggleButtonGroup
                  exclusive
                  color="primary"
                  value={trigger.targetPlacementType}
                  size={size}
                  fullWidth
                  disabled={readOnly}
                  onChange={(event, newAlignment) => {
                    if (newAlignment) {
                      handleSetField({
                        targetPlacementType: newAlignment,
                      });
                    }
                  }}
                >
                  <ToggleButton value={TARGET_PLACEMENT_TYPE_WATCH}>Watch</ToggleButton>
                  <ToggleButton value={TARGET_PLACEMENT_TYPE_PLAYER}>Player</ToggleButton>
                  <ToggleButton value={TARGET_PLACEMENT_TYPE_VIDEO}>Video</ToggleButton>
                </ToggleButtonGroup>
              </FormRow>
              {trigger.targetPlacementType === TARGET_PLACEMENT_TYPE_WATCH && (
                <>
                  <FormRow label="Watch Name">
                    <Autocomplete
                      size={size}
                      loading={!autocomplete.watchOptions}
                      options={autocomplete.watchOptions || []}
                      value={trigger.watch}
                      disabled={readOnly}
                      renderInput={(params) => (
                        <TextField
                          {...params}
                          {...getInputPropsByName(scheme, ['trigger.watch'])}
                          onFocus={() => dispatch(removeErrorByPropAction(['trigger.watch']))}
                          value=""
                          placeholder="Select Watch"
                          onChange={({ target }) => dispatch(getWatchOptionsAction(target.value))}
                        />
                      )}
                      onChange={(e, watch) => handleSetWatch(watch)}
                      onOpen={() => handleWatchOptionsWhenOpen(getWatchOptionsAction)}
                    />
                  </FormRow>
                  <FormRow label="Watch Channel">
                    <Autocomplete
                      size={size}
                      options={autocomplete.watchChannelOptions || []}
                      renderInput={(params) => (
                        <TextField
                          {...params}
                          data-id="watch-channel-input"
                          value=""
                          variant="outlined"
                          placeholder="Select Channel"
                        />
                      )}
                      value={trigger.watchChannel}
                      onChange={(e, watchChannel) => handleSetWatchChannel(watchChannel)}
                      disabled={readOnly || !trigger.watch}
                    />
                  </FormRow>
                </>
              )}
              {trigger.targetPlacementType === TARGET_PLACEMENT_TYPE_PLAYER && (
                <>
                  <FormRow label="Player Name">
                    <Autocomplete
                      size={size}
                      renderInput={(params) => (
                        <TextField
                          {...params}
                          {...getInputPropsByName(scheme, ['trigger.playerName'])}
                          onFocus={() => dispatch(removeErrorByPropAction(['trigger.playerName']))}
                          data-id="player-name-input"
                          value=""
                          variant="outlined"
                          placeholder="Select Player"
                        />
                      )}
                      options={autocomplete.textOptions || []}
                      loading={!autocomplete.textOptions}
                      value={trigger.playerName}
                      disabled={readOnly}
                      onChange={(e, playerName) => handleSetPlayer(playerName)}
                      onOpen={() => handleGetTextOptionsWhenOpen(getPlayerOptionsAction)}
                    />
                  </FormRow>
                  <FormRow label="Player size" tooltip="At least one must be selected">
                    <ToggleButtonGroup
                      equalWidth
                      size={size}
                      color="primary"
                      exclusive={false}
                      value={trigger.playerSize}
                      onChange={(event, newValue) => {
                        handleSetField({
                          playerSize: newValue,
                        });
                      }}
                    >
                      {[
                        {
                          title: 'XS',
                          id: PLAYER_SIZE_X_SMALL,
                        },
                        {
                          title: 'S',
                          id: PLAYER_SIZE_SMALL,
                        },
                        {
                          title: 'M',
                          id: PLAYER_SIZE_MEDIUM,
                        },
                        {
                          title: 'L',
                          id: PLAYER_SIZE_LARGE,
                        },
                      ].map((checkbox) => (
                        <ToggleButton
                          key={checkbox.id}
                          value={checkbox.id}
                          disabled={trigger.playerSize.includes(checkbox.id) && trigger.playerSize.length === 1}
                        >
                          {checkbox.title}
                        </ToggleButton>
                      ))}
                    </ToggleButtonGroup>
                  </FormRow>
                </>
              )}
              <FormRow label="Video Name" multiline>
                <Autocomplete
                  size={size}
                  renderInput={(params) => {
                    let fieldProps = {};

                    if (trigger.targetPlacementType === TARGET_PLACEMENT_TYPE_VIDEO) {
                      fieldProps = {
                        ...getInputPropsByName(scheme, ['trigger.video']),
                        onFocus: () => dispatch(removeErrorByPropAction(['trigger.video'])),
                      };
                    }

                    return (
                      <TextField
                        {...params}
                        {...fieldProps}
                        value=""
                        placeholder="Select Video"
                        onChange={({ target }) => dispatch(getVideoOptionsAction(target.value))}
                      />
                    );
                  }}
                  loading={!autocomplete.textOptions}
                  options={autocomplete.textOptions || []}
                  value={trigger.video}
                  disabled={readOnly}
                  onChange={(e, video) => handleSetField({ video })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getVideoOptionsAction)}
                />
                {trigger.video?.value && (
                  <Chip
                    size="xSmall"
                    color="neutral"
                    variant="text"
                    component="a"
                    href={`${EDITORIAL_PAGE.path}?videoId=${trigger.video.value}`}
                    target="_blank"
                    rel="noreferrer"
                    label={trigger.video.value}
                    deleteIcon={<LaunchOutlined />}
                    onDelete={() => null}
                    disabled={status === STATUS_DISABLED}
                  />
                )}
              </FormRow>
              <FormGroupTitle>Video Attributes</FormGroupTitle>
              <FormRow label="Category">
                <ActionIAB
                  size={size}
                  value={trigger.categories}
                  disabled={readOnly}
                  onChange={(categories) => handleSetField({ categories })}
                />
              </FormRow>
              <FormRow label="People">
                <ActionAutocomplete
                  size={size}
                  loading={!autocomplete.textOptions}
                  options={autocomplete.textOptions}
                  value={trigger.peoples}
                  disabled={readOnly}
                  onChange={(peoples) => handleSetField({ peoples })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getPeopleOptionsAction)}
                  onInputChange={(searchText) => dispatch(getPeopleOptionsAction(searchText))}
                />
              </FormRow>
              <FormRow label="Brands">
                <ActionAutocomplete
                  size={size}
                  loading={!autocomplete.textOptions}
                  options={autocomplete.textOptions}
                  value={trigger.brands}
                  disabled={readOnly}
                  onChange={(brands) => handleSetField({ brands })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getBrandsOptionsAction)}
                  onInputChange={(searchText) => dispatch(getBrandsOptionsAction(searchText))}
                />
              </FormRow>
              <FormRow label="Keywords">
                <ActionAutocomplete
                  size={size}
                  loading={!autocomplete.textOptions}
                  options={autocomplete.textOptions}
                  value={trigger.keywords}
                  disabled={readOnly}
                  onChange={(keywords) => handleSetField({ keywords })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getKeywordsOptionsAction)}
                  onInputChange={(searchText) => dispatch(getKeywordsOptionsAction(searchText))}
                />
              </FormRow>
              <FormRow label="Custom Tags">
                <ActionAutocomplete
                  size={size}
                  loading={!autocomplete.textOptions}
                  options={autocomplete.textOptions}
                  value={trigger.labels}
                  groupBy={(option) => option.groupBy}
                  disabled={readOnly}
                  onChange={(labels) => handleSetField({ labels })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getLabelOptionsAction)}
                  onInputChange={(searchText) => dispatch(getLabelOptionsAction(searchText))}
                />
              </FormRow>
              <FormRow label="Brand Safety">
                <ActionAutocomplete
                  size={size}
                  options={autocomplete.textOptions}
                  value={trigger.brandSafeties}
                  loading={!autocomplete.textOptions}
                  disabled={readOnly}
                  onChange={(brandSafeties) => handleSetField({ brandSafeties })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getBrandSafetyOptionsAction)}
                  onInputChange={(searchText) => dispatch(getBrandSafetyOptionsAction(searchText))}
                />
              </FormRow>
              <FormGroupTitle>Filters</FormGroupTitle>
              <FormRow label="Domain">
                <ActionAutocomplete
                  size={size}
                  value={trigger.domains}
                  loading={!autocomplete.textOptions}
                  options={autocomplete.textOptions}
                  disabled={readOnly}
                  onChange={(domains) => handleSetField({ domains })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getDomainOptionsAction)}
                  onInputChange={(searchText) => dispatch(getDomainOptionsAction(searchText))}
                />
              </FormRow>
              <FormRow label="Device">
                <ActionAutocomplete
                  size={size}
                  value={trigger.devices}
                  options={DEVICE_LIST}
                  disabled={readOnly}
                  onChange={(devices) => handleSetField({ devices })}
                />
              </FormRow>
              <FormRow label="Geo">
                <ActionAutocomplete
                  size={size}
                  value={trigger.geographies}
                  loading={!autocomplete.textOptions}
                  options={autocomplete.textOptions}
                  disabled={readOnly}
                  onChange={(geographies) => handleSetField({ geographies })}
                  onOpen={() => handleGetTextOptionsWhenOpen(getGeoOptionsAction)}
                />
              </FormRow>
            </>
          )}
        </>
      )}
    </FormSection>
  );
}

export default TriggerTab;
