import {
  Box,
  Button,
  createStyles,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle,
  ListItem,
  ListItemText,
  makeStyles,
  Snackbar,
  Theme,
  Tooltip,
  Typography,
} from '@material-ui/core'
import AssignmentIcon from '@material-ui/icons/Assignment'
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'
import ChevronRightIcon from '@material-ui/icons/ChevronRight'
import CloseIcon from '@material-ui/icons/Close'
import FileCopyIcon from '@material-ui/icons/FileCopy'
import LinkIcon from '@material-ui/icons/Link'
import SupervisorAccountIcon from '@material-ui/icons/SupervisorAccount'
import TimerIcon from '@material-ui/icons/Timer'
import { Alert } from '@material-ui/lab'
import axios from 'axios'
import React, { useEffect, useState } from 'react'
import { useHistory } from 'react-router-dom'
import { useAppSelector } from '../../hooks'
import { socketConnect, socketEndPresentation, socketSync } from '../../sockets'
import SlideDisplay from '../presentationEditor/components/SlideDisplay'
import { Center } from '../presentationEditor/components/styled'
import Scoreboard from './components/Scoreboard'
import Timer from './components/Timer'
import {
  OperatorButton,
  OperatorContainer,
  OperatorContent,
  OperatorFooter,
  OperatorHeader,
  OperatorHeaderItem,
  OperatorInnerContent,
  OperatorQuitButton,
} from './styled'

/**
 *  Description:
 *
 *  Presentation is an active competition
 *
 *
 *  ===========================================
 *  TODO:
 *  - When two userers are connected to the same Localhost:5000 and updates/starts/end competition it
 *    creates a bug where the competition can't be started.
 * ===========================================
 */
const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    table: {
      width: '100%',
    },
    margin: {
      margin: theme.spacing(1),
    },
    paper: {
      backgroundColor: theme.palette.background.paper,
      boxShadow: theme.shadows[5],
      padding: 4,
      outline: 'none',
    },
  })
)

interface Code {
  id: number
  code: string
  view_type_id: number
  competition_id: number
  team_id: number
}

