import React, { useContext, useReducer, useEffect, useState, useCallback } 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 SelectField from "../../components/Report/SelectField"

import { AuthContext } from "../../context/Auth/AuthContext"
import { i18n } from "../../translate/i18n";
import Chart from "./Chart"
import PieChart from "./PieChart"
//import openSocket from "socket.io-client"
import { socket } from "../../services/socket"
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: 280,
  },
  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]) {

          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 { user } = useContext(AuthContext)
  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 [ticketStatusChatEnd, setTicketStatusChatEnd] = useState([])

  const userQueueIds = user.queues?.map((q) => q.id);
  const [selectedQueue, setSelectedQueue] = useState(userQueueIds || []);

  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, userQueues: selectedQueue },
          })

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

          const { data: ticketStatusChatEndData } = await api.get("/reports/count/statusChatEnd", {
            params: { startDate: dateToday, endDate: dateToday, userQueues: selectedQueue },
          })

          setTicketStatusChatEnd(ticketStatusChatEndData.reportStatusChatEnd)

        } catch (err) {

        }
      }

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


  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)

    const onTicketsStatusDashboard = (data) => {
      if (data.action === "update") {
        setStatus("")
        setStatus(data.ticketStatus.status)
      }
    }

    socket.on("ticketStatus", onTicketsStatusDashboard)

    const onOnlineStatusDashboard = (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("onlineStatus", onOnlineStatusDashboard)

    const onUserDashboard = (data) => {
      if (data.action === "delete") {
        dispatch({ type: "DELETE_USER", payload: +data.userId })
      }
    }

    socket.on("user", onUserDashboard)

    return () => {
      socket.off("user", onUserDashboard)
      socket.off("onlineStatus", onOnlineStatusDashboard)
      socket.off("ticketStatus", onTicketsStatusDashboard)
    }
  }, [])

  const handleSelectedQueue = useCallback((queueSelected) => {
    if (queueSelected !== 'All') {
      const queueIndex = user?.queues?.findIndex((q) => q.id === parseInt(queueSelected));
      const queueIds = []
      queueIds.push(user?.queues[queueIndex]?.id);
      setSelectedQueue(queueIds);
    } else {
      const queueIds = user?.queues?.map((queue) => queue.id);
      setSelectedQueue(queueIds);
    }
  }, [user, setSelectedQueue])

  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, queueIds: selectedQueue },
          })
          const _closed = await api.get("/tickets/count", {
            params: { status: "closed", date: dateToday, queueIds: selectedQueue },
          })
          const _pending = await api.get("/tickets/count", {
            params: { status: "pending", queueIds: selectedQueue },
          })

          const _openAll = await api.get("/tickets/count", {
            params: { status: "open", queueIds: selectedQueue },
          })
          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, selectedQueue])

  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 style={{ display: 'flex', flexDirection: 'column', padding: '10px 0', alignItems: 'start' }}>
              <SelectField
                      func={handleSelectedQueue}
                      textBoxFieldSelected={'All'}
                      emptyField={false}
                      header={i18n.t('dashboard.titles.selectQueues')}
                      currencies={user.queues.map((obj) => {
                        return { 'value': obj.id, 'label': obj.name }
                      })} />
              </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>
                      {i18n.t('dashboard.titles.waiting')}
                    </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>
                      {i18n.t('dashboard.titles.inService')}
                    </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>
                      {i18n.t('dashboard.titles.ticketsClosed')}
                    </Typography>
                    <Grid item>
                      <Typography component="h1" variant="h4">
                        {ticketsStatus.closed}
                      </Typography>
                    </Grid>
                  </Paper>
                </Grid>
                <Grid item container spacing={3}>
                  <Grid item xs={12} sm={12} md={6} lg={6}>
                    <Paper className={classes.fixedHeightPaper} variant="outlined">
                      <Chart allTickets={usersOnlineInfo} selectedQueue={selectedQueue} />
                    </Paper>
                  </Grid>
                  <Grid item xs={12} sm={12} md={6} lg={6}>
                    <Paper className={classes.fixedHeightPaper} variant="outlined">
                      <PieChart data={ticketStatusChatEnd} />
                    </Paper>
                  </Grid>
                </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" }}
                >
                  {i18n.t('dashboard.titles.users')}
                  <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