import { CircularProgress, List, ListItem, Box, useTheme, Pagination } from "@mui/material";
import { useEffect, useState } from "react";

import TicketCard from "./TicketCard";
import { useSnackbar } from "notistack";

import { apiRequestHandler } from "@utils/api/apiRequestHandler";
import { ApiError, Ticket } from "@utils/api/types";

const TICKETS_PER_PAGE = 10;

export default function TicketList() {
  const theme = useTheme();
  const { enqueueSnackbar } = useSnackbar();
  const [tickets, setTickets] = useState<Ticket[]>([]);
  const [ticketCount, setTicketCount] = useState<number | null>(null);
  const [currentPage, setCurrentPage] = useState<number>(0);
  const [isLoading, setIsLoading] = useState<boolean>(false);

  useEffect(
    function fetchTickets() {
      setIsLoading(true);
      const abortController = new AbortController();

      apiRequestHandler
        .getTickets({ amt: TICKETS_PER_PAGE, page: currentPage, srch: "", status: "open" }, abortController.signal)
        .then((result) => {
          if (result instanceof ApiError) {
            enqueueSnackbar(`Error: ${result.message}`);
          } else if (result instanceof Error) {
            console.log(result);
          } else {
            setTickets(result.data);
            setTicketCount(result.count);
            setIsLoading(false);
          }
        });

      return () => {
        abortController.abort();
      };
    },
    [currentPage, enqueueSnackbar]
  );

  useEffect(
    function subscribeToTickets() {
      const unsubscribe = apiRequestHandler.subscribeToAllTickets({
        onMessage(event) {
          console.log("SSE received:", event.data);
          try {
            const newTicket = JSON.parse(event.data) as Ticket;
            const existingTicketIndex = tickets.findIndex((ticket) => ticket.id === newTicket.id);
            if (existingTicketIndex !== -1) {
              setTickets((prevTickets) => {
                const newTickets = prevTickets.slice();
                newTickets.splice(existingTicketIndex, 1, newTicket);
                return newTickets;
              });
              return;
            }
            setTickets((prevTickets) => [newTicket, ...prevTickets.slice(0, TICKETS_PER_PAGE - 1)]);
          } catch (error) {
            console.log("SSE is not JSON", error);
          }
        },
        onError(event) {
          console.log("SSE Error:", event);
        },
      });

      return () => {
        unsubscribe();
      };
    },
    [tickets]
  );

  return (
    <Box
      sx={{
        display: "flex",
        gap: "40px",
        flexDirection: "column",
      }}
    >
      <List
        sx={{
          p: 0,
          display: "flex",
          flexDirection: "column",
          gap: "40px",
          opacity: isLoading ? 0.4 : 1,
          transitionProperty: "opacity",
          transitionDuration: "200ms",
        }}
      >
        {tickets.map((ticket) => (
          <ListItem key={ticket.id} disablePadding>
            <TicketCard
              name={ticket.title}
              body={ticket.top_message.message}
              time={new Date(ticket.updated_at).toLocaleDateString()}
              ticketId={ticket.id}
            />
          </ListItem>
        ))}
        {isLoading && (
          <Box
            sx={{
              position: "absolute",
              width: "100%",
              height: "100%",
              minHeight: "80px",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
            }}
          >
            <CircularProgress sx={{ color: theme.palette.brightPurple.main }} size={60} />
          </Box>
        )}
      </List>
      {ticketCount !== null && ticketCount > TICKETS_PER_PAGE && (
        <Pagination
          count={Math.ceil(ticketCount / TICKETS_PER_PAGE)}
          page={currentPage + 1}
          onChange={(e, value) => setCurrentPage(value - 1)}
          sx={{ alignSelf: "center" }}
        />
      )}
    </Box>
  );
}
