import React, { useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import dayjs from 'dayjs';
import { useRouter } from 'next/router';
import { AddRounded, ContentCopyRounded, DeleteRounded, FilterAltRounded, SearchRounded } from '@mui/icons-material';

import { DELETE_FORM_TEMPLATES, POST_FORM_TEMPLATES } from '@/modules/@common/acl/constants';
import { SORT_ASC, SORT_DESC } from '@/modules/@common/constants/sort';
import { SEARCH_TEXT_MAX_LENGTH, TEMPLATE_CATEGORY_ALL } from '@/modules/forms/constants';
import { TABLE_HEADER } from '@/modules/forms/templates/constants';

import * as templateSelectors from '../redux/selectors';
import { deleteTemplateAction, getCategoryOptionsAction, getTemplatesAction, setFieldAction } from '../redux/slices';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserAccountIdSelector, getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';
import { strippedHtml } from '@/modules/forms/templates/helpers';

import { TableCellActions } from '@/modules/@common/Table';
import {
  Autocomplete,
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  Grid,
  IconButton,
  InputAdornment,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  TableScroll,
  TableSortLabel,
  TextField,
  Tooltip,
  Typography,
} from '@/mui/components';

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

function Templates() {
  const router = useRouter();
  const [removeConfirm, setRemoveConfirm] = useState(null);
  const dispatch = useDispatch();
  const templates = useSelector(templateSelectors.templatesSelector);
  const page = useSelector(templateSelectors.pageSelector);
  const pageSize = useSelector(templateSelectors.pageSizeSelector);
  const totalCount = useSelector(templateSelectors.totalCountSelector);
  const searchText = useSelector(templateSelectors.searchTextSelector);
  const sortBy = useSelector(templateSelectors.sortBySelector);
  const sortOrder = useSelector(templateSelectors.sortOrderSelector);
  const formTemplateCategoryId = useSelector(templateSelectors.formTemplateCategoryIdSelector);
  const formTemplateCategoryOptions = useSelector(templateSelectors.formTemplateCategoryOptionsSelector);

  const userPermissions = useSelector(getUserPermissionsSelector);

  const userAccountId = useSelector(getUserAccountIdSelector);

  const hasAccount = !!userAccountId;

  const tableHeaders = TABLE_HEADER.filter((header) => !hasAccount || header.id !== 'account.name');

  const handleFilter = (filterObject) => {
    dispatch(setFieldAction(filterObject));
    dispatch(getTemplatesAction());
  };

  const handleShowRemoveConfirm = (template) => setRemoveConfirm(template);

  const handleRemoveConfirm = () => {
    dispatch(deleteTemplateAction(removeConfirm.id));
    setRemoveConfirm(null);
  };

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

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

  const formTemplateCategoryValue = useMemo(() => {
    const res = formTemplateCategoryOptions.find(({ value }) => value === formTemplateCategoryId);

    return !res || res?.value === TEMPLATE_CATEGORY_ALL ? TEMPLATE_CATEGORY_ALL : res;
  }, [formTemplateCategoryOptions]);

  // todo: migrate to <CommonList />
  return (
    <div>
      <Grid container alignItems="center" justifyContent="center" className={styles.Title}>
        <Grid item xs={12}>
          <Typography variant="h6" color="text.primary" fontWeight={400}>
            Form Templates
          </Typography>
        </Grid>
      </Grid>
      <Grid container alignItems="center" justifyContent="center" className={styles.Controls}>
        <Grid container alignItems="center" justifyContent="space-between">
          <Grid item container xs={8}>
            <Grid item>
              <TextField
                id="search"
                size="small"
                className={styles.Search}
                value={searchText}
                onChange={({ target }) => handleFilter({ searchText: target.value, page: 1 })}
                placeholder="Search"
                inputProps={{
                  autoComplete: 'off',
                  maxLength: SEARCH_TEXT_MAX_LENGTH,
                }}
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <IconButton onClick={() => null}>
                        <SearchRounded />
                      </IconButton>
                    </InputAdornment>
                  ),
                }}
                variant="outlined"
              />
            </Grid>
            <Grid item className={styles.FilterSeparator}>
              <Stack spacing={1} direction="row" alignItems="center">
                <Divider orientation="vertical" flexItem />
                <FilterAltRounded color="shades.900" fontSize="medium" />
              </Stack>
            </Grid>
            <Grid item className={styles.FilterStatusControl}>
              <Autocomplete
                className={styles.StatusSelect}
                value={
                  formTemplateCategoryValue && formTemplateCategoryValue !== TEMPLATE_CATEGORY_ALL
                    ? formTemplateCategoryValue
                    : ''
                }
                options={formTemplateCategoryOptions.filter(({ value }) => value !== TEMPLATE_CATEGORY_ALL)}
                size="small"
                onChange={(e, selected$) =>
                  handleFilter({
                    formTemplateCategoryId: !selected$?.value ? TEMPLATE_CATEGORY_ALL : selected$.value,
                    page: 1,
                  })
                }
                renderInput={(params) => <TextField {...params} placeholder="Categories" />}
              />
            </Grid>
          </Grid>
          <Grid item container xs={4} justifyContent="flex-end">
            {hasPermission(POST_FORM_TEMPLATES, userPermissions) && (
              <Button
                data-id="new"
                size="small"
                variant="contained"
                color="primary"
                onClick={() => router.push('/form-templates/new')}
                startIcon={<AddRounded />}
              >
                Template
              </Button>
            )}
          </Grid>
        </Grid>
      </Grid>
      <Grid container className={styles.TableWrapper}>
        <TableContainer>
          <TableScroll>
            <Table size="large">
              <TableHead>
                <TableRow>
                  {tableHeaders.map((header) => (
                    <TableCell
                      padding={header.padding}
                      autoWidth={header.autoWidth}
                      width={header.width ?? 'inherit'}
                      data-id={`header-${header.id}`}
                      key={header.id}
                      sortDirection={sortBy === header.id ? sortOrder.toLowerCase() : false}
                    >
                      {header.sortable && (
                        <TableSortLabel
                          active={sortBy === header.id}
                          direction={sortBy === header.id ? sortOrder.toLowerCase() : SORT_ASC}
                          onClick={() =>
                            handleFilter({
                              sortBy: header.id,
                              sortOrder: sortOrder === SORT_ASC ? SORT_DESC : SORT_ASC,
                              page: 1,
                            })
                          }
                        >
                          {header.label}
                        </TableSortLabel>
                      )}
                      {!header.sortable && header.label}
                    </TableCell>
                  ))}
                </TableRow>
              </TableHead>
              <TableBody>
                {templates.map((row) => (
                  <TableRow
                    hover
                    onClick={() => router.push(`/form-templates/${row.id}`)}
                    key={row.id}
                    className={styles.Row}
                  >
                    <TableCell component="th" scope="row">
                      {row.id}
                    </TableCell>
                    <TableCell component="th" scope="row">
                      <div className={styles.NoWrap}>{row.formTemplateCategory?.name}</div>
                    </TableCell>
                    {!hasAccount && (
                      <TableCell component="th" scope="row">
                        <div className={styles.NoWrap}>{row.account?.name ?? 'All accounts'}</div>
                      </TableCell>
                    )}
                    <TableCell component="th" scope="row">
                      <div className={styles.NoWrap}>{row.name}</div>
                    </TableCell>
                    <TableCell component="th" scope="row">
                      <div className={styles.NoWrap}>{strippedHtml(row.title)}</div>
                    </TableCell>
                    <TableCell component="th" scope="row">
                      <div className={styles.NoWrap}>{row.updatedBy}</div>
                    </TableCell>
                    <TableCell component="th" scope="row">
                      <div className={styles.NoWrap}>{dayjs(row.updatedAt).format('MMM D, YYYY hh:mm A')}</div>
                    </TableCell>
                    <TableCellActions>
                      {hasPermission(POST_FORM_TEMPLATES, userPermissions) && (
                        <Tooltip title="Duplicate template" disableInteractive>
                          <IconButton
                            size="small"
                            onClick={(e) => {
                              e.stopPropagation();
                              router.push(`/form-templates/${row.id}/duplicate`);
                            }}
                          >
                            <ContentCopyRounded />
                          </IconButton>
                        </Tooltip>
                      )}
                      {hasPermission(DELETE_FORM_TEMPLATES, userPermissions) && (
                        <Tooltip title="Delete template" disableInteractive>
                          <IconButton
                            size="small"
                            onClick={(e) => {
                              e.stopPropagation();
                              handleShowRemoveConfirm(row);
                            }}
                          >
                            <DeleteRounded />
                          </IconButton>
                        </Tooltip>
                      )}
                    </TableCellActions>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableScroll>
          {!!totalCount && (
            <TablePagination
              rowsPerPageOptions={[10, 15, 25]}
              count={totalCount}
              rowsPerPage={pageSize}
              page={page}
              onPageChange={(event, selectedPage) => handleFilter({ page: selectedPage })}
              onRowsPerPageChange={(event) =>
                handleFilter({
                  pageSize: parseInt(event.target.value, 10),
                  page: 1,
                })
              }
              component="div"
            />
          )}
        </TableContainer>
      </Grid>

      <Dialog open={!!removeConfirm?.id} onClose={() => setRemoveConfirm(null)} maxWidth="md">
        <DialogTitle>Remove Confirm</DialogTitle>
        <DialogContent>{`Are you sure you want to remove template "${removeConfirm?.name}" ?`}</DialogContent>
        <DialogActions>
          <Button size="small" variant="outlined" color="primary" onClick={() => setRemoveConfirm(null)}>
            Cancel
          </Button>
          <Button size="small" variant="contained" color="primary" onClick={handleRemoveConfirm}>
            Delete
          </Button>
        </DialogActions>
      </Dialog>
    </div>
  );
}

export default Templates;
