import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';
import { Add, FilterAlt, SearchRounded, Settings } from '@mui/icons-material';

import {
  DEMAND_ADVERTISER_PAGE,
  DEMAND_TAG_PAGE,
  DEMAND_TAG_PAGE_INFO_ROWS_FOR_DISPLAY_FORMAT,
  DEMAND_TAG_PAGE_TABLE_CELLS_FOR_DISPLAY_FORMAT,
  DEMAND_TAG_PAGE_TABLE_HEADERS_FOR_DISPLAY_FORMAT,
  SUPPLY_SITE_PAGE,
  SUPPLY_TAG_PAGE,
  SUPPLY_TAG_PAGE_INFO_ROWS_FOR_DISPLAY_FORMAT,
  SUPPLY_TAG_PAGE_TABLE_CELLS_FOR_DISPLAY_FORMAT,
  SUPPLY_TAG_PAGE_TABLE_HEADERS_FOR_DISPLAY_FORMAT,
} from '../../constants';
import { PCN_GET_MARKETPLACE_DASHBOARD } from '@/modules/@common/acl/constants';

import * as selectors from '../../redux/selectors';
import * as actions from '../../redux/slices';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';

import Table from '@/modules/marketplace/common/Table';
import Chart from '../Chart';
import Total from '../Total';
import usePageConfig from '../usePageConfig';
import {
  Autocomplete,
  Button,
  Divider,
  Grid,
  IconButton,
  InputAdornment,
  MenuItem,
  Select,
  Stack,
  TextField,
  Tooltip,
} from '@/mui/components';
import { CustomCsvFilled } from '@/mui/components/CustomIcon';

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

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

  const userPermissions = useSelector(getUserPermissionsSelector);

  const sortBy = useSelector(selectors.sortBySelector);
  const sortOrder = useSelector(selectors.sortOrderSelector);
  // props.pageConfig
  // const pageConfig = useSelector(selectors.pageConfigSelector);
  const info = useSelector(selectors.infoSelector);
  const total = useSelector(selectors.totalSelector);
  const chartTab = useSelector(selectors.chartTabSelector);
  const chartData = useSelector(selectors.chartDataSelector);
  const chartHistory = useSelector(selectors.chartHistorySelector);
  const timeIntervalFilter = useSelector(selectors.timeIntervalFilterSelector);
  const comparisonFilter = useSelector(selectors.comparisonFilterSelector);
  const isChartLoading = useSelector(selectors.isChartLoadingSelector);
  const search = useSelector(selectors.searchSelector);
  const filterByStatus = useSelector(selectors.filterByStatusSelector);
  const filterByLabel = useSelector(selectors.filterByLabelSelector);
  const labelsOptions = useSelector(selectors.labelsOptionsSelector);
  const supply = useSelector(selectors.supplySelector);
  const data = useSelector(selectors.dataSelector);
  const page = useSelector(selectors.pageSelector);
  const rowsPerPage = useSelector(selectors.rowsPerPageSelector);
  const totalCount = useSelector(selectors.totalCountSelector);
  const isLoading = useSelector(selectors.isLoadingSelector);

  const getChartData = (o) => dispatch(actions.getChartDataAction(o));
  const setChartTab = (o) => dispatch(actions.setChartTabAction(o));
  const setTimeIntervalFilter = (o) => dispatch(actions.setTimeIntervalFilterAction(o));
  const setComparisonFilter = (o) => dispatch(actions.setComparisonFilterAction(o));
  const downloadCSV = (o) => dispatch(actions.downloadCSVAction(o));
  const setRowsPerPage = (o) => dispatch(actions.setRowsPerPageAction(o));

  const router = useRouter();
  const isAdminMP = hasPermission(PCN_GET_MARKETPLACE_DASHBOARD, userPermissions);

  const pageConfig = usePageConfig({ isAdminMP });

  const [selected, setSelected] = useState([]);

  useEffect(() => {
    if (pageConfig) {
      setSelected([]);
    }
  }, [pageConfig?.type]);

  const createRowLink = (row) => {
    if (pageConfig.nextLevelLink) {
      const queries = router.asPath.split('?')[1]
        ? `?${router.asPath.split('?')[1]}&${pageConfig.nextLevelQuery}=${encodeURIComponent(row.name)}`
        : `?${encodeURIComponent(row.name)}`;

      return `${router.asPath.split('?')[0]}${pageConfig.nextLevelLink}/${row.id}${queries}`;
    }

    if (pageConfig.getTableTagLink) {
      return pageConfig.getTableTagLink(row);
    }

    return null;
  };

  const handleSorting = (id) => {
    if (id === 'NAME') {
      const isAsc = sortBy === id && sortOrder === 'ASC';
      dispatch(actions.setSortOrderAction(isAsc ? 'DESC' : 'ASC'));
    } else {
      const isDesc = sortBy === id && sortOrder === 'DESC';
      dispatch(actions.setSortOrderAction(isDesc ? 'ASC' : 'DESC'));
    }
    dispatch(actions.setSortByAction(id));
  };

  const onChangePage = (value) => {
    dispatch(actions.setFieldAction({ page: value }));
    dispatch(actions.getDataAction());
  };

  const setRowBackgroundByTierValue = (row) => {
    const { tier } = row;
    const mapper = [
      styles.Tier___0,
      styles.Tier___1,
      styles.Tier___2,
      styles.Tier___3,
      styles.Tier___4,
      styles.Tier___5,
      styles.Tier___6,
      styles.Tier___7,
      styles.Tier___8,
      styles.Tier___9,
    ];
    return mapper[+tier] ?? mapper[0];
  };

  const defineTotalInfoRows = () => {
    // props.pageConfig
    if (pageConfig?.type === DEMAND_TAG_PAGE && info?.format === 'DISPLAY') {
      return isAdminMP
        ? DEMAND_TAG_PAGE_INFO_ROWS_FOR_DISPLAY_FORMAT
        : DEMAND_TAG_PAGE_INFO_ROWS_FOR_DISPLAY_FORMAT.filter(
            (item) => !['REVENUE', 'RPM', 'PROFIT', 'ERPM'].includes(item.value),
          ).map((item) => {
            if (item.value === 'GROSS_REVENUE') {
              return { ...item, label: 'Pub Revenue' };
            }
            if (item.value === 'GROSS_RPM') {
              return { ...item, label: 'Ad RPM' };
            }
            return item;
          });
    }

    // props.pageConfig
    if (pageConfig?.type === SUPPLY_TAG_PAGE && info?.format === 'DISPLAY') {
      return isAdminMP
        ? SUPPLY_TAG_PAGE_INFO_ROWS_FOR_DISPLAY_FORMAT.filter(
            (item) => !['PUB_REVENUE', 'PUB_AD_RPM'].includes(item.value),
          )
        : SUPPLY_TAG_PAGE_INFO_ROWS_FOR_DISPLAY_FORMAT.filter(
            (item) =>
              ![
                'REVENUE',
                'GROSS_RPM',
                'GROSS_REVENUE',
                'EXPENSES',
                'MEDIA_COST',
                'MEDIA_MARGIN',
                'AC_AD_RPM',
                'CTR',
              ].includes(item.value),
          );
    }

    return pageConfig.infoRows;
  };

  const defineTableHeaders = () => {
    // props.pageConfig
    if (pageConfig?.type === DEMAND_TAG_PAGE && info?.format === 'DISPLAY') {
      return isAdminMP
        ? DEMAND_TAG_PAGE_TABLE_HEADERS_FOR_DISPLAY_FORMAT
        : DEMAND_TAG_PAGE_TABLE_HEADERS_FOR_DISPLAY_FORMAT.filter(
            (item) => !['REVENUE', 'RPM', 'ERPM', 'PROFIT', 'TIER_PRIORITY', 'priority'].includes(item.id),
          ).map((item) => {
            if (item.id === 'GROSS_REVENUE') {
              return { ...item, label: 'Pub Revenue' };
            }
            if (item.id === 'GROSS_RPM') {
              return { ...item, label: 'Ad RPM' };
            }
            return item;
          });
    }

    // props.pageConfig
    if (pageConfig?.type === SUPPLY_TAG_PAGE && info?.format === 'DISPLAY') {
      return !isAdminMP
        ? SUPPLY_TAG_PAGE_TABLE_HEADERS_FOR_DISPLAY_FORMAT.filter(
            (item) =>
              ![
                'TIER_PRIORITY',
                'priority',
                'AD_SERVING_FEES',
                'REQUESTS',
                'BIDS',
                'GROSS_REVENUE',
                'PROFIT',
                'REVENUE',
                'EPPM',
                'NET_ERPM',
                'REQ_EPPM',
                'REQ_NET_ERPM',
                'CTR',
                'ACTUAL_RPM',
                'STATUS',
              ].includes(item.id),
          )
        : SUPPLY_TAG_PAGE_TABLE_HEADERS_FOR_DISPLAY_FORMAT.filter((item) => !['PUB_REVENUE'].includes(item.id));
    }

    return pageConfig.tableHeaders;
  };

  const defineTableCells = () => {
    // props.pageConfig
    if (pageConfig?.type === DEMAND_TAG_PAGE && info?.format === 'DISPLAY') {
      return isAdminMP
        ? DEMAND_TAG_PAGE_TABLE_CELLS_FOR_DISPLAY_FORMAT
        : DEMAND_TAG_PAGE_TABLE_CELLS_FOR_DISPLAY_FORMAT.filter(
            (item) =>
              !['fields.REVENUE', 'fields.RPM', 'fields.ERPM', 'fields.PROFIT', 'tier', 'priority'].includes(item.id),
          );
    }

    // props.pageConfig
    if (pageConfig?.type === SUPPLY_TAG_PAGE && info?.format === 'DISPLAY') {
      return !isAdminMP
        ? SUPPLY_TAG_PAGE_TABLE_CELLS_FOR_DISPLAY_FORMAT.filter(
            (item) =>
              ![
                'tier',
                'priority',
                'adServingFee',
                'fields.REQUESTS',
                'fields.BIDS',
                'fields.GROSS_REVENUE',
                'fields.PROFIT',
                'fields.REVENUE',
                'fields.EPPM',
                'fields.NET_ERPM',
                'fields.REQ_EPPM',
                'fields.REQ_NET_ERPM',
                'fields.CTR',
                'fields.ACTUAL_RPM',
                'status',
              ].includes(item.key),
          )
        : SUPPLY_TAG_PAGE_TABLE_CELLS_FOR_DISPLAY_FORMAT.filter((item) => !['fields.PUB_REVENUE'].includes(item.key));
    }

    return pageConfig.tableCells;
  };

  return (
    pageConfig && (
      <div className={styles.Main}>
        <Grid container justifyContent="center" className={styles.InfoContainer}>
          <Grid container flexWrap="nowrap">
            <Total rows={defineTotalInfoRows()} info={total} rowsInColumn={pageConfig.rowsInColumn} />
            <div className={styles.ChartContainer}>
              <Chart
                chartTab={chartTab}
                chartData={chartData}
                chartHistory={chartHistory}
                getChartData={getChartData}
                setChartTab={setChartTab}
                pageConfig={pageConfig}
                timeIntervalFilter={timeIntervalFilter}
                comparisonFilter={comparisonFilter}
                setTimeIntervalFilter={setTimeIntervalFilter}
                setComparisonFilter={setComparisonFilter}
                isChartLoading={isChartLoading}
                stopRefreshInterval={props.stopRefreshInterval}
                resetRefreshInterval={props.resetRefreshInterval}
              />
            </div>
          </Grid>
        </Grid>

        <div className={styles.TableFiltersContainer}>
          <Stack spacing={2} alignItems="center" direction="row" className={styles.Search}>
            <TextField
              className={styles.SearchInput}
              id="search"
              placeholder="Search"
              value={search}
              onChange={(event) => {
                dispatch(actions.setSearchAction(event.target.value));
              }}
              onFocus={props.stopRefreshInterval}
              onBlur={props.resetRefreshInterval}
              InputProps={{
                endAdornment: (
                  <InputAdornment position="end">
                    <SearchRounded />
                  </InputAdornment>
                ),
              }}
              variant="outlined"
              size="small"
            />

            {pageConfig.showDownloadCSVButton && (
              <Tooltip title="Download CSV" placement="top">
                <IconButton onClick={downloadCSV} size="small">
                  <CustomCsvFilled />
                </IconButton>
              </Tooltip>
            )}

            {pageConfig.tableFilters?.length && (
              <Stack spacing={2} direction="row" alignItems="center" className={styles.Filters}>
                <Divider orientation="vertical" flexItem />
                <FilterAlt color="shades.900" fontSize="medium" />
                <Select
                  className={styles.Status}
                  variant="outlined"
                  size="small"
                  id="table-filter"
                  value={filterByStatus}
                  onChange={(event) => {
                    dispatch(actions.setFilterByStatusAction(event.target.value));
                  }}
                  onOpen={props.stopRefreshInterval}
                  onClose={props.resetRefreshInterval}
                  displayEmpty
                  inputProps={{ 'aria-label': 'Without label' }}
                >
                  <MenuItem value={null} disabled className={styles.DefaultSelectProp}>
                    Filter By
                  </MenuItem>
                  {pageConfig.tableFilters.map((item) => (
                    <MenuItem key={item.value} value={item.value}>
                      {item.label}
                    </MenuItem>
                  ))}
                </Select>
                {pageConfig.showFilterByLabel && (
                  <Autocomplete
                    className={styles.Filter}
                    id="labelFilter"
                    size="small"
                    value={filterByLabel}
                    options={labelsOptions}
                    optionLabelKey="value"
                    onChange={(e, newValue) => {
                      dispatch(actions.setFilterByLabelAction(newValue));
                    }}
                    renderInput={(params) => (
                      <TextField
                        {...params}
                        placeholder="Label"
                        onChange={(e) => {
                          dispatch(
                            actions.getLabelsForTableFilterAction({
                              prefix: e.target.value,
                            }),
                          );
                        }}
                        variant="outlined"
                        size="small"
                        fullWidth
                      />
                    )}
                  />
                )}
              </Stack>
            )}
          </Stack>

          {isAdminMP && !!supply?.waterfallNote?.length && (
            <div className={styles.Note}>
              <Tooltip title={supply.waterfallNote} placement="top">
                <span>
                  <span className={styles.NoteContent}>{'WF Note: '}</span>
                  <span className={styles.NoteContent}>{supply.waterfallNote}</span>
                </span>
              </Tooltip>
            </div>
          )}

          <Stack spacing={2} direction="row" alignItems="center" className={styles.Actions}>
            {pageConfig.bulkActions?.length && (
              <Select
                variant="outlined"
                size="small"
                id="bulk-actions"
                value=""
                displayEmpty
                inputProps={{ 'aria-label': 'Without label' }}
                onOpen={props.stopRefreshInterval}
                onClose={props.resetRefreshInterval}
                startAdornment={
                  <InputAdornment position="start">
                    <Settings />
                  </InputAdornment>
                }
              >
                <MenuItem value="" disabled className={styles.DefaultSelectProp}>
                  Bulk Actions
                </MenuItem>
                {pageConfig.bulkActions.map((item) => (
                  <MenuItem
                    key={item.label}
                    value={item.label}
                    onClick={() => {
                      item.onClick({ selected });
                      setSelected([]);
                    }}
                    disabled={!selected?.length}
                  >
                    {item.label}
                  </MenuItem>
                ))}
              </Select>
            )}

            {pageConfig.plusButton && (
              <Button
                variant="contained"
                size="small"
                color="primary"
                data-id="plusButton"
                onClick={() => {
                  // props.pageConfig
                  if (pageConfig.type === DEMAND_ADVERTISER_PAGE) {
                    pageConfig.plusButton.onClick({
                      queries: {
                        advertiserTier: info?.tier,
                        publisherDemand: info?.publisherDemand,
                      },
                    });
                    // props.pageConfig
                  } else if (pageConfig.type === SUPPLY_SITE_PAGE) {
                    pageConfig.plusButton.onClick({
                      queries: {
                        accountType: info?.accountType,
                      },
                    });
                  } else {
                    pageConfig.plusButton.onClick();
                  }
                }}
                startIcon={<Add />}
              >
                {pageConfig.plusButton.label}
              </Button>
            )}
          </Stack>
        </div>

        <div className={styles.Table}>
          <Table
            headers={defineTableHeaders()}
            cells={defineTableCells()}
            rows={data}
            selecting={pageConfig.tableSelecting}
            selected={selected}
            setSelected={setSelected}
            cellRenderer={pageConfig.cellRenderer}
            setRowBackgroundBy={pageConfig.setRowBackgroundBy && setRowBackgroundByTierValue}
            sortOrder={sortOrder}
            sortBy={sortBy}
            handleSorting={handleSorting}
            page={page}
            rowsPerPage={rowsPerPage}
            onChangePage={onChangePage}
            setRowsPerPage={setRowsPerPage}
            totalCount={totalCount}
            rowsPerPageOptions={pageConfig.rowsPerPageOptions}
            createRowLink={createRowLink}
            isOpenNewTab={pageConfig.isOpenNewTab}
            stopRefreshInterval={props.stopRefreshInterval}
            resetRefreshInterval={props.resetRefreshInterval}
            isLoading={isLoading}
          />
        </div>
      </div>
    )
  );
}

Main.propTypes = {
  stopRefreshInterval: PropTypes.func.isRequired,
  resetRefreshInterval: PropTypes.func.isRequired,
};

export default Main;
