import React, { ChangeEvent } from 'react';
import { Box, Button, Divider, FormControl, InputBase, InputLabel, Link, MenuItem, Select, TextField, Tooltip, Typography } from '@mui/material';
import useStore from '../../../hooks/useStore';
import MultiSelect from '../../reusable/MultiSelect';
import { messageChannelContext } from '../../../provider/MessageChannel';
import LoadingButton from '@mui/lab/LoadingButton';
import { useSnackbar } from 'notistack';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';

type DownloadSelectorProps = {
  onFinish?: () => unknown
}

const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
  const messageHandler = React.useContext(messageChannelContext);
  const [store, dispatch] = useStore();
  const [availableDubs, setAvailableDubs] = React.useState<string[]>([]);
  const [availableSubs, setAvailableSubs ] = React.useState<string[]>([]);
  const [ loading, setLoading ] = React.useState(false);
  const { enqueueSnackbar } = useSnackbar();
  const ITEM_HEIGHT = 48;
  const ITEM_PADDING_TOP = 8;

  React.useEffect(() => {
    (async () => {
      /* If we don't wait the response is undefined? */
      await new Promise((resolve) => setTimeout(() => resolve(undefined), 100));
      const dubLang = messageHandler?.handleDefault('dubLang');
      const subLang = messageHandler?.handleDefault('dlsubs');
      const q = messageHandler?.handleDefault('q');
      const fileName = messageHandler?.handleDefault('fileName');
      const dlVideoOnce = messageHandler?.handleDefault('dlVideoOnce');
      const result = await Promise.all([dubLang, subLang, q, fileName, dlVideoOnce]);
      dispatch({
        type: 'downloadOptions',
        payload: {
          ...store.downloadOptions,
          dubLang: result[0],
          dlsubs: result[1],
          q: result[2],
          fileName: result[3],
          dlVideoOnce: result[4],
        }
      });
      setAvailableDubs(await messageHandler?.availableDubCodes() ?? []);
      setAvailableSubs(await messageHandler?.availableSubCodes() ?? []);
    })();
  }, []);

  const addToQueue = async () => {
    setLoading(true);
    const res = await messageHandler?.resolveItems(store.downloadOptions);
    if (!res)
      return enqueueSnackbar('The request failed. Please check if the ID is correct.', {
        variant: 'error'
      });
    setLoading(false);
    if (onFinish)
      onFinish();
  };

  const listEpisodes = async () => {
    if (!store.downloadOptions.id) {
      return enqueueSnackbar('Please enter a ID', {
        variant: 'error'
      });
    }
    setLoading(true);
    const res = await messageHandler?.listEpisodes(store.downloadOptions.id);
    if (!res || !res.isOk) {
      setLoading(false);
      return enqueueSnackbar('The request failed. Please check if the ID is correct.', {
        variant: 'error'
      });
    } else {
      dispatch({
        type: 'episodeListing',
        payload: res.value
      });
    }
    setLoading(false);
  };

  return <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' }}>
    <Box sx={{display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      margin: '5px',
      }}>
        <Box sx={{
          width: '50rem',
          height: '21rem',
          margin: '10px',
          display: 'flex',
          justifyContent: 'space-between',
          //backgroundColor: '#ffffff30',
          }}>
        <Box sx={{
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      gap: '0.7rem',
      //backgroundColor: '#ff000030'
    }}>
      <Typography sx={{fontSize: '1.4rem'}}>
        General Options
      </Typography>
      <TextField value={store.downloadOptions.id} required onChange={e => {
        dispatch({
          type: 'downloadOptions',
          payload: { ...store.downloadOptions, id: e.target.value }
        });
      }} label='Show ID'/>
      <TextField type='number' value={store.downloadOptions.q} required onChange={e => {
        const parsed = parseInt(e.target.value);
        if (isNaN(parsed) || parsed < 0 || parsed > 10)
          return;
        dispatch({
          type: 'downloadOptions',
          payload: { ...store.downloadOptions, q: parsed }
        });
      }} label='Quality Level (0 for max)'/>
      <Box sx={{ display: 'flex', gap: '5px' }}>
      <Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, noaudio: !store.downloadOptions.noaudio } })} variant={store.downloadOptions.noaudio ? 'contained' : 'outlined'}>Skip Audio</Button>
      <Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, novids: !store.downloadOptions.novids } })} variant={store.downloadOptions.novids ? 'contained' : 'outlined'}>Skip Video</Button>
      </Box>
      <Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, dlVideoOnce: !store.downloadOptions.dlVideoOnce } })} variant={store.downloadOptions.dlVideoOnce ? 'contained' : 'outlined'}>Skip Unnecessary</Button>
      <Tooltip title={store.service == 'hidive' ? '' :
      <Typography>
      Simulcast is only supported on Hidive
      </Typography>}
      arrow placement='top'
      >
      <Box>
      <Button sx={{ textTransform: 'none'}} disabled={store.service != 'hidive'} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, simul: !store.downloadOptions.simul } })} variant={store.downloadOptions.simul ? 'contained' : 'outlined'}>Download Simulcast ver.</Button>
      </Box>
      </Tooltip>
      </Box>
    <Box sx={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        gap: '0.7rem',
        //backgroundColor: '#00000020'
      }}>
        <Typography sx={{fontSize: '1.4rem'}}>
        Episode Options
      </Typography>
      <Box sx={{
        display: 'flex',
        flexDirection: 'column',
        gap: '1px'
      }}>
        <Box sx={{
          borderColor: '#595959',
          borderStyle: 'solid',
          borderWidth: '1px',
          borderRadius: '5px',
          //backgroundColor: '#ff4567',
          width: '15rem',
          height: '3.5rem',
          display: 'flex',
          '&:hover' : {
            borderColor: '#ffffff',
          },
        }}>
          <InputBase sx={{
            ml: 2,
            flex: 1,
          }}
          disabled={store.downloadOptions.all} value={store.downloadOptions.e} required onChange={e => {
            dispatch({
              type: 'downloadOptions',
              payload: { ...store.downloadOptions, e: e.target.value }
            });
          }} placeholder='Episode Select'/>
          <Divider orientation='vertical'/>
          <LoadingButton loading={loading} disableElevation disableFocusRipple disableRipple disableTouchRipple onClick={listEpisodes} variant='text' sx={{ textTransform: 'none'}}><Typography>List<br/>Episodes</Typography></LoadingButton>
        </Box>
      </Box>
      <Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, all: !store.downloadOptions.all } })} variant={store.downloadOptions.all ? 'contained' : 'outlined'}>Download All</Button>
      <Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, but: !store.downloadOptions.but } })} variant={store.downloadOptions.but ? 'contained' : 'outlined'}>Download All but</Button>
      </Box>
      <Box sx={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        gap: '0.7rem',
        //backgroundColor: '#00ff0020'
      }}>
      <Typography sx={{fontSize: '1.4rem'}}>
        Language Options
      </Typography>
      <MultiSelect
        title='Dub Languages'
        values={availableDubs}
        selected={store.downloadOptions.dubLang}
        onChange={(e) => {
          dispatch({
            type: 'downloadOptions',
            payload: { ...store.downloadOptions, dubLang: e }
          });
        }}
        allOption
      />
      
      <MultiSelect
        title='Sub Languages'
        values={availableSubs}
        selected={store.downloadOptions.dlsubs}
        onChange={(e) => {
          dispatch({
            type: 'downloadOptions',
            payload: { ...store.downloadOptions, dlsubs: e }
          });
        }}
      />
      <Tooltip title={store.service == 'crunchy' ? '' :
            <Typography>
              Hardsubs are only supported on Crunchyroll
            </Typography>
      }
          arrow placement='top'>
      <Box sx={{
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      width: '100%',
      gap: '1rem'
    }}>
      
      <Box sx={{
          borderRadius: '5px',
          //backgroundColor: '#ff4567',
          width: '15rem',
          height: '3.5rem',
          display: 'flex',
        }}>
          <FormControl fullWidth>
            <InputLabel id='hsLabel'>Hardsub Language</InputLabel>
          <Select
          MenuProps={{
            PaperProps: {
              style: {
                maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
                width: 250
              }
            }
          }}
          labelId='hsLabel'
          label='Hardsub Language'
          disabled={store.service != 'crunchy'}
          value={store.downloadOptions.hslang}
          onChange={(e) => {
            dispatch({
              type: 'downloadOptions',
              payload: { ...store.downloadOptions, hslang: (e.target.value as string) === '' ? undefined : e.target.value as string }
            });
          }}
          >
            <MenuItem value=''>No Hardsub</MenuItem>
            {availableSubs.map((lang) => {
              if(lang === 'all' || lang === 'none')
                return undefined
              return <MenuItem value={lang}>{lang}</MenuItem>
            })}
            </Select>
            </FormControl>
            </Box>
            
        
        <Tooltip title={
        <Typography>
           Downloads the hardsub version of the selected subtitle.<br/>Subtitles are displayed <b>PERMANENTLY!</b><br/>You can choose only <b>1</b> subtitle per video!
           </Typography>
      } arrow placement='top'>
        <InfoOutlinedIcon sx={{
          transition: '100ms',
          ml: '0.35rem',
          mr: '0.65rem',
          '&:hover' : {
            color: '#ffffff30',
          }
        }} />
      </Tooltip>
        </Box>
        </Tooltip>
      </Box>
    </Box>
    <Box sx={{width: '95%', height: '0.3rem', backgroundColor: '#ffffff50', borderRadius: '10px', marginBottom: '20px'}}/>
    <Box sx={{
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      width: '100%',
      gap: '15px'
    }}>
    <TextField value={store.downloadOptions.fileName} onChange={e => {
        dispatch({
          type: 'downloadOptions',
          payload: { ...store.downloadOptions, fileName: e.target.value }
        });
      }} sx={{ width: '87%' }} label='Filename Overwrite' />
      <Tooltip title={
        <Typography>
           Click here to see the documentation
           </Typography>
      } arrow placement='top'>
        <Link href='https://github.com/anidl/multi-downloader-nx/blob/master/docs/DOCUMENTATION.md#filename-template' rel="noopener noreferrer" target="_blank">
        <InfoOutlinedIcon sx={{
          transition: '100ms',
          '&:hover' : {
            color: '#ffffff30',
          }
        }} />
        </Link>
      </Tooltip>
      </Box>
    </Box>
    <Box sx={{width: '95%', height: '0.3rem', backgroundColor: '#ffffff50', borderRadius: '10px', marginTop: '10px'}}/>
    
      <LoadingButton sx={{ margin: '15px', textTransform: 'none' }}  loading={loading} onClick={addToQueue} variant='contained'>Add to Queue</LoadingButton>
     
  </Box>; 
};

export default DownloadSelector;