import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import dayjs from 'dayjs';
import { Laptop, LaunchOutlined, Smartphone, Visibility, VisibilityOff } from '@mui/icons-material';

import { DEVICE_DESKTOP, DEVICE_MOBILE, PLAYER_LARGE, PLAYER_MEDIUM, PLAYER_SMALL } from '../../../constants';
import { EDITORIAL_PAGE } from '@/modules/@common/router/constants';

import * as selectors from '../../../redux/selectors';
import {
  getBrandSafetyOptionsAction,
  getBrandsOptionsAction,
  getDomainOptionsAction,
  getGeographyOptionsAction,
  getKeywordsOptionsAction,
  getLabelsOptionsAction,
  getPeopleOptionsAction,
  getPlayerOptionsAction,
  getVideoOptionsAction,
  getWatchOptionsAction,
  removeErrorByPropAction,
  setAction,
} from '../../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';

import ActionAutocomplete from '@/modules/@common/ActionAutocomplete';
import ActionIAB from '@/modules/@common/ActionIAB';
import { FormGroupTitle, FormRow, FormSection, useFormSettings } from '@/modules/@common/Form';
import { Autocomplete, Chip, Stack, TextField, TimePicker, ToggleButton, ToggleButtonGroup } from '@/mui/components';

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

  const hub = useSelector(selectors.hubSelector);

  const watch = useSelector(selectors.watchSelectors);
  const watchOptions = useSelector(selectors.watchOptionsSelectors);
  const watchChannel = useSelector(selectors.watchChannelSelectors);
  const watchChannelOptions = useSelector(selectors.watchChannelOptionsSelectors);
  const domains = useSelector(selectors.domainsSelectors);
  const domainOptions = useSelector(selectors.domainOptionsSelectors);
  const devices = useSelector(selectors.devicesSelectors);
  const geography = useSelector(selectors.geographySelectors);
  const geographyOptions = useSelector(selectors.geographyOptionsSelectors);
  const inview = useSelector(selectors.inviewSelectors);
  const notInview = useSelector(selectors.notInviewSelectors);
  const player = useSelector(selectors.playerSelectors);
  const playerOptions = useSelector(selectors.playerOptionsSelectors);
  const playerSizes = useSelector(selectors.playerSizesSelectors);
  const video = useSelector(selectors.videoSelector);
  const videoOptions = useSelector(selectors.videoOptionsSelector);
  const videoFromTimestamp = useSelector(selectors.videoFromTimestampSelector);
  const videoToTimestamp = useSelector(selectors.videoToTimestampSelector);
  const iabCategories = useSelector(selectors.iabCategoriesSelector);
  const people = useSelector(selectors.peopleSelector);
  const peopleOptions = useSelector(selectors.peopleOptionsSelector);
  const brands = useSelector(selectors.brandsSelector);
  const brandsOptions = useSelector(selectors.brandsOptionsSelector);
  const keywords = useSelector(selectors.keywordsSelector);
  const keywordsOptions = useSelector(selectors.keywordsOptionsSelector);
  const labels = useSelector(selectors.labelsSelector);
  const labelsOptions = useSelector(selectors.labelsOptionsSelectors);
  const brandSafety = useSelector(selectors.brandSafetySelector);
  const brandSafetyOptions = useSelector(selectors.brandSafetyOptionsSelector);

  const scheme = useSelector(selectors.schemeSelector);

  // handlers
  const handleSetState = (state) => dispatch(setAction(state));
  const handleSetDevice = (deviceId) => {
    const updateDevices = devices.includes(deviceId) ? devices.filter((d) => d !== deviceId) : [...devices, deviceId];

    dispatch(
      setAction({
        devices: updateDevices,
      }),
    );
  };

  useEffect(() => {
    if (watch && !watchOptions) {
      dispatch(getWatchOptionsAction(watch.title));
    } else if (watchChannel && !watchChannelOptions) {
      const selectedWatch = watchOptions.find((watchOption) => watchOption.id === watch.id);
      dispatch(setAction({ watchChannelOptions: selectedWatch?.watchChannels || [] }));
    }
  }, [watchChannel, watchChannelOptions, watch, watchOptions]);

  return (
    <>
      <FormSection>
        <FormGroupTitle>Placement Details</FormGroupTitle>
        <FormRow label="Luminous Watch Name">
          <Stack fullWidth>
            <Autocomplete
              fullWidth
              value={watch}
              options={watchOptions || []}
              optionValueKey="id"
              optionLabelKey="title"
              loading={!watchOptions}
              size={size}
              filterSelectedOptions
              disabled={!hub || player}
              onChange={(e, selected) => {
                handleSetState({
                  watch: selected,
                  watchChannel: null,
                  watchChannelOptions: selected?.watchChannels || [],
                });
              }}
              onOpen={() => {
                dispatch(getWatchOptionsAction(''));
              }}
              onInputChange={(e, searchText) => dispatch(getWatchOptionsAction(searchText))}
              renderInput={(params) => (
                <TextField
                  {...params}
                  value=""
                  placeholder="Select Watch"
                  {...getInputPropsByName(scheme, ['watch'])}
                  onFocus={() => dispatch(removeErrorByPropAction(['watch']))}
                  label=""
                />
              )}
            />
          </Stack>
        </FormRow>
        <FormRow label="Luminous Watch Channel">
          <Stack fullWidth>
            <Autocomplete
              fullWidth
              value={watchChannel}
              options={watchChannelOptions || []}
              optionValueKey="id"
              optionLabelKey="title"
              loading={!watchChannelOptions}
              size={size}
              filterSelectedOptions
              disabled={!hub || !watch}
              onChange={(e, selected) => {
                handleSetState({
                  watchChannel: selected,
                });
              }}
              renderInput={(params) => (
                <TextField
                  {...params}
                  value=""
                  placeholder="Select Watch Channel"
                  {...getInputPropsByName(scheme, ['watchChannel'])}
                  onFocus={() => dispatch(removeErrorByPropAction(['watchChannel']))}
                  label=""
                />
              )}
            />
          </Stack>
        </FormRow>
        <FormRow label="Player Name">
          <Stack fullWidth>
            <Autocomplete
              fullWidth
              value={player}
              options={playerOptions || []}
              optionValueKey="id"
              optionLabelKey="alias"
              loading={!playerOptions}
              size={size}
              filterSelectedOptions
              disabled={!hub || watch}
              onChange={(e, selected) => {
                handleSetState({
                  player: selected,
                });
              }}
              onOpen={() => {
                dispatch(getPlayerOptionsAction(''));
              }}
              onInputChange={(e, searchText) => dispatch(getPlayerOptionsAction(searchText))}
              renderInput={(params) => (
                <TextField
                  {...params}
                  value=""
                  placeholder="Select Player"
                  {...getInputPropsByName(scheme, ['player'])}
                  onFocus={() => dispatch(removeErrorByPropAction(['player']))}
                  label=""
                />
              )}
            />
          </Stack>
        </FormRow>
        <FormRow label="Player size">
          <ToggleButtonGroup
            equalWidth
            size={size}
            color="primary"
            exclusive={false}
            value={playerSizes}
            disabled={!hub || !player}
            onChange={(event, newValue) => {
              handleSetState({
                playerSizes: newValue,
              });
            }}
          >
            {[
              {
                title: 'S',
                id: PLAYER_SMALL,
              },
              {
                title: 'M',
                id: PLAYER_MEDIUM,
              },
              {
                title: 'L',
                id: PLAYER_LARGE,
              },
            ].map((checkbox) => (
              <ToggleButton
                key={checkbox.id}
                value={checkbox.id}
                disabled={playerSizes.includes(checkbox.id) && playerSizes.length === 1}
              >
                {checkbox.title}
              </ToggleButton>
            ))}
          </ToggleButtonGroup>
        </FormRow>
        <FormRow label="Domain">
          <ActionAutocomplete
            size={size}
            value={domains}
            loading={!domainOptions}
            options={domainOptions || []}
            disabled={!hub}
            onChange={(domainsValue) => handleSetState({ domains: domainsValue })}
            onOpen={() => dispatch(getDomainOptionsAction(''))}
            onInputChange={(searchText) => dispatch(getDomainOptionsAction(searchText))}
          />
        </FormRow>

        <FormRow label="Device">
          <Stack direction="row">
            <ToggleButtonGroup equalWidth color="primary" size="small" value={devices}>
              <ToggleButton value={DEVICE_MOBILE} onClick={() => handleSetDevice(DEVICE_MOBILE)}>
                <Smartphone />
              </ToggleButton>
              <ToggleButton value={DEVICE_DESKTOP} onClick={() => handleSetDevice(DEVICE_DESKTOP)}>
                <Laptop />
              </ToggleButton>
            </ToggleButtonGroup>
          </Stack>
        </FormRow>

        <FormRow label="Geography">
          <ActionAutocomplete
            size={size}
            value={geography}
            loading={!geographyOptions}
            options={geographyOptions || []}
            onChange={(geographyValue) => handleSetState({ geography: geographyValue })}
            onOpen={() => dispatch(getGeographyOptionsAction(''))}
          />
        </FormRow>

        <FormRow label="Viewability">
          <Stack direction="row">
            <ToggleButtonGroup equalWidth color="primary" size="small" value={[inview, notInview].filter(Boolean)}>
              <ToggleButton value={inview} onClick={() => handleSetState({ inview: !inview })}>
                <Visibility />
              </ToggleButton>
              <ToggleButton value={notInview} onClick={() => handleSetState({ notInview: !notInview })}>
                <VisibilityOff />
              </ToggleButton>
            </ToggleButtonGroup>
          </Stack>
        </FormRow>
      </FormSection>
      <FormSection>
        <FormGroupTitle>Video Details</FormGroupTitle>
        <FormRow label="Video Name">
          <Stack fullWidth alignItems="flex-start">
            <Autocomplete
              fullWidth
              value={video}
              options={videoOptions || []}
              optionValueKey="id"
              optionLabelKey="name"
              loading={!videoOptions}
              size={size}
              filterSelectedOptions
              disabled={!hub}
              onChange={(e, selected) => {
                handleSetState({
                  video: selected,
                });
              }}
              onOpen={() => {
                dispatch(getVideoOptionsAction(''));
              }}
              onInputChange={(e, searchText) => dispatch(getVideoOptionsAction(searchText))}
              renderInput={(params) => (
                <TextField
                  {...params}
                  value=""
                  placeholder="Select Video"
                  {...getInputPropsByName(scheme, ['video'])}
                  onFocus={() => dispatch(removeErrorByPropAction(['video']))}
                  label=""
                />
              )}
            />
            {video?.id && (
              <Chip
                size="xSmall"
                color="neutral"
                variant="text"
                component="a"
                href={`${EDITORIAL_PAGE.path}?videoId=${video.id}`}
                target="_blank"
                rel="noreferrer"
                label={video.name}
                deleteIcon={<LaunchOutlined />}
                onDelete={() => null}
              />
            )}
          </Stack>
        </FormRow>
        <FormRow label="From timestamp">
          <TimePicker
            fullWidth
            slotProps={{
              textField: {
                size,
                ...getInputPropsByName(scheme, ['videoFromTimestamp']),
                label: '',
              },
            }}
            // timer used as duration do not change behavior
            placeholder="00:00:00"
            value={dayjs(videoFromTimestamp, 'HH:mm:ss')}
            onChange={(triggerTime) => {
              handleSetState({
                videoFromTimestamp: dayjs(triggerTime).format('HH:mm:ss'),
              });
            }}
            ampm={false}
            views={['hours', 'minutes', 'seconds']}
            format="HH:mm:ss"
            label=""
            disabled={!hub || !video}
            onOpen={() => dispatch(removeErrorByPropAction(['videoFromTimestamp']))}
          />
        </FormRow>
        <FormRow label="To timestamp">
          <TimePicker
            fullWidth
            slotProps={{
              textField: {
                size,
              },
            }}
            // timer used as duration do not change behavior
            placeholder="00:00:00"
            value={dayjs(videoToTimestamp, 'HH:mm:ss')}
            onChange={(triggerTime) => {
              handleSetState({
                videoToTimestamp: dayjs(triggerTime).format('HH:mm:ss'),
              });
            }}
            ampm={false}
            views={['hours', 'minutes', 'seconds']}
            format="HH:mm:ss"
            disabled={!hub || !video}
          />
        </FormRow>
        <FormRow label="Category">
          <ActionIAB
            size={size}
            value={iabCategories}
            onChange={(categories) => handleSetState({ iabCategories: categories })}
          />
        </FormRow>
        <FormRow label="People">
          <ActionAutocomplete
            size={size}
            value={people}
            loading={!peopleOptions}
            options={peopleOptions || []}
            disabled={!hub}
            onChange={(peopleValue) => handleSetState({ people: peopleValue })}
            onOpen={() => dispatch(getPeopleOptionsAction(''))}
            onInputChange={(searchText) => dispatch(getPeopleOptionsAction(searchText))}
          />
        </FormRow>
        <FormRow label="Brands">
          <ActionAutocomplete
            size={size}
            value={brands}
            loading={!brandsOptions}
            options={brandsOptions || []}
            disabled={!hub}
            onChange={(brandsValue) => handleSetState({ brands: brandsValue })}
            onOpen={() => dispatch(getBrandsOptionsAction(''))}
            onInputChange={(searchText) => dispatch(getBrandsOptionsAction(searchText))}
          />
        </FormRow>
        <FormRow label="Keywords">
          <ActionAutocomplete
            size={size}
            value={keywords}
            loading={!keywordsOptions}
            options={keywordsOptions || []}
            disabled={!hub}
            onChange={(keywordsValue) => handleSetState({ keywords: keywordsValue })}
            onOpen={() => dispatch(getKeywordsOptionsAction(''))}
            onInputChange={(searchText) => dispatch(getKeywordsOptionsAction(searchText))}
          />
        </FormRow>
        <FormRow label="Custom Tags">
          <ActionAutocomplete
            size={size}
            value={labels}
            loading={!labelsOptions}
            options={labelsOptions || []}
            groupBy={(option) => option.groupBy}
            disabled={!hub}
            onChange={(labelsValue) => handleSetState({ labels: labelsValue })}
            onOpen={() => dispatch(getLabelsOptionsAction(''))}
            onInputChange={(searchText) => dispatch(getLabelsOptionsAction(searchText))}
          />
        </FormRow>
        <FormRow label="Brand Safety">
          <ActionAutocomplete
            size={size}
            value={brandSafety}
            loading={!brandSafetyOptions}
            options={brandSafetyOptions || []}
            onChange={(brandSafetyValue) => handleSetState({ brandSafety: brandSafetyValue })}
            onOpen={() => dispatch(getBrandSafetyOptionsAction(''))}
          />
        </FormRow>
      </FormSection>
    </>
  );
}

export default TargetingTab;
