import React, { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import dayjs from 'dayjs';
import { useRouter } from 'next/router';
import { Cancel, CheckCircle, ContentCopyRounded } from '@mui/icons-material';

import { PAGE_CONFIG, TABS, TABS_SELF_SERVE } from '../constants';
import { PCN_GET_MARKETPLACE_DASHBOARD } from '@/modules/@common/acl/constants';
import { SORT_ASC, SORT_DESC } from '@/modules/@common/constants/sort';
import { CUSTOM_PARENT_STICKY_CLASS_NAME } from '@/modules/marketplace/common/constants';

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

import { TableCellActions } from '@/modules/@common/Table';
import Header from '../../common/HeaderNew';
import Filters from './Filters';
import {
  Box,
  Checkbox,
  IconButton,
  Stack,
  Tab,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  TableScroll,
  TableSortLabel,
  Tabs,
  Tooltip,
} from '@/mui/components';

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

const STATUS_ICON = {
  ACTIVE: (
    <IconButton size="small" color="success" onClick={() => null}>
      <CheckCircle />
    </IconButton>
  ),
  DISABLED: (
    <IconButton size="small" color="error" onClick={() => null}>
      <Cancel />
    </IconButton>
  ),
  DELETED: (
    <IconButton size="small" color="error" onClick={() => null}>
      <Cancel />
    </IconButton>
  ),
};

function KeyLists() {
  const dispatch = useDispatch();

  const userTimezone = useSelector(getUserTimezoneSelector);
  const userPermissions = useSelector(getUserPermissionsSelector);

  const tab = useSelector(selectors.tabSelector);
  const search = useSelector(selectors.searchSelector);
  const status = useSelector(selectors.statusSelector);
  const totalCount = useSelector(selectors.totalCountSelector);
  const page = useSelector(selectors.pageSelector);
  const rowsPerPage = useSelector(selectors.rowsPerPageSelector);
  const sortBy = useSelector(selectors.sortBySelector);
  const sortOrder = useSelector(selectors.sortOrderSelector);
  const keyLists = useSelector(selectors.keyListsSelector);

  const setField = (o) => dispatch(actions.setFieldAction(o));

  const isAdminMP = hasPermission(PCN_GET_MARKETPLACE_DASHBOARD, userPermissions);

  const router = useRouter();
  const [pageConfig, setPageConfig] = useState(PAGE_CONFIG.keys);
  const [selected, setSelected] = useState([]);

  const isListsPage = router.pathname.includes('/lists');

  const fetchData = () => {
    if (router.pathname.includes('/keys')) {
      dispatch(actions.searchAvailableKeysAction());
    }

    if (isListsPage) {
      dispatch(actions.searchKeyListsAction());
    }
  };

  const bulkUpdate = (value) => {
    if (router.pathname.includes('/keys')) {
      dispatch(
        actions.bulkUpdateAvailableKeysAction({
          ids: selected,
          status: value,
        }),
      );
    }

    if (isListsPage) {
      dispatch(
        actions.bulkUpdateKeyListsAction({
          ids: selected,
          status: value,
        }),
      );
    }
  };

  useEffect(() => {
    if (isAdminMP) {
      fetchData();
    } else {
      dispatch(actions.getHubsAndDemandAccountsAction());
    }

    if (router.pathname.includes('/keys')) {
      dispatch(actions.setFieldAction({ tab: 0 }));
    }

    if (isListsPage) {
      dispatch(actions.setFieldAction({ tab: isAdminMP ? 1 : 0 }));
    }
  }, []);

  useEffect(() => {
    if (router.pathname.includes('/keys')) {
      setPageConfig(PAGE_CONFIG.keys);
    }

    if (isListsPage) {
      setPageConfig(PAGE_CONFIG.lists);
    }
  }, [router.pathname]);

  const handleSelectAllClick = (event) => {
    if (event.target.checked) {
      const newSelected = keyLists.map((item) => item.id);
      setSelected(newSelected);
      return;
    }
    setSelected([]);
  };

  const handleSelect = (id) => {
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(selected.slice(0, selectedIndex), selected.slice(selectedIndex + 1));
    }

    setSelected(newSelected);
  };

  const createNewDomain = () => router.push(`${pageConfig.link}/new`);

  const handleRowClick = (id) => {
    router.push(`${pageConfig.link}/${id}`);
  };

  const handleSorting = (id) => {
    const isAsc = sortBy === id && sortOrder === 'ASC';

    dispatch(
      actions.setFieldAction({
        sortOrder: isAsc ? 'DESC' : 'ASC',
        sortBy: id,
        page: 0,
      }),
    );

    fetchData();
  };

  const handleBulkUpdate = (newStatus) => {
    bulkUpdate(newStatus);
    setSelected([]);
  };

  const tabs = isAdminMP ? TABS : TABS_SELF_SERVE;

  const tableRef = useRef(null);
  const tableHeaderRef = useRef(null);

  useEffect(() => {
    const step = (event) => {
      if (tableHeaderRef.current && tableRef.current) {
        const top = getNumberInRange(
          (tableRef.current.getBoundingClientRect().y - (event.target.getBoundingClientRect?.().y ?? 0)) * -1,
          0,
          tableRef.current.clientHeight - tableHeaderRef.current.clientHeight * 2,
        );

        tableHeaderRef.current.style.transform = `translateY(${top}px)`;
      }
    };

    const subscribeParent = tableRef.current.closest(`.${CUSTOM_PARENT_STICKY_CLASS_NAME}`) || document;

    subscribeParent.addEventListener('scroll', step);

    return () => {
      subscribeParent.removeEventListener('scroll', step);
    };
  }, [tableRef.current, tableHeaderRef.current]);

  return (
    <div className={styles.Wrapper}>
      <Header />
      <Stack direction="row" alignItems="center" justifyContent="flex-start" className={styles.Controls}>
        <Tabs className={styles.Tabs} value={tab}>
          {tabs.map((item, index) => (
            <Tab
              data-id={item.label}
              key={item.label}
              label={item.label}
              onClick={() => {
                dispatch(actions.setFieldAction({ tab: index }));
                router.push(item.link);
                dispatch(actions.setInitialListsStateAction());
              }}
              disabled={!isAdminMP}
            />
          ))}
        </Tabs>
      </Stack>
      <Stack direction="row" fullWidth alignItems="center" className={styles.Filters}>
        <Filters
          search={search}
          setField={setField}
          filterStatus={status}
          fetchData={fetchData}
          handleBulkUpdate={handleBulkUpdate}
          disabledBulk={!selected?.length}
          onCreateNew={createNewDomain}
          addButtonText={pageConfig.addButtonText}
        />
      </Stack>
      <div className={styles.Body}>
        <TableContainer>
          <TableScroll>
            <Table ref={tableRef} className={styles.Table} size="large" aria-label="table">
              <TableHead ref={tableHeaderRef}>
                <TableRow>
                  <TableCell padding="checkbox" align="center">
                    <Checkbox
                      color="primary"
                      indeterminate={selected?.length && selected?.length < keyLists?.length}
                      checked={keyLists?.length && selected?.length === keyLists?.length}
                      onChange={handleSelectAllClick}
                      inputProps={{ 'aria-label': 'select all' }}
                    />
                  </TableCell>

                  {pageConfig.tableHeaders?.map((header, index) => (
                    <TableCell key={`${header.id}-${index + 1}`}>
                      {header.isSortable && (
                        <TableSortLabel
                          active={sortBy === header.id}
                          direction={sortBy === header.id ? sortOrder?.toLowerCase() : SORT_ASC}
                          onClick={() => {
                            handleSorting(header.id);
                          }}
                        >
                          {header.label}
                          {sortBy === header.id ? (
                            <Box component="span" className={styles.VisibilityHidden}>
                              {sortOrder === SORT_DESC ? 'sorted descending' : 'sorted ascending'}
                            </Box>
                          ) : null}
                        </TableSortLabel>
                      )}
                      {!header.isSortable && header.label}
                    </TableCell>
                  ))}
                </TableRow>
              </TableHead>
              <TableBody>
                {keyLists.map(
                  (
                    { id, name, key, count, user, updatedBy, created, updated, status: statusKeyList, daccountName },
                    index,
                  ) => (
                    <TableRow
                      className={styles.Row}
                      key={id}
                      onClick={() => {
                        handleRowClick(id);
                      }}
                    >
                      <TableCell padding="checkbox" align="center">
                        <Checkbox
                          color="primary"
                          checked={selected.indexOf(id) !== -1}
                          onChange={() => {
                            handleSelect(id);
                          }}
                          inputProps={{ 'aria-labelledby': `enhanced-table-checkbox-${index}` }}
                          onClick={(e) => e.stopPropagation()}
                        />
                      </TableCell>
                      <TableCell>
                        {name?.length > 50 ? (
                          <Tooltip title={name}>
                            <span>{`${name.substring(0, 50)}...`}</span>
                          </Tooltip>
                        ) : (
                          name
                        )}
                      </TableCell>
                      <TableCell>
                        {key?.length > 50 ? (
                          <Tooltip title={key}>
                            <span>{`${key.substring(0, 50)}...`}</span>
                          </Tooltip>
                        ) : (
                          key || count
                        )}
                      </TableCell>
                      <TableCell>{user || updatedBy}</TableCell>
                      <TableCell>
                        {dayjs(updated || created)
                          .tz(userTimezone)
                          .format('DD-MMM-YY HH:mm A')}
                      </TableCell>

                      {isListsPage && <TableCell>{daccountName || ''}</TableCell>}

                      <TableCell>{STATUS_ICON[statusKeyList]}</TableCell>

                      {isListsPage && (
                        <TableCellActions>
                          <IconButton
                            size="small"
                            color="neutral"
                            onClick={(e) => {
                              e.stopPropagation();
                              router.push(`${pageConfig.link}/${id}?duplicate`);
                            }}
                          >
                            <ContentCopyRounded />
                          </IconButton>
                        </TableCellActions>
                      )}
                    </TableRow>
                  ),
                )}
              </TableBody>
            </Table>
          </TableScroll>
          <TablePagination
            component="div"
            size="small"
            rowsPerPageOptions={[10, 25, 50, 100, 200]}
            count={totalCount}
            rowsPerPage={rowsPerPage}
            page={page + 1}
            onPageChange={(event, newPage) => {
              dispatch(actions.setFieldAction({ page: newPage - 1 }));
              fetchData();
            }}
            onRowsPerPageChange={(event) => {
              dispatch(
                actions.setFieldAction({
                  rowsPerPage: +event.target.value,
                  page: 0,
                }),
              );
              fetchData();
            }}
          />
        </TableContainer>
      </div>
    </div>
  );
}

export default KeyLists;