const OperatorViewPage: React.FC = () => {
  // for dialog alert
  const [openAlert, setOpen] = React.useState(false)
  const [openAlertCode, setOpenCode] = React.useState(false)
  const [codes, setCodes] = React.useState<Code[]>([])
  const competitionName = useAppSelector((state) => state.presentation.competition.name)

  //const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))

  const classes = useStyles()
  const teams = useAppSelector((state) => state.presentation.competition.teams)
  const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
  const presentation = useAppSelector((state) => state.presentation)
  const activeId = useAppSelector((state) => state.presentation.competition.id)
  const timer = useAppSelector((state) => state.presentation.timer)
  const history = useHistory()
  const viewTypes = useAppSelector((state) => state.types.viewTypes)
  const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Audience')?.id
  const [successMessageOpen, setSuccessMessageOpen] = useState(true)
  const activeSlideOrder = useAppSelector(
    (state) =>
      state.presentation.competition.slides.find((slide) => slide.id === state.presentation.activeSlideId)?.order
  )
  const slideTimer = useAppSelector((state) =>
    activeSlideOrder !== undefined ? state.presentation.competition.slides[activeSlideOrder].timer : null
  )
  const isFirstSlide = activeSlideOrder === 0
  const isLastSlide = useAppSelector((state) => activeSlideOrder === state.presentation.competition.slides.length - 1)
  const showScoreboard = useAppSelector((state) => state.presentation.show_scoreboard)

  useEffect(() => {
    socketConnect('Operator')
  }, [])

  /** Handles the browsers back button and if pressed cancels the ongoing competition */
  window.onpopstate = () => {
    alert('Tävlingen avslutas för alla')
    endCompetition()
  }

  const handleClose = () => {
    setOpen(false)
    setOpenCode(false)
    setAnchorEl(null)
  }

  /** Making sure the user wants to exit the competition by displaying a dialog box */
  const handleVerifyExit = () => {
    setOpen(true)
  }

  const handleOpenCodes = async () => {
    await getCodes()
    setOpenCode(true)
  }

  const endCompetition = () => {
    setOpen(false)
    socketEndPresentation()
    history.push('/admin/competition-manager')
    window.location.reload(false) // TODO: fix this, we "need" to refresh site to be able to run the competition correctly again
  }

  const getCodes = async () => {
    await axios
      .get(`/api/competitions/${activeId}/codes`)
      .then((response) => {
        setCodes(response.data.items)
      })
      .catch(console.log)
  }
  const getTypeName = (code: Code) => {
    let typeName = ''
    switch (code.view_type_id) {
      case 1:
        const team = teams.find((team) => team.id === code.team_id)
        if (team) {
          typeName = team.name
        } else {
          typeName = 'Lagnamn hittades ej'
        }
        break
      case 2:
        typeName = 'Domare'
        break
      case 3:
        typeName = 'Publik'
        break
      case 4:
        typeName = 'Tävlingsoperatör'
        break
      default:
        typeName = 'Typ hittades ej'
        break
    }
    return typeName
  }

  const handleStartTimer = () => {
    if (!slideTimer) return

    if (!timer.enabled) socketSync({ timer: { value: Date.now() + 1000 * slideTimer, enabled: true } })
    else socketSync({ timer: { ...timer, enabled: false } })
  }

  const handleSetNextSlide = () => {
    if (activeSlideOrder !== undefined)
      socketSync({ slide_order: activeSlideOrder + 1, timer: { value: null, enabled: false } })
  }

  const handleSetPrevSlide = () => {
    if (activeSlideOrder !== undefined)
      socketSync({ slide_order: activeSlideOrder - 1, timer: { value: null, enabled: false } })
  }

  return (
    <OperatorContainer>
      <Dialog open={openAlertCode} onClose={handleClose} aria-labelledby="max-width-dialog-title" maxWidth="xl">
        <Center>
          <DialogTitle id="max-width-dialog-title" className={classes.paper} style={{ width: '100%' }}>
            Koder för {competitionName}
          </DialogTitle>
        </Center>
        <DialogContent>
          {/* <DialogContentText>Här visas tävlingskoderna till den valda tävlingen.</DialogContentText> */}
          {codes &&
            codes.map((code) => (
              <ListItem key={code.id} style={{ display: 'flex' }}>
                <ListItemText primary={`${getTypeName(code)}: `} />
                <Typography component="div">
                  <ListItemText style={{ textAlign: 'right', marginLeft: '10px' }}>
                    <Box fontFamily="Monospace" fontWeight="fontWeightBold">
                      {code.code}
                    </Box>
                  </ListItemText>
                </Typography>
                <Tooltip title="Kopiera kod" arrow>
                  <Button
                    margin-right="0px"
                    onClick={() => {
                      navigator.clipboard.writeText(code.code)
                    }}
                  >
                    <FileCopyIcon fontSize="small" />
                  </Button>
                </Tooltip>
                <Tooltip title="Kopiera länk" arrow>
                  <Button
                    margin-right="0px"
                    onClick={() => {
                      navigator.clipboard.writeText(`${window.location.host}/${code.code}`)
                    }}
                  >
                    <LinkIcon fontSize="small" />
                  </Button>
                </Tooltip>
              </ListItem>
            ))}
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose} color="primary">
            Stäng
          </Button>
        </DialogActions>
      </Dialog>
      <OperatorHeader color="primary" position="fixed">
        <Tooltip title="Avsluta tävling" arrow>
          <OperatorQuitButton onClick={handleVerifyExit} variant="contained" color="secondary">
            <CloseIcon fontSize="large" />
          </OperatorQuitButton>
        </Tooltip>

        <Dialog open={openAlert} onClose={handleClose} aria-labelledby="responsive-dialog-title">
          <DialogTitle id="responsive-dialog-title">{'Vill du avsluta tävlingen?'}</DialogTitle>
          <DialogContent>
            <DialogContentText>
              Genom att avsluta tävlingen kommer den avslutas för alla. Du kommer gå tillbaka till startsidan.
            </DialogContentText>
          </DialogContent>
          <DialogActions>
            <Button autoFocus onClick={handleClose} color="primary">
              Avbryt
            </Button>
            <Button onClick={endCompetition} color="primary" autoFocus>
              Avsluta tävling
            </Button>
          </DialogActions>
        </Dialog>
        <OperatorHeaderItem>
          <Typography variant="h4">{presentation.competition.name}</Typography>
        </OperatorHeaderItem>
        <OperatorHeaderItem>
          <Typography variant="h4">
            {activeSlideOrder !== undefined && activeSlideOrder + 1} / {presentation.competition.slides.length}
          </Typography>
        </OperatorHeaderItem>
      </OperatorHeader>
      {<div style={{ minHeight: 64 }} />}
      <OperatorContent>
        <OperatorInnerContent>
          {activeViewTypeId && <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />}
        </OperatorInnerContent>
      </OperatorContent>
      {<div style={{ minHeight: 128 }} />}
      <OperatorFooter position="fixed">
        <Tooltip title="Föregående sida" arrow>
          <OperatorButton onClick={handleSetPrevSlide} variant="contained" disabled={isFirstSlide} color="primary">
            <ChevronLeftIcon fontSize="large" />
          </OperatorButton>
        </Tooltip>

        {slideTimer !== null && (
          <Tooltip title="Starta timer" arrow>
            <OperatorButton
              onClick={handleStartTimer}
              variant="contained"
              disabled={timer.value !== null && !timer.enabled}
              color="primary"
            >
              <TimerIcon fontSize="large" />
              <Timer disableText />
            </OperatorButton>
          </Tooltip>
        )}

        <Tooltip title="Visa ställning för publik" arrow>
          <OperatorButton onClick={() => socketSync({ show_scoreboard: true })} variant="contained" color="primary">
            <AssignmentIcon fontSize="large" />
          </OperatorButton>
        </Tooltip>
        {showScoreboard && <Scoreboard isOperator />}

        <Tooltip title="Visa koder" arrow>
          <OperatorButton onClick={handleOpenCodes} variant="contained" color="primary">
            <SupervisorAccountIcon fontSize="large" />
          </OperatorButton>
        </Tooltip>

        <Tooltip title="Nästa sida" arrow>
          <OperatorButton onClick={handleSetNextSlide} variant="contained" disabled={isLastSlide} color="primary">
            <ChevronRightIcon fontSize="large" />
          </OperatorButton>
        </Tooltip>
      </OperatorFooter>

      <Snackbar
        open={successMessageOpen && Boolean(competitionName)}
        autoHideDuration={4000}
        onClose={() => setSuccessMessageOpen(false)}
      >
        <Alert severity="success">{`Du har gått med i tävlingen "${competitionName}" som operatör`}</Alert>
      </Snackbar>
    </OperatorContainer>
  )
}

export default OperatorViewPage