import React, { useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'clsx';
import { Description, Devices, Language, PlayCircleRounded, Publish, Visibility } from '@mui/icons-material';

import { DEMAND_TAG_KEY_VALUE_TARGETING_TYPE } from '@/modules/marketplace/account/constants';

import { Popover, Typography } from '@/mui/components';

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

const config = {
  devices: {
    header: 'Devices Targeting',
    iconComponent: Devices,
    items: [],
  },
  viewability: {
    header: 'Viewability Targeting',
    iconComponent: Visibility,
    items: [],
  },
  playerSizes: {
    header: 'Player Size Targeting',
    iconComponent: PlayCircleRounded,
    items: [],
  },
  geo: {
    header: 'Geo Targeting',
    iconComponent: Language,
    include: [],
    exclude: [],
    tagHeader: 'Tag:',
    advertiserHeader: 'Advertiser:',
    advertiserInclude: [],
    advertiserExclude: [],
  },
  browsers: {
    header: 'Browsers Targeting',
    include: [],
    exclude: [],
    hidden: true,
  },
  os: {
    header: 'OS Targeting',
    include: [],
    exclude: [],
    hidden: true,
  },
  frequency: {
    header: 'Frequency Cap',
    iconComponent: Publish,
    value: '',
    amount: '',
    type: '',
    timeframe: '',
  },
  kvTargeting: {
    header: 'Key-Values Targeting',
    iconComponent: Description,
    values: [],
  },
};

function TargetingCell(props) {
  const [anchorEl, setAnchorEl] = useState(null);
  const [targetingKey, setTargetingKey] = useState(null);

  const targeting = Object.keys(config).reduce((acc, cur) => {
    const include = props.cell?.include?.[cur] ?? [];
    const exclude = props.cell?.exclude?.[cur] ?? [];

    if (cur === 'frequency') {
      return {
        ...acc,
        [cur]: {
          ...acc[cur],
          ...(props.cell?.[cur] ?? {}),
          notEmpty: !!props.cell?.[cur] && props.cell?.[cur]?.status !== 'DISABLED',
        },
      };
    }

    if (cur === 'viewability' || cur === 'playerSizes') {
      const items = Array.isArray(include) ? include : [include];
      return {
        ...acc,
        [cur]: {
          ...acc[cur],
          items,
          notEmpty: items?.length,
        },
      };
    }

    if (cur === 'geo') {
      return {
        ...acc,
        [cur]: {
          ...acc[cur],
          include,
          exclude,
          advertiserInclude: props.cell.advertiserInclude?.geo,
          advertiserExclude: props.cell.advertiserExclude?.geo,
          notEmpty:
            include?.length ||
            exclude?.length ||
            props.cell.advertiserInclude?.geo?.length ||
            props.cell.advertiserExclude?.geo?.length,
        },
      };
    }

    if (cur === 'kvTargeting') {
      return {
        ...acc,
        [cur]: {
          ...acc[cur],
          values: props.cell?.[cur] ?? [],
          notEmpty: props.cell?.[cur]?.length,
        },
      };
    }

    return {
      ...acc,
      [cur]: {
        ...acc[cur],
        include,
        exclude,
        notEmpty: include?.length || exclude?.length,
      },
    };
  }, config);

  const handlePopoverOpen = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const handlePopoverClose = () => {
    setAnchorEl(null);
    setTargetingKey(null);
  };

  const open = Boolean(anchorEl);

  return (
    <div className={styles.Targeting}>
      {Object.keys(targeting).map((key) => {
        if (targeting[key].hidden) {
          return null;
        }

        if (targeting[key].iconComponent) {
          const Icon = targeting[key].iconComponent;
          return (
            <Icon
              key={key}
              data-id={`icon-${targeting[key]}`}
              className={classNames(styles.Icon, {
                [styles.Icon_empty]: !targeting[key].notEmpty,
                [styles.Icon_error]: props.cell.waterfallSkip,
              })}
              onMouseEnter={(e) => {
                handlePopoverOpen(e);
                setTargetingKey(key);
              }}
              onMouseLeave={handlePopoverClose}
              fontSize="medium"
            />
          );
        }

        return null;
      })}

      <Popover
        id="mouse-over-popover"
        className={styles.Popover}
        classes={{
          paper: styles.Paper,
        }}
        open={open}
        anchorEl={anchorEl}
        anchorOrigin={{
          vertical: 'top',
          horizontal: 'right',
        }}
        onClose={handlePopoverClose}
        disableRestoreFocus
        disableScrollLock
      >
        <div className={styles.Popover}>
          {targetingKey && (
            <Typography className={styles.Popover_title} variant="subtitle2" fontWeight={600} component="div">
              {targeting[targetingKey].header}
            </Typography>
          )}

          {targetingKey && targeting[targetingKey].items && (
            <Typography className={styles.Popover_content} variant="body2" component="div">
              {targeting[targetingKey].items.join(', ')}
            </Typography>
          )}

          {targetingKey && targetingKey === 'viewability' && props.cell?.viewabilityThreshold && (
            <Typography className={styles.Popover_title} variant="subtitle2" fontWeight={600} component="div">
              {`Viewability targeting: ${Math.round(props.cell.viewabilityThreshold * 10000) / 100}%`}
            </Typography>
          )}

          {targetingKey &&
            targetingKey === 'geo' &&
            (!!targeting[targetingKey].include?.length || !!targeting[targetingKey].exclude?.length) && (
              <Typography className={styles.Popover_title} variant="subtitle2" fontWeight={600} component="div">
                {targeting[targetingKey].tagHeader}
              </Typography>
            )}

          {targetingKey && targeting[targetingKey].include && (
            <Typography className={styles.Popover_content} variant="body2" component="div">
              {`Include: ${targeting[targetingKey].include.join(', ')}`}
            </Typography>
          )}

          {targetingKey && targeting[targetingKey].exclude && (
            <Typography className={styles.Popover_content} variant="body2" component="div">
              {`Exclude: ${targeting[targetingKey].exclude.join(', ')}`}
            </Typography>
          )}

          {targetingKey && targeting[targetingKey].type && (
            <Typography className={styles.Popover_content} variant="body2" component="div">
              {`Type: ${targeting[targetingKey].type}`}
            </Typography>
          )}

          {targetingKey && targeting[targetingKey].value && (
            <Typography className={styles.Popover_content} variant="body2" component="div">
              {`Amount per User: ${targeting[targetingKey].value}`}
            </Typography>
          )}

          {targetingKey && targeting[targetingKey].timeframe && (
            <Typography className={styles.Popover_content} variant="body2" component="div">
              {`Time Frame: ${targeting[targetingKey].timeframe}`}
            </Typography>
          )}

          {targetingKey && targeting[targetingKey].amount && (
            <Typography className={styles.Popover_content} variant="body2" component="div">
              {`Amount per Time: ${targeting[targetingKey].amount}`}
            </Typography>
          )}

          {targetingKey &&
            targetingKey === 'geo' &&
            (!!targeting[targetingKey].advertiserInclude?.length ||
              !!targeting[targetingKey].advertiserExclude?.length) && (
              <>
                <Typography className={styles.Popover_title} variant="subtitle2" fontWeight={600} component="div">
                  {targeting[targetingKey].advertiserHeader}
                </Typography>
                <Typography className={styles.Popover_content} variant="body2" component="div">
                  {`Include: ${targeting[targetingKey].advertiserInclude?.join(', ') ?? ''}`}
                </Typography>
                <Typography className={styles.Popover_content} variant="body2" component="div">
                  {`Exclude: ${targeting[targetingKey].advertiserExclude?.join(', ') ?? ''}`}
                </Typography>
              </>
            )}

          {targetingKey &&
            targetingKey === 'kvTargeting' &&
            !!targeting[targetingKey].values?.length &&
            targeting[targetingKey].values.map((item, index) => (
              <div key={`Key-Value-${index + 1}`}>
                <Typography className={styles.Popover_subtitle} variant="subtitle2" fontWeight={600} component="div">
                  {`Key-Value ${index + 1}:`}
                </Typography>

                <Typography className={styles.Popover_content} variant="body2" component="div">
                  {`Parameter: ${item.keyName}`}
                </Typography>

                <Typography className={styles.Popover_content} variant="body2" component="div">
                  {`${item.state === 'INCLUDE' ? 'Include' : 'Exclude'}:
                    ${
                      item.type === DEMAND_TAG_KEY_VALUE_TARGETING_TYPE.value
                        ? item.values?.join(', ')
                        : item.listNames?.join(', ')
                    }`}
                </Typography>
              </div>
            ))}
        </div>
      </Popover>
    </div>
  );
}

TargetingCell.propTypes = {
  cell: PropTypes.shape({
    include: PropTypes.arrayOf(PropTypes.shape({})),
    exclude: PropTypes.arrayOf(PropTypes.shape({})),
    advertiserInclude: PropTypes.shape({
      geo: PropTypes.arrayOf(PropTypes.string),
    }),
    advertiserExclude: PropTypes.shape({
      geo: PropTypes.arrayOf(PropTypes.string),
    }),
    waterfallSkip: PropTypes.bool,
    viewabilityThreshold: PropTypes.number,
  }).isRequired,
};

export default TargetingCell;
