import React, { useEffect, useReducer, useState, useContext } from "react";

import openSocket from "socket.io-client";

import {
  Button,
  IconButton,
  makeStyles,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  Typography,
} from "@material-ui/core";

import MainContainer from "../../components/MainContainer";
import MainHeader from "../../components/MainHeader";
import MainHeaderButtonsWrapper from "../../components/MainHeaderButtonsWrapper";
import TableRowSkeleton from "../../components/TableRowSkeleton";
import Title from "../../components/Title";
import { i18n } from "../../translate/i18n";
import toastError from "../../errors/toastError";
import api from "../../services/api";
import { DeleteOutline, Edit } from "@material-ui/icons";
import QueueModal from "../../components/QueueModal";
import { toast } from "react-toastify";
import ConfirmationModal from "../../components/ConfirmationModal";

import { AuthContext } from "../../context/Auth/AuthContext";
import { Can } from "../../components/Can";

const useStyles = makeStyles((theme) => ({
  mainPaper: {
    flex: 1,
    padding: theme.spacing(1),
    overflowY: "scroll",
    ...theme.scrollbarStyles,
  },
  customTableCell: {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
  },
}));

const reducer = (state, action) => {
  if (action.type === "LOAD_QUEUES") {
    const queues = action.payload;
    const newQueues = [];

    queues.forEach((queue) => {
      const queueIndex = state.findIndex((q) => q.id === queue.id);
      if (queueIndex !== -1) {
        state[queueIndex] = queue;
      } else {
        newQueues.push(queue);
      }
    });

    return [...state, ...newQueues];
  }

  if (action.type === "UPDATE_QUEUES") {
    const queue = action.payload;
    const queueIndex = state.findIndex((u) => u.id === queue.id);

    if (queueIndex !== -1) {
      state[queueIndex] = queue;
      return [...state];
    } else {
      return [queue, ...state];
    }
  }

  if (action.type === "DELETE_QUEUE") {
    const queueId = action.payload;
    const queueIndex = state.findIndex((q) => q.id === queueId);
    if (queueIndex !== -1) {
      state.splice(queueIndex, 1);
    }
    return [...state];
  }

  if (action.type === "RESET") {
    return [];
  }
};

const Queues = () => {
  const classes = useStyles();

  const { user } = useContext(AuthContext);

  const [queues, dispatch] = useReducer(reducer, []);
  const [loading, setLoading] = useState(false);

  const [queueModalOpen, setQueueModalOpen] = useState(false);
  const [selectedQueue, setSelectedQueue] = useState(null);
  const [confirmModalOpen, setConfirmModalOpen] = useState(false);

  useEffect(() => {
    (async () => {
      setLoading(true);
      try {
        const { data } = await api.get("/queue");
        dispatch({ type: "LOAD_QUEUES", payload: data });

        setLoading(false);
      } catch (err) {
        toastError(err);
        setLoading(false);
      }
    })();
  }, []);

  useEffect(() => {
    const socket = openSocket(process.env.REACT_APP_BACKEND_URL);

    socket.on("queue", (data) => {
      if (data.action === "update" || data.action === "create") {
        dispatch({ type: "UPDATE_QUEUES", payload: data.queue });
      }

      if (data.action === "delete") {
        dispatch({ type: "DELETE_QUEUE", payload: data.queueId });
      }
    });

    return () => {
      socket.disconnect();
    };
  }, []);

  const handleOpenQueueModal = () => {
    setQueueModalOpen(true);
    setSelectedQueue(null);
  };

  const handleCloseQueueModal = () => {
    setQueueModalOpen(false);
    setSelectedQueue(null);
  };

  const handleEditQueue = (queue) => {
    setSelectedQueue(queue);
    setQueueModalOpen(true);
  };

  const handleCloseConfirmationModal = () => {
    setConfirmModalOpen(false);
    setSelectedQueue(null);
  };

  const handleDeleteQueue = async (queueId) => {
    try {
      await api.delete(`/queue/${queueId}`);
      toast.success(i18n.t("Queue deleted successfully!"));
    } catch (err) {
      toastError(err);
    }
    setSelectedQueue(null);
  };

  return (
    <Can
      role={user.profile}
      perform="queues-view:show"
      yes={() => (
        <MainContainer>
          <ConfirmationModal
            title={
              selectedQueue &&
              `${i18n.t("queues.confirmationModal.deleteTitle")} ${selectedQueue.name
              }?`
            }
            open={confirmModalOpen}
            onClose={handleCloseConfirmationModal}
            onConfirm={() => handleDeleteQueue(selectedQueue.id)}
          >
            {i18n.t("queues.confirmationModal.deleteMessage")}
          </ConfirmationModal>
          <QueueModal
            open={queueModalOpen}
            onClose={handleCloseQueueModal}
            queueId={selectedQueue?.id}
          />
          <MainHeader>
            <Title>{i18n.t("queues.title")}</Title>


            <Can
              role={user.profile}
              perform="show-icon-add-queue"
              yes={() => (
                <MainHeaderButtonsWrapper>
                  <Button
                    variant="contained"
                    color="primary"
                    onClick={handleOpenQueueModal}
                  >
                    {i18n.t("queues.buttons.add")}
                  </Button>
                </MainHeaderButtonsWrapper>
              )}
            />


          </MainHeader>
          <Paper className={classes.mainPaper} variant="outlined">
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell align="center">
                    {i18n.t("queues.table.name")}
                  </TableCell>
                  <TableCell align="center">
                    {i18n.t("queues.table.color")}
                  </TableCell>
                  <TableCell align="center">
                    {i18n.t("queues.table.greeting")}
                  </TableCell>
                  <TableCell align="center">
                    {i18n.t("queues.table.actions")}
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                <>
                  {queues.map((queue) => (
                    <TableRow key={queue.id}>
                      <TableCell align="center">{queue.name}</TableCell>
                      <TableCell align="center">
                        <div className={classes.customTableCell}>
                          <span
                            style={{
                              backgroundColor: queue.color,
                              width: 60,
                              height: 20,
                              alignSelf: "center",
                            }}
                          />
                        </div>
                      </TableCell>
                      <TableCell align="center">
                        <div className={classes.customTableCell}>
                          <Typography
                            style={{ width: 300, align: "center" }}
                            noWrap
                            variant="body2"
                          >
                            {queue.greetingMessage}
                          </Typography>
                        </div>
                      </TableCell>



                      <TableCell align="center">


                        <Can
                          role={user.profile}
                          perform="show-icon-edit-queue"
                          yes={() => (
                            <IconButton
                              size="small"
                              onClick={() => handleEditQueue(queue)}
                            >
                              <Edit />
                            </IconButton>
                          )}
                        />


                        <Can
                          role={user.profile}
                          perform="show-icon-delete-queue"
                          yes={() => (
                            <IconButton
                              size="small"
                              onClick={() => {
                                setSelectedQueue(queue);
                                setConfirmModalOpen(true);
                              }}
                            >
                              <DeleteOutline />
                            </IconButton>
                          )}
                        />

                      </TableCell>
                    </TableRow>
                  ))}
                  {loading && <TableRowSkeleton columns={4} />}
                </>
              </TableBody>
            </Table>
          </Paper>
        </MainContainer>
      )}
    />
  );
};

export default Queues;
