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

import { addHours, addMinutes, addSeconds, intervalToDuration } from "date-fns";

import Paper from "@material-ui/core/Paper";
import Container from "@material-ui/core/Container";
import Grid from "@material-ui/core/Grid";
import { makeStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import Tooltip from "@mui/material/Tooltip";
import Zoom from "@mui/material/Zoom";
import IconButton from "@mui/material/IconButton";
import Info from "@material-ui/icons/Info";

import { AuthContext } from "../../context/Auth/AuthContext";
// import { i18n } from "../../translate/i18n";
import Chart from "./Chart";
import openSocket from "socket.io-client";
import api from "../../services/api";

import { Can } from "../../components/Can";
import TableUser from "../../components/DashboardUser/TableUser";

const useStyles = makeStyles((theme) => ({
  container: {
    paddingTop: theme.spacing(4),
    paddingBottom: theme.spacing(4),
  },
  fixedHeightPaper: {
    padding: theme.spacing(2),
    display: "flex",
    overflow: "auto",
    flexDirection: "column",
    height: 240,
  },
  customFixedHeightPaper: {
    padding: theme.spacing(2),
    display: "flex",
    overflow: "auto",
    flexDirection: "column",
    height: 120,
  },
  customFixedHeightPaperLg: {
    padding: theme.spacing(2),
    display: "flex",
    overflow: "auto",
    flexDirection: "column",
    height: "100%",
  },
  containerPaperFix: {
    width: "100%",
    textTransform: "capitalize",
    padding: theme.spacing(2),
    paddingBottom: theme.spacing(4),
    height: "auto",
    overflowY: "hidden",
  },
  cardPaperFix: {
    textTransform: "capitalize",
    paddingLeft: theme.spacing(4),
    paddingRight: theme.spacing(4),
    height: window.innerWidth <= 992 ? "500px" : "auto",
    overflowY: "hidden",
  },
  cardStyleFix: {
    display: "flex",
    flexDirection: "row",
    justifyContent: "left",
    alignItems: "center",
    gap: "32px",
  },
  logginBtn: {
    position: "absolute",
    bottom: "21px",
    right: "21px",
    fontSize: "12px",
  },
  tableRowHead: {
    backgroundColor: "lightgrey",
  },
  tableRowBody: {
    textAlign: "center",
    " &:nth-child(even)": {
      backgroundColor: "#f7f7f7",
    },
  },
  tableCounterOpen: {
    color: "white",
    backgroundColor: "green",
    width: "25px",
    textAlign: "center",
    borderRadius: "5px",
  },
  tableCounterClosed: {
    color: "white",
    backgroundColor: "red",
    width: "25px",
    textAlign: "center",
    borderRadius: "5px",
  },
  tableQueues: {
    color: "white",
    width: "25px",
    textAlign: "center",
    borderRadius: "5px",
  },
}));

var _fifo

const sumOnlineTimeNow = (oldOnlineTimeSum) => {

  let onlineTime = new Date()

  if (!oldOnlineTimeSum.onlineTime) {  

    oldOnlineTimeSum.onlineTime = `${oldOnlineTimeSum.updatedAt.split(' ')[0]} 00:00:00`

  }

  onlineTime.setUTCHours(new Date(oldOnlineTimeSum.onlineTime).getHours())
  onlineTime.setUTCMinutes(new Date(oldOnlineTimeSum.onlineTime).getMinutes())
  onlineTime.setUTCSeconds(new Date(oldOnlineTimeSum.onlineTime).getSeconds())


  let newtTime = intervalToDuration({ start: new Date(oldOnlineTimeSum.updatedAt), end: new Date() })


  if (newtTime.hours && +newtTime.hours > 0) {
    onlineTime = addHours(onlineTime, newtTime.hours)
  }
  if (newtTime.minutes && +newtTime.minutes > 0) {
    onlineTime = addMinutes(onlineTime, newtTime.minutes)
  }
  if (newtTime.seconds && +newtTime.seconds > 0) {
    onlineTime = addSeconds(onlineTime, newtTime.seconds)
  }

  const isoDate = new Date(onlineTime);  

  const newOnlinetime = isoDate.toJSON().slice(0, 19).replace('T', ' ');

  return newOnlinetime
}

const reducer = (state, action) => {
  if (action.type === "DELETE_USER_STATUS") {
    const userId = action.payload;

    const userIndex = state.findIndex((u) => `${u.id}` === `${userId}`);

    if (userIndex !== -1) {
      state.splice(userIndex, 1);
    }

    return [...state];
  }

  if (action.type === "LOAD_QUERY") {
    const queries = action.payload;
    const newQueries = [];

    queries.forEach((query) => {
      const queryIndex = state.findIndex((q) => q.id === query.id);

      if (queryIndex !== -1) {
        state[queryIndex] = query;
      } else {
        newQueries.push(query);
      }
    });

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

  if (action.type === "UPDATE_STATUS_ONLINE") {
    let onlineUser = action.payload;
    let index = -1;

    // console.log('UPDATE_STATUS_ONLINE: ', onlineUser)

    let onlySumOpenClosed = false;

    if (onlineUser.sumOpen || onlineUser.sumClosed) {
      index = state.findIndex(
        (e) =>
          (onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) ||
          (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId)
      );

      onlySumOpenClosed = true;
    } else {
      index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`);
    }

    if (index !== -1) {
      if (!onlySumOpenClosed) {
        if (!("statusOnline" in state[index])) {
          state[index].statusOnline = onlineUser;
        } else if ("statusOnline" in state[index]) {

          state[index].statusOnline["status"] = onlineUser.status;

        }
      }


      if ("onlineTime" in onlineUser) {

        if ("sumOnlineTime" in state[index]) {

          // console.log(' ffffffffffffffffffffffffffff ')
          state[index].sumOnlineTime.sum = onlineUser.onlineTime.split(" ")[1]

        } else if (!("sumOnlineTime" in state[index])) {

          state[index].sumOnlineTime = {
            userId: onlineUser.userId,
            sum: onlineUser.onlineTime.split(" ")[1],
          };

        }
      }

      if (onlineUser.sumOpen) {
        if ("sumOpen" in state[index]) {
          state[index].sumOpen["count"] = onlineUser.sumOpen.count;
        } else if (!("sumOpen" in state[index])) {
          state[index].sumOpen = onlineUser.sumOpen;
        }
      }

      if (onlineUser.sumClosed) {
        if ("sumClosed" in state[index]) {
          state[index].sumClosed["count"] = onlineUser.sumClosed.count;
        } else if (!("sumClosed" in state[index])) {
          state[index].sumClosed = onlineUser.sumClosed;
        }
      }

      if (onlineUser.openClosedInQueue) {
        state[index].openClosedInQueue = onlineUser.openClosedInQueue;
      }
      if (onlineUser.openClosedOutQueue) {
        state[index].openClosedOutQueue = onlineUser.openClosedOutQueue;
      }
    }
    return [...state];
  }

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

const Dashboard = () => {
  const classes = useStyles();
  const [usersOnlineInfo, dispatch] = useReducer(reducer, []);
  const [ticketStatusChange, setStatus] = useState();
  const [ticketsStatus, setTicktsStatus] = useState({ open: 0, openAll: 0, pending: 0, closed: 0 });

  const { user } = useContext(AuthContext);

  useEffect(() => {
    dispatch({ type: "RESET" });
  }, []);

  const handleLogouOnlineUser = async (userId) => {
    try {
      await api.get(`/users/logout/${userId}`);
      //toast.success(("Desloged!"));
      //handleDeleteRows(scheduleId)
    } catch (err) {
      // toastError(err);
    }
  };

  useEffect(() => {
    //setLoading(true);

    const delayDebounceFn = setTimeout(() => {
      // setLoading(true);
      const fetchQueries = async () => {
        try {
          let date = new Date().toLocaleDateString("pt-BR").split("/");
          let dateToday = `${date[2]}-${date[1]}-${date[0]}`;

          const { data } = await api.get("/reports/user/services", {
            params: { userId: null, startDate: dateToday, endDate: dateToday },
          });

          // console.log('data.data: ', data.usersProfile)

          dispatch({ type: "RESET" });
          dispatch({ type: "LOAD_QUERY", payload: data.usersProfile });
        } catch (err) {

        }
      };

      fetchQueries();
    }, 500);
    return () => clearTimeout(delayDebounceFn);
  }, []);


  useEffect(() => {


    if (!usersOnlineInfo || usersOnlineInfo.length === 0) return

    if (_fifo) {
      clearInterval(_fifo);
    }

    _fifo = setInterval(() => {

      for (let i = 0; i < usersOnlineInfo.length; i++) {

        if (usersOnlineInfo[i].statusOnline && usersOnlineInfo[i].statusOnline.status === 'online') { 
          
          let onlineTimeCurrent = sumOnlineTimeNow({ onlineTime: usersOnlineInfo[i].statusOnline.onlineTime, updatedAt: usersOnlineInfo[i].statusOnline.updatedAt })

          dispatch({ type: "UPDATE_STATUS_ONLINE", payload: { userId: usersOnlineInfo[i].id, status: usersOnlineInfo[i].statusOnline.status, onlineTime: onlineTimeCurrent } });

        }
      }


      // usersOnlineInfo.map((e) => {

      //   if (e.statusOnline && e.statusOnline.status === 'online') { 

      //     let onlineTimeCurrent =   sumOnlineTimeNow({onlineTime: e.statusOnline.onlineTime, updatedAt: e.statusOnline.updatedAt}) 

      //     dispatch({ type: "UPDATE_STATUS_ONLINE", payload: { userId: e.id, status: e.statusOnline.status, onlineTime: onlineTimeCurrent } }); 

      //   }

      // })


    }, 3000);


  }, [usersOnlineInfo])


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

    socket.on("ticketStatus", (data) => {
      if (data.action === "update") {
        setStatus("");
        setStatus(data.ticketStatus.status);
      }
    });

    socket.on("onlineStatus", (data) => {
      if (data.action === "logout" || data.action === "update") {
        dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime });
      } else if (data.action === "delete") {
        dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime });
      }
    });

    socket.on("user", (data) => {
      if (data.action === "delete") {
        dispatch({ type: "DELETE_USER", payload: +data.userId });
      }
    });

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

  useEffect(() => {
    if (ticketStatusChange === "") return
    const delayDebounceFn = setTimeout(() => {
      const fetchQueries = async () => {
        try {
          let date = new Date().toLocaleDateString("pt-BR").split("/");
          let dateToday = `${date[2]}-${date[1]}-${date[0]}`;

          const _open = await api.get("/tickets/count", {
            params: { status: "open", date: dateToday },
          });
          const _closed = await api.get("/tickets/count", {
            params: { status: "closed", date: dateToday },
          });
          const _pending = await api.get("/tickets/count", {
            params: { status: "pending" },
          });

          const _openAll = await api.get("/tickets/count", {
            params: { status: "open" },
          });
          setTicktsStatus({
            open: _open.data.count,
            openAll: _openAll.data.count,
            closed: _closed.data.count,
            pending: _pending.data.count,
          });
          // setOpen(_open.data.count);
          // setClosed(_closed.data.count);
          // setPending(_pending.data.count);
        } catch (err) {
          console.log(err);
        }
      };

      fetchQueries();
    }, 500);
    return () => clearTimeout(delayDebounceFn);
  }, [ticketStatusChange]);

  return (
    <Can
      role={user.profile}
      perform="dashboard-view:show"
      yes={() => (
        <Container maxWidth="lg" className={classes.container}>
          <Grid container spacing={3}>
            <Paper className={classes.containerPaperFix} sx={12}>
              <Grid item sx={4}>
                <Typography
                  component="h1"
                  variant="h4"
                  color="primary"
                  style={{ marginBottom: "16px" }}
                >
                  tickets
                  <Tooltip
                    title={`Os dados informados abaixo é baseado na data: ${new Date().toLocaleDateString(
                      "pt-BR",
                      { timeZone: "UTC" }
                    )}`}
                    color="primary"
                    TransitionComponent={Zoom}
                  >
                    <IconButton>
                      <Info />
                    </IconButton>
                  </Tooltip>
                </Typography>
              </Grid>
              <Grid container spacing={3}>
                <Grid item xs={12} sm={6} md={6} lg={4}>
                  <Paper
                    className={classes.customFixedHeightPaper}
                    style={{ overflow: "hidden" }}
                    variant="outlined"
                  >
                    <Typography component="h3" variant="h6" color="primary" paragraph>
                      Aguardando
                    </Typography>
                    <Grid item>
                      <Typography component="h1" variant="h4">
                        {ticketsStatus.pending}
                      </Typography>
                    </Grid>
                  </Paper>
                </Grid>
                <Grid item xs={12} sm={6} md={6} lg={4}>
                  <Paper
                    className={classes.customFixedHeightPaper}
                    style={{ overflow: "hidden" }}
                    variant="outlined"
                  >
                    <Typography component="h3" variant="h6" color="primary" style={{ marginBottom: "0" }} paragraph>
                      Em Atendimento
                    </Typography>
                    <Typography paragraph style={{ fontSize: "12px", margin: "0px" }}>Hoje/Todo Periodo</Typography>

                    <Grid item>
                      <Typography component="h1" variant="h4">
                        {ticketsStatus.open}/{ticketsStatus.openAll}
                      </Typography>
                    </Grid>
                  </Paper>
                </Grid>

                <Grid item xs={12} sm={6} md={6} lg={4}>
                  <Paper
                    className={classes.customFixedHeightPaper}
                    style={{ overflow: "hidden" }}
                    variant="outlined"
                  >
                    <Typography component="h3" variant="h6" color="primary" paragraph>
                      Fechados
                    </Typography>
                    <Grid item>
                      <Typography component="h1" variant="h4">
                        {ticketsStatus.closed}
                      </Typography>
                    </Grid>
                  </Paper>
                </Grid>
                <Grid item xs={12}>
                  <Paper className={classes.fixedHeightPaper} variant="outlined">
                    <Chart allTickets={usersOnlineInfo} />
                  </Paper>
                </Grid>
              </Grid>
            </Paper>
            <Paper className={classes.containerPaperFix} style={{ marginTop: "21px" }} sx={12}>
              <Grid item sx={4}>
                <Typography
                  component="h1"
                  variant="h4"
                  color="primary"
                  style={{ marginBottom: "16px" }}
                >
                  Usuários
                  <Tooltip
                    title={`Os dados informados abaixo é baseado na data: ${new Date().toLocaleDateString(
                      "pt-BR",
                      { timeZone: "UTC" }
                    )}`}
                    color="primary"
                    TransitionComponent={Zoom}
                  >
                    <IconButton>
                      <Info />
                    </IconButton>
                  </Tooltip>
                </Typography>
              </Grid>
              <Grid container spacing={3}>
                <Grid item xs={12} sm={6} md={6} lg={4}>
                  <Paper
                    className={classes.customFixedHeightPaper}
                    style={{ overflow: "hidden" }}
                    variant="outlined"
                  >
                    <Typography component="h3" variant="h6" color="primary" paragraph>
                      Total de Agentes
                    </Typography>
                    <Grid item>
                      <Typography component="h1" variant="h4">
                        {usersOnlineInfo.length}
                      </Typography>
                    </Grid>
                  </Paper>
                </Grid>
                <Grid item xs={12} sm={6} md={6} lg={4}>
                  <Paper
                    className={classes.customFixedHeightPaper}
                    style={{ overflow: "hidden" }}
                    variant="outlined"
                  >
                    <Typography component="h3" variant="h6" color="primary" paragraph>
                      Online
                    </Typography>
                    <Grid item>
                      <Typography component="h1" variant="h4">
                        {
                          usersOnlineInfo.filter(
                            (status) =>
                              status.statusOnline && status.statusOnline.status === "online"
                          ).length
                        }
                      </Typography>
                    </Grid>
                  </Paper>
                </Grid>
                <Grid item xs={12} sm={6} md={6} lg={4}>
                  <Paper
                    className={classes.customFixedHeightPaper}
                    style={{ overflow: "hidden" }}
                    variant="outlined"
                  >
                    <Typography component="h3" variant="h6" color="primary" paragraph>
                      Offline
                    </Typography>
                    <Grid item>
                      <Typography component="h1" variant="h4">
                        {
                          usersOnlineInfo.filter(
                            (status) =>
                              !status.statusOnline || status.statusOnline.status === "offline"
                          ).length
                        }
                      </Typography>
                    </Grid>
                  </Paper>
                </Grid>

                {usersOnlineInfo &&
                  <TableUser
                    classes={classes}
                    usersOnlineInfo={usersOnlineInfo}
                    logout={handleLogouOnlineUser}
                  />
                }


              </Grid>
            </Paper>
          </Grid>
        </Container>
      )}
    />
  );
};

export default Dashboard;