import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { createFilterOptions } from '@mui/material/Autocomplete';
import { Add, ContentCopyRounded } from '@mui/icons-material';

import {
  DEMAND_TAG_DEFAULT_TIER_VALUES,
  DEMAND_TAG_EVENT_PIXELS_SIZE,
  DEMAND_TAG_FORMAT,
  DEMAND_TAG_PAGE_TYPE_VALUES,
  DEMAND_TAG_PRIORITY,
  DEMAND_TAG_STATUS,
  SOURCE_TAG_OPTIONS,
} from '@/modules/marketplace/account/constants';

import * as selectors from '../../../../redux/selectors';
import * as actions from '../../../../redux/slices';
import { getRequiredInputProps } from '@/modules/@common/Form/helpers';
import copyToClipboard from '@/modules/@common/helpers/copy';
import validation from '@/modules/marketplace/account/helpers/demandTagFormValidationRules';
import { integerFieldBlockInvalidChar } from '@/modules/marketplace/account/helpers/validate';
import { getNextId } from '@/modules/marketplace/common/helpers';

import { Form, FormContent, FormGroupTitle, FormRow, FormSection } from '@/modules/@common/Form';
import FormLineItem from './components/FormLineItem';
import HeaderBiddingForm from './components/HeaderBiddingForm';
import LineItem from './components/LineItem';
import {
  Autocomplete,
  Button,
  DateRangePicker,
  Divider,
  Grid,
  IconButton,
  InputAdornment,
  Link,
  MenuItem,
  Select,
  Stack,
  Switch,
  TextField,
  ToggleButton,
  ToggleButtonGroup,
  Typography,
} from '@/mui/components';

import styles from './index.module.scss';

const filter = createFilterOptions();

