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)

  const [settings, setSettings] = useState([])

  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 fetchSession = async () => {
      try {
        const { data } = await api.get('/settings')
        setSettings(data)
      } catch (err) {
        toastError(err)
      }
    }
    fetchSession()
  }, [])

  const getSettingValue = (key) => {
    const { value } = settings.find((s) => s.key === key)

    return value
  }

  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 })
      }
    })

    socket.on('settings', (data) => {
      if (data.action === 'update') {
        setSettings((prevState) => {
          const aux = [...prevState]
          const settingIndex = aux.findIndex((s) => s.key === data.setting.key)
          aux[settingIndex].value = data.setting.value
          return aux
        })
      }
    })

    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={() => (
                            <div
                              style={{
                                margin: 0,
                                padding: 0,
                                border: 'none',
                                display: 'inline',
                              }}
                            >
                              {(settings &&
                                settings.length > 0 &&
                                getSettingValue('editQueue') &&
                                getSettingValue('editQueue') === 'enabled') |
                              (user.profile === 'master') ? (
                                <IconButton
                                  size="small"
                                  onClick={() => handleEditQueue(queue)}
                                >
                                  <Edit />
                                </IconButton>
                              ) : (
                                <div></div>
                              )}
                            </div>

                            // <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