import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { Delete } from '@mui/icons-material';

import { LUMINOUSX } from '../constants';

import * as entitiesSelectors from '../redux/selectors';
import { mergeEntitiesAction } from '../redux/slices';

import {
  Button,
  Checkbox,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  Radio,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
} from '@/mui/components';

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

const getApprovedEntities = (entities) => entities.filter((entity) => entity.types?.includes(LUMINOUSX));
const getDefaultPrimary = (entities) => {
  if (!entities.length) return null;

  const approvedEntities = getApprovedEntities(entities);

  if (approvedEntities.length > 0) {
    // If multiple approved, take the one with the most videos
    return approvedEntities.reduce((max, entity) => (entity.counterVideos > max.counterVideos ? entity : max)).id;
  }

  // No approved entities, take the one with the most videos
  return entities.reduce((max, entity) => (entity.counterVideos > max.counterVideos ? entity : max)).id;
};

function MergeEntitiesDialog(props) {
  const dispatch = useDispatch();
  const data = useSelector(entitiesSelectors.dataSelector);
  const isLoading = useSelector(entitiesSelectors.isMergeLoadingSelector);

  const entities = data.filter((d) => props.selectedRows.includes(d.id));

  const [entitiesForMerge, setEntitiesForMerge] = useState(entities);
  const [primary, setPrimary] = useState(null);
  const [alias, setAlias] = useState([]);

  const approvedEntities = getApprovedEntities(entitiesForMerge);
  const getShouldDisableApply = () =>
    entitiesForMerge.length <= 1 || approvedEntities.length > 1 || approvedEntities.some((ent) => ent.id !== primary);

  const handleRemove = (id) => {
    if (primary === id) {
      setPrimary(null);
    }
    setEntitiesForMerge(entitiesForMerge.filter((d) => d.id !== id));
  };

  const handleApply = () => {
    dispatch(mergeEntitiesAction({ entitiesForMerge, primary, alias, callback: props.onClose }));
  };

  useEffect(() => {
    if (!primary) {
      setPrimary(getDefaultPrimary(entitiesForMerge));
    }
  }, [primary]);

  return (
    <Dialog open={props.open} onClose={props.onClose} max Width="lg">
      <DialogTitle onClose={props.onClose}>Merge Entities</DialogTitle>
      <DialogContent>
        <Stack>
          <TableContainer className={styles.TableContainer}>
            <Table size="small" stickyHeader>
              <TableHead>
                <TableRow>
                  <TableCell>Name</TableCell>
                  <TableCell width="72">Primary</TableCell>
                  <TableCell width="110">Save as Alias</TableCell>
                  <TableCell width="105">X-Ray Status</TableCell>
                  <TableCell width="72">Videos</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {entitiesForMerge.map((row) => (
                  <TableRow key={row.id}>
                    <TableCell>{row.value}</TableCell>
                    <TableCell>
                      <Radio
                        color="primary"
                        size="small"
                        disabled={isLoading}
                        checked={primary === row.id}
                        onChange={() => {
                          setPrimary(row.id);
                          setAlias((prev) => prev.filter((a) => a !== row.id));
                        }}
                      />
                    </TableCell>
                    <TableCell>
                      <Checkbox
                        color="primary"
                        size="small"
                        checked={alias.includes(row.id)}
                        disabled={isLoading || primary === row.id}
                        onChange={() =>
                          setAlias((prev) =>
                            prev.includes(row.id) ? prev.filter((a) => a !== row.id) : [...prev, row.id],
                          )
                        }
                      />
                    </TableCell>
                    <TableCell>{row.types?.includes(LUMINOUSX) ? 'Enabled' : 'Disabled'}</TableCell>
                    <TableCell className={styles.WithActions}>
                      <Stack direction="row" alignItems="center" gap={1}>
                        {row.counterVideos}
                        <IconButton
                          className={styles.Action}
                          size="xSmall"
                          disabled={isLoading}
                          onClick={() => handleRemove(row.id)}
                        >
                          <Delete />
                        </IconButton>
                      </Stack>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button size="small" variant="outlined" color="primary" onClick={props.onClose}>
          Cancel
        </Button>
        <Button
          disabled={isLoading || getShouldDisableApply()}
          size="small"
          variant="contained"
          color="primary"
          onClick={handleApply}
        >
          Merge
        </Button>
      </DialogActions>
    </Dialog>
  );
}

MergeEntitiesDialog.propTypes = {
  open: PropTypes.bool.isRequired,
  selectedRows: PropTypes.arrayOf(PropTypes.string).isRequired,
  onClose: PropTypes.func.isRequired,
  onApply: PropTypes.func.isRequired,
};

export default MergeEntitiesDialog;