function SettingsTab(props) {
  const dispatch = useDispatch();

  const pageConfig = useSelector(selectors.pageConfigSelector);
  const labelsOptions = useSelector(selectors.labelsOptionsSelector);

  const settings = useSelector(selectors.settingsSelector);
  const {
    name,
    source,
    platformId,
    format,
    status,
    flightsDates,
    uid,
    advertiser,
    demandAccount,
    type,
    url,
    priority,
    defaultTier,
    labels,
    timeout,
    eventPixelsList,
    videoId,
    clickThroughUrl,
    platforms,
    errors,
  } = settings;

  const { isCreatingNew, isDuplicate } = pageConfig ?? {};
  const [showNewForm, toggleNewFrom] = useState(false);
  dayjs.extend(utc);

  const defineDefaultTierForSelfServeTag = ({ type: typeParam, priority: priorityParam }) => {
    if (priorityParam === DEMAND_TAG_PRIORITY.openAuction) {
      if (typeParam === DEMAND_TAG_PAGE_TYPE_VALUES.tag) {
        dispatch(
          actions.setSettingsTabAction({
            defaultTier: 3,
          }),
        );
      }

      if (typeParam === DEMAND_TAG_PAGE_TYPE_VALUES.hb) {
        dispatch(
          actions.setSettingsTabAction({
            defaultTier: 2,
          }),
        );
      }

      if (typeParam === DEMAND_TAG_PAGE_TYPE_VALUES.mp4) {
        dispatch(
          actions.setSettingsTabAction({
            defaultTier: 1,
          }),
        );
      }
    }
  };

  useEffect(() => {
    if (isCreatingNew && !props.isAdminMP) {
      defineDefaultTierForSelfServeTag({ type, priority });
    }
  }, [pageConfig]);

  return (
    <Form>
      <FormContent>
        <FormSection>
          <FormGroupTitle>Basic Setting</FormGroupTitle>
          <FormRow label="Name">
            <TextField
              value={name}
              size="small"
              placeholder="Enter Tag Name"
              {...getRequiredInputProps({
                fieldName: 'name',
                error: !!errors?.name?.length,
                helperText: errors?.name,
              })}
              onChange={({ target }) => {
                const { name: nameError, ...restErrors } = errors;
                dispatch(actions.setSettingsTabAction({ name: target.value, errors: restErrors }));
              }}
            />
          </FormRow>

          {props.isAdminMP && (
            <>
              <FormRow label="Source">
                <Select
                  variant="outlined"
                  size="small"
                  id="source"
                  value={source}
                  onChange={(event) => {
                    dispatch(actions.setSettingsTabAction({ source: event.target.value }));
                  }}
                  disabled={!(isCreatingNew || isDuplicate)}
                >
                  {SOURCE_TAG_OPTIONS.map((item) => (
                    <MenuItem key={item.value} value={item.value}>
                      {item.label}
                    </MenuItem>
                  ))}
                </Select>
              </FormRow>

              {source !== SOURCE_TAG_OPTIONS[0].value && (
                <FormRow label="Platform ID">
                  <TextField
                    size="small"
                    value={platformId}
                    placeholder="Enter Platform ID"
                    disabled={!(isCreatingNew || isDuplicate)}
                    {...getRequiredInputProps({
                      fieldName: 'platformId',
                      error: !!errors?.platformId?.length,
                      helperText: errors?.platformId,
                    })}
                    onChange={({ target }) => {
                      const { platformId: platformIdError, ...restErrors } = errors;
                      dispatch(actions.setSettingsTabAction({ platformId: target.value, errors: restErrors }));
                    }}
                  />
                </FormRow>
              )}
            </>
          )}

          <FormRow label="Format">
            <ToggleButtonGroup
              equalWidth
              size="small"
              color="primary"
              variant="outlined"
              disabled={!isCreatingNew}
              value={format}
            >
              <ToggleButton
                value={DEMAND_TAG_FORMAT.video}
                onClick={() => {
                  dispatch(
                    actions.setSettingsTabAction({
                      format: DEMAND_TAG_FORMAT.video,
                    }),
                  );
                }}
              >
                Video
              </ToggleButton>
              <ToggleButton
                value={DEMAND_TAG_FORMAT.display}
                onClick={() => {
                  // return type to tag because mp4 is hidden
                  if (
                    format === DEMAND_TAG_FORMAT.sponsored ||
                    (format === DEMAND_TAG_FORMAT.video && type === DEMAND_TAG_PAGE_TYPE_VALUES.mp4)
                  ) {
                    dispatch(
                      actions.setSettingsTabAction({
                        type: DEMAND_TAG_PAGE_TYPE_VALUES.tag,
                      }),
                    );

                    if (isCreatingNew && !props.isAdminMP) {
                      defineDefaultTierForSelfServeTag({
                        type: DEMAND_TAG_PAGE_TYPE_VALUES.tag,
                        priority,
                      });
                    }
                  }

                  dispatch(
                    actions.setSettingsTabAction({
                      format: DEMAND_TAG_FORMAT.display,
                    }),
                  );
                }}
              >
                Display
              </ToggleButton>
              <ToggleButton
                value={DEMAND_TAG_FORMAT.sponsored}
                onClick={() => {
                  dispatch(
                    actions.setSettingsTabAction({
                      format: DEMAND_TAG_FORMAT.sponsored,
                    }),
                  );

                  dispatch(
                    actions.setSettingsTabAction({
                      type: DEMAND_TAG_PAGE_TYPE_VALUES.mp4,
                    }),
                  );

                  if (isCreatingNew && !props.isAdminMP) {
                    defineDefaultTierForSelfServeTag({
                      type: DEMAND_TAG_PAGE_TYPE_VALUES.mp4,
                      priority,
                    });
                  }
                }}
              >
                Sponsored
              </ToggleButton>
            </ToggleButtonGroup>
          </FormRow>
          <FormRow label="Status">
            <Switch
              color="primary"
              size="small"
              checked={status === DEMAND_TAG_STATUS.enabled}
              onChange={() =>
                dispatch(
                  actions.setSettingsTabAction({
                    status:
                      status === DEMAND_TAG_STATUS.enabled ? DEMAND_TAG_STATUS.disabled : DEMAND_TAG_STATUS.enabled,
                  }),
                )
              }
            />
          </FormRow>
          <FormRow label="Flight Dates">
            <ToggleButtonGroup equalWidth size="small" color="primary" variant="outlined" value={!flightsDates ? 0 : 1}>
              <ToggleButton
                value={0}
                onClick={() =>
                  dispatch(
                    actions.setSettingsTabAction({
                      flightsDates: null,
                    }),
                  )
                }
              >
                Indefinite
              </ToggleButton>
              <ToggleButton
                value={1}
                onClick={() =>
                  dispatch(
                    actions.setSettingsTabAction({
                      flightsDates: {},
                    }),
                  )
                }
              >
                Custom
              </ToggleButton>
            </ToggleButtonGroup>
          </FormRow>
          {flightsDates && (
            <FormRow label="Schedule (UTC)">
              <DateRangePicker
                className={styles.DateRangePicker}
                value={[dayjs.utc(flightsDates?.startDate ?? null), dayjs.utc(flightsDates?.endDate ?? null)]}
                format="MM/DD/YYYY"
                calendars={2}
                disablePast
                timezone="UTC"
                minDate={dayjs.utc().startOf('day')}
                onChange={(date) => {
                  const { flightsDates: error, ...restErrors } = errors;

                  dispatch(
                    actions.setSettingsTabAction({
                      flightsDates: {
                        startDate: dayjs.utc(date[0]).startOf('day').valueOf(),
                        endDate:
                          date[1] &&
                          dayjs.utc(date[1]).endOf('day').valueOf() > dayjs.utc(date[0]).startOf('day').valueOf()
                            ? dayjs.utc(date[1]).endOf('day').valueOf()
                            : dayjs.utc(date[0]).endOf('day').valueOf(),
                      },
                      errors: restErrors,
                    }),
                  );
                }}
                slotProps={{
                  textField: {
                    size: 'small',
                    error: errors?.flightsDates ?? false,
                  },
                }}
              />
            </FormRow>
          )}
          {!isCreatingNew && (
            <FormRow label="UID">
              <TextField
                data-id="uid"
                value={uid}
                size="small"
                inputProps={{
                  readOnly: true,
                }}
              />
            </FormRow>
          )}
          <FormRow label="Advertiser Name">
            <TextField
              value={advertiser}
              size="small"
              inputProps={{
                readOnly: true,
              }}
            />
          </FormRow>
          <FormRow label="Demand Account">
            <TextField
              value={demandAccount}
              size="small"
              inputProps={{
                readOnly: true,
              }}
            />
          </FormRow>

          {format !== DEMAND_TAG_FORMAT.sponsored && (
            <FormRow label="Type">
              <ToggleButtonGroup
                equalWidth
                size="small"
                color="primary"
                variant="outlined"
                disabled={!isCreatingNew}
                value={type}
              >
                <ToggleButton
                  value={DEMAND_TAG_PAGE_TYPE_VALUES.tag}
                  onClick={() => {
                    dispatch(
                      actions.setSettingsTabAction({
                        type: DEMAND_TAG_PAGE_TYPE_VALUES.tag,
                      }),
                    );

                    if (isCreatingNew && !props.isAdminMP) {
                      defineDefaultTierForSelfServeTag({
                        type: DEMAND_TAG_PAGE_TYPE_VALUES.tag,
                        priority,
                      });
                    }
                  }}
                >
                  Tag
                </ToggleButton>
                <ToggleButton
                  value={DEMAND_TAG_PAGE_TYPE_VALUES.hb}
                  onClick={() => {
                    dispatch(
                      actions.setSettingsTabAction({
                        type: DEMAND_TAG_PAGE_TYPE_VALUES.hb,
                      }),
                    );

                    if (isCreatingNew && !props.isAdminMP) {
                      defineDefaultTierForSelfServeTag({
                        type: DEMAND_TAG_PAGE_TYPE_VALUES.hb,
                        priority,
                      });
                    }
                  }}
                >
                  HB
                </ToggleButton>

                {format === DEMAND_TAG_FORMAT.video && (
                  <ToggleButton
                    value={DEMAND_TAG_PAGE_TYPE_VALUES.mp4}
                    onClick={() => {
                      dispatch(
                        actions.setSettingsTabAction({
                          type: DEMAND_TAG_PAGE_TYPE_VALUES.mp4,
                        }),
                      );

                      if (isCreatingNew && !props.isAdminMP) {
                        defineDefaultTierForSelfServeTag({
                          type: DEMAND_TAG_PAGE_TYPE_VALUES.mp4,
                          priority,
                        });
                      }
                    }}
                  >
                    DIRECT MP4
                  </ToggleButton>
                )}
              </ToggleButtonGroup>
            </FormRow>
          )}

          {type === DEMAND_TAG_PAGE_TYPE_VALUES.tag && (
            <FormRow label="Ad Server URL" justifyContent="flex-end">
              <TextField
                value={url}
                size="small"
                multiline
                rows={4}
                placeholder="Enter URL"
                onChange={({ target }) => {
                  const { url: urlError, ...restErrors } = errors;
                  dispatch(actions.setSettingsTabAction({ url: target.value, errors: restErrors }));
                }}
                {...getRequiredInputProps({
                  fieldName: 'serverUrl',
                  error: !!errors?.url?.length,
                  helperText: errors?.url?.length ? (
                    errors?.url
                  ) : (
                    <Typography variant="caption" color="text.secondary">
                      {'For supported macros, please see our '}
                      <Link
                        target="_blank"
                        rel="noreferrer"
                        href="https://docs.anyclip.com/en/articles/9638792-marketplace-supported-macros"
                      >
                        macros online help
                      </Link>
                    </Typography>
                  ),
                })}
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <IconButton size="small" onClick={() => copyToClipboard(url)}>
                        <ContentCopyRounded />
                      </IconButton>
                    </InputAdornment>
                  ),
                }}
              />
            </FormRow>
          )}

          {type === DEMAND_TAG_PAGE_TYPE_VALUES.hb && platforms?.length && (
            <HeaderBiddingForm isDuplicate={isDuplicate} isCreatingNew={isCreatingNew} />
          )}

          {type === DEMAND_TAG_PAGE_TYPE_VALUES.mp4 && (
            <>
              <FormRow label="Studio Video ID">
                <TextField
                  value={videoId}
                  size="small"
                  placeholder="Enter Video ID"
                  {...getRequiredInputProps({
                    fieldName: 'name',
                    error: !!errors?.videoId?.length,
                    helperText: errors?.videoId,
                  })}
                  onChange={({ target }) => {
                    const { videoId: videoIdError, ...restErrors } = errors;
                    dispatch(actions.setSettingsTabAction({ videoId: target.value, errors: restErrors }));
                  }}
                />
              </FormRow>

              {format !== DEMAND_TAG_FORMAT.sponsored && (
                <FormRow label="Click Through URL">
                  <TextField
                    value={clickThroughUrl}
                    size="small"
                    placeholder="Enter URL"
                    onChange={({ target }) => {
                      dispatch(actions.setSettingsTabAction({ clickThroughUrl: target.value }));
                    }}
                  />
                </FormRow>
              )}
            </>
          )}
          <FormRow
            label="Priority"
            tooltip={
              "When configured as 'Open Auction',\n" +
              'the tag will be dynamically prioritized among various waterfall ' +
              'tiers by the AnyClip Optimization team'
            }
          >
            <ToggleButtonGroup equalWidth size="small" color="primary" variant="outlined" value={priority}>
              <ToggleButton
                value={DEMAND_TAG_PRIORITY.firstLook}
                onClick={() =>
                  dispatch(
                    actions.setSettingsTabAction({
                      priority: DEMAND_TAG_PRIORITY.firstLook,
                      defaultTier: 0,
                    }),
                  )
                }
              >
                1st Look
              </ToggleButton>
              <ToggleButton
                value={DEMAND_TAG_PRIORITY.openAuction}
                onClick={() => {
                  dispatch(
                    actions.setSettingsTabAction({
                      priority: DEMAND_TAG_PRIORITY.openAuction,
                    }),
                  );

                  if (isCreatingNew && !props.isAdminMP) {
                    defineDefaultTierForSelfServeTag({
                      type,
                      priority: DEMAND_TAG_PRIORITY.openAuction,
                    });
                  }
                }}
              >
                Open Auction
              </ToggleButton>
            </ToggleButtonGroup>
          </FormRow>

          {props.isAdminMP && (
            <FormRow label="Default Tier">
              <ToggleButtonGroup
                equalWidth
                size="small"
                color="primary"
                disabled={priority === DEMAND_TAG_PRIORITY.firstLook}
                value={defaultTier}
              >
                {DEMAND_TAG_DEFAULT_TIER_VALUES.map((tier) => (
                  <ToggleButton
                    key={tier.value}
                    value={tier.value}
                    onClick={() =>
                      dispatch(
                        actions.setSettingsTabAction({
                          defaultTier: tier.value,
                        }),
                      )
                    }
                  >
                    {tier.value}
                  </ToggleButton>
                ))}
              </ToggleButtonGroup>
            </FormRow>
          )}

          {props.isAdminMP && (
            <FormRow label="Label">
              <Autocomplete
                id="labels"
                size="small"
                value={labels}
                options={labelsOptions}
                optionLabelKey="value"
                onOpen={() =>
                  dispatch(
                    actions.getLabelsForTableFilterAction({
                      prefix: '',
                    }),
                  )
                }
                filterOptions={(options, params) => {
                  const filtered = filter(options, params);

                  if (filtered?.some((item) => item.value === params.inputValue)) {
                    return filtered;
                  }

                  if (params.inputValue !== '') {
                    filtered.push({
                      inputValue: `Create: "${params.inputValue}"`,
                      value: params.inputValue,
                    });
                  }

                  return filtered;
                }}
                getOptionLabel={(option) => {
                  if (typeof option === 'string') {
                    return option;
                  }
                  if (option?.inputValue) {
                    return option?.inputValue;
                  }
                  return option?.value;
                }}
                multiple={true}
                freeSolo
                onChange={(e, newValue) => {
                  dispatch(
                    actions.setSettingsTabAction({
                      labels: newValue.map((item) => {
                        if (typeof item === 'string') {
                          return item;
                        }

                        return item.value;
                      }),
                    }),
                  );
                }}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    placeholder="Enter Label"
                    onChange={(e) => {
                      dispatch(
                        actions.getLabelsForTableFilterAction({
                          prefix: e.target.value,
                        }),
                      );
                    }}
                    variant="outlined"
                    size="small"
                    fullWidth
                  />
                )}
              />
            </FormRow>
          )}

          <FormGroupTitle>Advanced Setting</FormGroupTitle>
          <FormRow label="Timeout (ms)">
            <TextField
              type="number"
              InputProps={{
                inputProps: { min: 0 },
              }}
              value={timeout}
              size="small"
              placeholder="Enter Timeout"
              {...getRequiredInputProps({
                fieldName: 'timeout',
                error: !validation.validateTimeout(timeout).isValid,
                helperText: validation.validateTimeout(timeout).error,
              })}
              onKeyDown={integerFieldBlockInvalidChar}
              onChange={({ target }) =>
                dispatch(
                  actions.setSettingsTabAction({
                    timeout: parseInt(target.value, 10),
                  }),
                )
              }
            />
          </FormRow>

          <Divider flexItem />
          <FormRow label="Event Pixels" justifyContent="flex-end" fullWidth>
            {!!eventPixelsList.length && (
              <Button
                size="small"
                onClick={() => toggleNewFrom(true)}
                disabled={eventPixelsList.length === DEMAND_TAG_EVENT_PIXELS_SIZE}
                startIcon={<Add />}
              >
                New
              </Button>
            )}
            {!eventPixelsList.length && !showNewForm && (
              <Button size="small" onClick={() => toggleNewFrom(true)} startIcon={<Add />}>
                Add Event Pixel
              </Button>
            )}
          </FormRow>
          <FormRow fullWidth>
            <Stack fullWidth>
              <LineItem id="title" url="URL" event="Event" type="Type" isLabelRow />
              {showNewForm && (
                <FormLineItem
                  onSubmit={(data) => {
                    toggleNewFrom(false);
                    dispatch(
                      actions.setSettingsTabAction({
                        eventPixelsList: [
                          {
                            id: getNextId(eventPixelsList),
                            ...data,
                          },
                          ...eventPixelsList,
                        ],
                      }),
                    );
                  }}
                  onCancel={() => {
                    toggleNewFrom(false);
                  }}
                />
              )}
              {eventPixelsList.map((e) => (
                <LineItem
                  key={e.id}
                  id={e.id}
                  url={e.url}
                  event={e.event}
                  type={e.type}
                  onSubmit={(data) =>
                    dispatch(
                      actions.setSettingsTabAction({
                        eventPixelsList: eventPixelsList.map((i) => (i.id === data.id ? { ...data } : i)),
                      }),
                    )
                  }
                  onRemove={(data) =>
                    dispatch(
                      actions.setSettingsTabAction({
                        eventPixelsList: eventPixelsList.filter((i) => i.id !== data.id),
                      }),
                    )
                  }
                />
              ))}
              <Grid container justifyContent="flex-start">
                <Typography variant="caption" color="text.secondary">
                  {'For supported macros, please see our '}
                  <Link
                    target="_blank"
                    rel="noreferrer"
                    href="https://docs.anyclip.com/en/articles/9638792-marketplace-supported-macros"
                  >
                    macros online help
                  </Link>
                </Typography>
              </Grid>
            </Stack>
          </FormRow>
        </FormSection>
      </FormContent>
    </Form>
  );
}

SettingsTab.propTypes = {
  isAdminMP: PropTypes.bool.isRequired,
};

export default SettingsTab;
