import React, { useEffect, useState } from 'react';
import dayjs from 'dayjs';
import timezonePlugin from 'dayjs/plugin/timezone';
import utcPlugin from 'dayjs/plugin/utc';
import { useRouter } from 'next/router';
import { AddRounded, DownloadRounded, FilterAltRounded, SearchRounded } from '@mui/icons-material';

import { STATUS_ACTIVE, TYPE_INSTAGRAM, TYPE_SHAREPOINT } from '../../constants';
import { SEARCH_TEXT_MAX_LENGTH, STATUS_OPTIONS, TYPE_MENU_OPTIONS } from '../constants';

import type { FeedsDataRecordType, StateFiltersType, StateTableSliceType } from '../types';

import { getConfigHeaders, typeToUrlSegment } from '../helpers';
import * as selectors from '../redux/selectors';
import { getDataAction, setAction, setTableAction } from '../redux/slices';
import { omitUndefinedProps } from '@/mui/helpers';

import CommonList from '@/modules/@common/List';
import { useAppDispatch, useAppSelector } from '@/modules/@common/store/hooks';
import CommonTable, { TableCellActions } from '@/modules/@common/Table';
import Empty from '../components/Empty/Empty';
import ImportDialog from '../components/ImportDialog/ImportDialog';
import StatusCell from '../components/StatusCell/StatusCell';
import TypeCell from '../components/TypeCell/TypeCell';
import {
  Autocomplete,
  Button,
  Divider,
  IconButton,
  InputAdornment,
  Menu,
  MenuItem,
  Stack,
  TableCell,
  TableRow,
  TextField,
  Tooltip,
} from '@/mui/components';

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

dayjs.extend(utcPlugin);
dayjs.extend(timezonePlugin);

type StateFlattenType = StateTableSliceType & StateFiltersType;

function List() {
  const router = useRouter();
  const dispatch = useAppDispatch();

  const [showCreateMenu, setShowCreateMenu] = useState<HTMLButtonElement | null>(null);
  const [showImportDialog, setShowImportDialog] = useState<number | null>(null);

  const data = useAppSelector(selectors.dataSelector);
  const page = useAppSelector(selectors.pageSelector);
  const pageSize = useAppSelector(selectors.pageSizeSelector);
  const totalCount = useAppSelector(selectors.totalCountSelector);
  const sortBy = useAppSelector(selectors.sortBySelector);
  const sortOrder = useAppSelector(selectors.sortOrderSelector);
  const selected = useAppSelector(selectors.selectedSelector);

  // filters
  const searchText = useAppSelector(selectors.searchTextSelector);
  const status = useAppSelector(selectors.statusSelector);

  const shouldShowEmpty = useAppSelector(selectors.shouldShowEmptySelector);

  const handleFilter = (filter: Partial<StateFlattenType>) => {
    const { sortBy: sortBy$, sortOrder: sortOrder$, page: page$, pageSize: pageSize$, ...mainState } = filter;

    const res = omitUndefinedProps({
      sortBy: sortBy$,
      sortOrder: sortOrder$,
      page: page$,
      pageSize: pageSize$,
      selected: [],
    });

    dispatch(setTableAction(res));

    dispatch(setAction({ ...mainState }));
    dispatch(getDataAction());
  };

  useEffect(() => {
    dispatch(getDataAction());
  }, []);

  return (
    <CommonList
      title="Sources"
      renderFilters={
        <Stack direction="row" alignItems="center" spacing={2}>
          <div>
            <TextField
              className={styles.SearchField}
              size="small"
              placeholder="Search"
              value={searchText}
              onChange={({ target }) => handleFilter({ searchText: target.value, page: 1 })}
              inputProps={{
                autoComplete: 'off',
                maxLength: SEARCH_TEXT_MAX_LENGTH,
              }}
              InputProps={{
                endAdornment: (
                  <InputAdornment position="end">
                    <IconButton onClick={() => null}>
                      <SearchRounded />
                    </IconButton>
                  </InputAdornment>
                ),
              }}
              variant="outlined"
              disabled={shouldShowEmpty}
            />
          </div>

          <Stack spacing={1} direction="row" alignItems="center">
            <Divider orientation="vertical" flexItem />
            <FilterAltRounded fontSize="medium" />
          </Stack>

          <Autocomplete
            className={styles.StatusSelect}
            size="small"
            optionLabelKey="label"
            optionValueKey="value"
            value={STATUS_OPTIONS.find((o) => o.value === status) || null}
            options={STATUS_OPTIONS}
            renderInput={(params$) => <TextField {...params$} size="small" placeholder="Status" variant="outlined" />}
            onChange={(e, selected$) => {
              const selectedStatus = selected$ as { value: StateFlattenType['status'] };
              handleFilter({
                status: selectedStatus?.value || null,
                page: 1,
              });
            }}
          />
        </Stack>
      }
      renderActions={
        <Tooltip title="Source">
          <>
            <Button
              size="small"
              variant="contained"
              color="primary"
              startIcon={<AddRounded />}
              onClick={({ currentTarget }) => setShowCreateMenu(currentTarget)}
            >
              Source
            </Button>
            <Menu anchorEl={showCreateMenu} open={Boolean(showCreateMenu)} onClose={() => setShowCreateMenu(null)}>
              {TYPE_MENU_OPTIONS.map((menu) => (
                <MenuItem key={menu.value} onClick={() => router.push(`/feeds/new/${typeToUrlSegment(menu.value)}`)}>
                  {menu.label}
                </MenuItem>
              ))}
            </Menu>
          </>
        </Tooltip>
      }
    >
      {shouldShowEmpty ? (
        <Empty />
      ) : (
        <CommonTable
          configHeaders={getConfigHeaders()}
          configRenderRow={(row: FeedsDataRecordType) => {
            const shouldShowImport =
              row.status === STATUS_ACTIVE &&
              row.source?.isConnected &&
              !row.archived &&
              ![TYPE_SHAREPOINT, TYPE_INSTAGRAM].includes(row.type);

            return (
              <TableRow
                className={styles.Row}
                key={row.id}
                hover
                onClick={() => router.push(`/feeds/${row.id}/${typeToUrlSegment(row.type)}`)}
              >
                <TableCell>
                  <div className={styles.NoWrap}>{row.id}</div>
                </TableCell>
                <TableCell>{row.type && <TypeCell type={row.type} />}</TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.description}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.lang}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>
                    <StatusCell status={row.status} source={row.source} type={row.type} />
                  </div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.schedule_status ? 'On' : 'Off'}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.updatedBy}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{dayjs(row.updateDate).format('MMM D, YYYY hh:mm A')}</div>
                </TableCell>
                <TableCellActions>
                  {shouldShowImport && (
                    <Tooltip title="Import" disableInteractive>
                      <IconButton
                        size="small"
                        onClick={(e) => {
                          e.stopPropagation();
                          setShowImportDialog(row.id);
                        }}
                      >
                        <DownloadRounded />
                      </IconButton>
                    </Tooltip>
                  )}
                </TableCellActions>
              </TableRow>
            );
          }}
          data={data || []}
          selected={selected as unknown as never[]} // TypeScript see CommonTable selected props as never
          sortBy={sortBy}
          sortOrder={sortOrder}
          totalCount={totalCount}
          page={page}
          rowsPerPage={pageSize}
          onFilter={handleFilter}
        />
      )}

      {showImportDialog && <ImportDialog feedId={showImportDialog} onClose={() => setShowImportDialog(null)} />}
    </CommonList>
  );
}

export default List;
