import Autocomplete from '@mui/material/Autocomplete';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Checkbox from '@mui/material/Checkbox';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import FormControl from '@mui/material/FormControl';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormGroup from '@mui/material/FormGroup';
import FormLabel from '@mui/material/FormLabel';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import Paper from '@mui/material/Paper';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import Select from '@mui/material/Select';
import type { SelectChangeEvent } from '@mui/material/Select';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import { RootState } from './rootReducer';
import {
  actions,
  closeDrawer,
  deleteSearch,
  getCustomSearch,
  getKeysList,
  loadSavedSearch,
  saveSearch,
  searchDetails,
  searchSettingSelector,
  setAndOr,
  setAreAllDepartmentsSelected,
  setSearchString,
  setSearchType,
  setStatusFilter,
  setTimeSpan,
  timeSpanSelector,
  updateSearch,
} from './searchDrawerSlice';
import { resetNode, selectFirstNode, setNodeByNodeID } from './nodeSlice';
import { useDispatch, useSelector } from 'react-redux';
import React, { ChangeEvent, useEffect } from 'react';
import styled, { css } from 'styled-components';
import { typeIcons } from './TaskNavigator';
import { I18nProvider } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import { i18n } from '@lingui/core';
import { AppDispatch } from './store';

// Applied to <Radio /> and <Checkbox />
const checkedStyles = {
  '&.Mui-checked': { color: 'var(--Google-Blau, rgba(0,153,255,1))' },
};

const highlightStyle = {
  color: 'var(--Google-Blau, rgba(0,153,255,1))',
  '&.Mui-checked': {
    color: 'var(--Google-Blau, rgba(0,153,255,1))',
  },
};

const TextFieldComponent = ({ name, label, searchValue, highlight }) => {
  return (
    <TextField
      fullWidth={true}
      name={name}
      label={label}
      value={searchValue}
      margin='dense'
      size='small'
      sx={{
        mb: 2,
        ...(highlight && {
          backgroundColor: '#E8F0FE',
        }),
      }}
    />
  );
};

const SplitComponent = ({ label }) => {
  return (
    <Typography variant='button' sx={{ textAlign: 'center' }}>
      {label}
    </Typography>
  );
};

const FilterBox = styled.div<{ isOpen: boolean }>`
  overflow: auto;
  transition: width 0.25s ease-in-out;
  margin-left: 0.5rem;
  height: calc(100vh - 64px);
  width: 23rem;

  ${(props) =>
    !props.isOpen &&
    css`
      overflow: hidden;
      width: 0;
      padding: 0;
      flex: reset;
    `}
`;

const SetSearchNameDialog = ({
  isOpen,
  handleSave,
  handleClose,
  handleNameUpdate,
  setIsPrivate,
  name,
  isInvalidInput,
  isSavedSearchPrivate,
}) => {
  return (
    <Dialog onClose={handleClose} open={isOpen}>
      <DialogContent>
        <TextField
          autoFocus={true}
          label={<Trans>name</Trans>}
          value={name}
          onChange={handleNameUpdate}
          error={isInvalidInput}
          helperText={
            isInvalidInput && (
              <Trans>Name already exists. Please enter a different name.</Trans>
            )
          }
        />
        <Box m={1} />
        <FormControlLabel
          control={
            <Checkbox
              size='small'
              defaultChecked={isSavedSearchPrivate}
              onChange={(e) => setIsPrivate(e.target.checked)}
              sx={checkedStyles}
            />
          }
          label={<Trans>Set as private</Trans>}
        />
      </DialogContent>
      <DialogActions>
        <Button
          onClick={handleClose}
          sx={{ borderColor: '#000000de', color: '#000000de' }}
        >
          <Trans>Cancel</Trans>
        </Button>
        <Button
          onClick={handleSave}
          sx={{ borderColor: '#0000003A', color: '#000000DE' }}
        >
          <Trans>Save</Trans>
        </Button>
      </DialogActions>
    </Dialog>
  );
};

const KeyValueComponent = ({ options, highlight, highlightVal }) => {
  const [value, setValue] = React.useState(options[0]);
  const [inputValue, setInputValue] = React.useState(options[0]);
  const d = useDispatch<AppDispatch>();

  return (
    <div>
      <Autocomplete
        value={value || ''}
        onChange={(event, newValue) => {
          setValue(newValue);
          d(setSearchString({ name: 'name', value: newValue }));
        }}
        inputValue={inputValue || ''}
        onInputChange={(event, newInputValue) => {
          setInputValue(newInputValue);
          d(setSearchString({ name: 'name', value: newInputValue }));
        }}
        options={options}
        size='small'
        renderInput={(params) => (
          <TextField
            {...params}
            label={<Trans>Name</Trans>}
            margin='dense'
            variant='outlined'
            name='name'
            sx={{
              mb: 2,
              ...(highlight && {
                backgroundColor: '#E8F0FE',
              }),
            }}
          />
        )}
      />
      <TextField
        fullWidth={true}
        label={<Trans>Value</Trans>}
        size='small'
        margin='dense'
        variant='outlined'
        name='value'
        sx={{
          mb: 2,
          ...(highlightVal && {
            backgroundColor: '#E8F0FE',
          }),
        }}
      />
    </div>
  );
};

const SearchDrawer = () => {
  const state = useSelector((s: RootState) => s.searchDrawer);
  const isOpen = state.isOpen;
  const ticketStatus = state.ticketStatus;
  const searchType = state.searchType;
  const timeSpan = state.timespan;
  const isNewSearchNameDialogOpen = state.isNewSearchDialogOpen;
  const newSearchName = state.searchSettingName;

  const nodeType = useSelector((s: RootState) => s.node?.type || null);
  const nodeName = useSelector((s: RootState) => s.node?.name || null);
  const nodeId = useSelector((s: RootState) => s.node?.id);
  const customSearches = useSelector((s: RootState) =>
    searchSettingSelector.selectAll(s.searchDrawer.searchSettings),
  );
  const [invalidSaveSearchInput, setInvalidSaveSearchInput] =
    React.useState(false);
  const taskState = useSelector((s: RootState) => s.filter.taskState);
  const isSavedSearchPrivate = state.isSavedSearchPrivate;
  const [isPrivate, setIsPrivate] = React.useState(false);

  const d = useDispatch();

  const handleSearchString = (e: ChangeEvent<HTMLInputElement>) => {
    // d(setSearchString(e.target.value));
  };

  const handleSearchArea = (e: ChangeEvent<HTMLInputElement>) => {
    d(setAreAllDepartmentsSelected(e.target.value == 'all-departments'));
  };

  const handleStatusCheck = (e: ChangeEvent<HTMLInputElement>) => {
    const checkEle = e.target;
    const name = checkEle.name;
    const checked = checkEle.checked || false;
    d(setStatusFilter({ name, checked }));
  };

  const handleSearchParamForm = (e: ChangeEvent<HTMLInputElement>) => {
    switch (e.target.type) {
      case 'text':
        return d(
          setSearchString({ name: e.target.name, value: e.target.value }),
        );
      case 'checkbox':
        return d(setSearchType(e.target.value));
      case 'radio':
        return d(setAndOr({ name: e.target.name, value: e.target.value }));
    }
  };

  const hanldeTimespanSelector = (e: SelectChangeEvent) => {
    const value = e.target.value;
    d(setTimeSpan(value));
  };

  const handleSearch = () => {
    d(searchDetails(state.areAllDepartmentsSelected));
  };

  const handleClose = () => {
    d(closeDrawer());
  };

  const handleLoadSavedSearch = (e: SelectChangeEvent) => {
    d(loadSavedSearch(e.target.value));
  };

  const handleSavedSearchUpdate = () => {
    setIsPrivate(isSavedSearchPrivate);
    d(actions.toggleUpdateSearchDialog());
  };

  const handleDeleteSelectedSetting = () => {
    d(deleteSearch(state.selectedSavedSearch));
  };

  // -- START NEW SEARCH DIALOG HANDLERS
  const invalidSaveSearchName = () => {
    return customSearches.some((entity) => {
      if (entity.name === newSearchName) {
        setInvalidSaveSearchInput(true);
        return true;
      }
    });
  };

  const handleNewSearchDialogOpen = () => {
    d(actions.openNewSettingDialog());
  };
  const handleNewSearchDialogClose = () => {
    d(actions.closeNewSettingDialog());
    d(getCustomSearch());
    setInvalidSaveSearchInput(false);
    setIsPrivate(false);
  };
  const handleNewSearchNameUpdate = (e: ChangeEvent<HTMLInputElement>) => {
    d(actions.setNewSettingName(e.target.value));
  };
  const handleNewSearchSave = () => {
    if (invalidSaveSearchName()) return;
    d(actions.setSavedSearchAsPublicOrPrivate(isPrivate));
    d(saveSearch());
  };
  // -- END NEW SEARCH DIALOG HANDLERS

  // -- START UPDATE SEARCH DIALOG HANDLERS
  const invalidUpdateSearchName = () => {
    const selectedId = state.selectedSavedSearch as unknown as number;

    return customSearches.some((entity) => {
      if (entity.name === newSearchName && entity.id !== selectedId) {
        setInvalidSaveSearchInput(true);
        return true;
      }
    });
  };

  const handleUpdateDialogToggle = () => {
    d(actions.toggleUpdateSearchDialog());
    setInvalidSaveSearchInput(false);
    setIsPrivate(false);
  };
  const handleUpdateSearchName = (e: ChangeEvent<HTMLInputElement>) => {
    d(actions.updateCustomSearchName(e.target.value));
  };

  const handleUpdateSearch = () => {
    if (invalidUpdateSearchName()) return;
    d(actions.setSavedSearchAsPublicOrPrivate(isPrivate));
    d(updateSearch());
  };
  // -- END UPDATE SEARCH DIALOG HANDLERS

  const handleResetNode = () => {
    d(resetNode());
  };

  useEffect(() => {
    if (isOpen === false) return;
    if (nodeType === null) return;
    d(getKeysList({ nodeId, nodeType }));
  }, [d, isOpen, nodeId]);

  useEffect(
    function forceSelectNode() {
      if (isOpen === false) return;
      if (nodeName !== null) return;
      d(selectFirstNode());
    },
    [d, isOpen, nodeName],
  );

  useEffect(
    function fetchCustomSearch() {
      if (isOpen === false) return;
      d(getCustomSearch());
    },
    [d, isOpen],
  );

  const newSearchDialogView = (
    <SetSearchNameDialog
      handleClose={handleNewSearchDialogClose}
      handleNameUpdate={handleNewSearchNameUpdate}
      setIsPrivate={setIsPrivate}
      handleSave={handleNewSearchSave}
      isOpen={isNewSearchNameDialogOpen}
      name={newSearchName}
      isInvalidInput={invalidSaveSearchInput}
      isSavedSearchPrivate={false}
    />
  );

  const updateSearchDialogView = (
    <SetSearchNameDialog
      handleClose={handleUpdateDialogToggle}
      handleNameUpdate={handleUpdateSearchName}
      setIsPrivate={setIsPrivate}
      handleSave={handleUpdateSearch}
      isOpen={state.isUpdateSearchDialogOpen}
      name={state.searchSettingName}
      isInvalidInput={invalidSaveSearchInput}
      isSavedSearchPrivate={isPrivate}
    />
  );

  const areAllSearchFieldsEmpty = () => {
    const tasknameValue =
      state.search.taskname?.search === undefined
        ? ''
        : state.search.taskname.search;
    const creatorValue = state.search.creator.search;
    const remarkValue = state.search.maincomment.search;
    const commentValue = state.search.comment.search;
    const nameValue = state.search.name.search;
    const valueValue = state.search.value.search;
    return (
      tasknameValue === '' &&
      creatorValue === '' &&
      remarkValue === '' &&
      commentValue === '' &&
      (nameValue === '' || nameValue === null || nameValue === undefined) &&
      valueValue === ''
    );
  };

  const filterKeysList = () => {
    if (taskState === 'done') {
      return state.keysList.doneTaskState;
    } else {
      return state.keysList.openTaskState;
    }
  };

  return (
    <FilterBox isOpen={isOpen}>
      <I18nProvider i18n={i18n}>
        <Paper>
          <Box sx={{ padding: '1rem' }}>
            {newSearchDialogView}
            {updateSearchDialogView}
            <FormControl fullWidth variant='outlined'>
              <InputLabel id='saved-search-label'>
                <Trans>Saved search</Trans>
              </InputLabel>
              <Select
                fullWidth
                labelId='saved-search-label'
                id='demo-simple-select-outlined'
                defaultValue={''}
                value={state.selectedSavedSearch}
                onChange={handleLoadSavedSearch}
                label={<Trans>Saved search</Trans>}
              >
                <MenuItem value=''>
                  <em>
                    <Trans>None</Trans>
                  </em>
                </MenuItem>
                {customSearches.map((s) => (
                  <MenuItem key={s.id} value={s.id}>
                    {s.isPrivate && (
                      <Box
                        component='img'
                        alt={'isPrivate icon'}
                        sx={{ height: '1em', width: '1em', marginRight: '8px' }}
                        src={typeIcons('USER')}
                      />
                    )}
                    {s.name}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
            <Box mt={5} />
            <Box>
              <Typography variant='h6'>
                <Trans>Selected</Trans>
              </Typography>
              <RadioGroup
                name='search-area'
                value={
                  state.areAllDepartmentsSelected
                    ? 'all-departments'
                    : 'current-node'
                }
                onChange={handleSearchArea}
                onKeyDown={(e) => {
                  if (e.key === 'Enter' && !areAllSearchFieldsEmpty()) {
                    e.preventDefault();
                    handleSearch();
                  }
                }} 
              >
                <FormControlLabel
                  value='current-node'
                  control={
                    <Radio
                      size='small'
                      sx={state.areAllDepartmentsSelected ? {} : highlightStyle}
                    />
                  }
                  label={
                    <Box
                      display='flex'
                      alignItems='center'
                      flexWrap='wrap'
                      overflow='hidden'
                    >
                      <img src={typeIcons(nodeType)} />
                      <Box pl='0.3em'>{nodeName}</Box>
                    </Box>
                  }
                />
                <FormControlLabel
                  value='all-departments'
                  control={
                    <Radio
                      size='small'
                      sx={state.areAllDepartmentsSelected ? highlightStyle : {}}
                    />
                  }
                  label={<Trans>All departments</Trans>}
                />
              </RadioGroup>
            </Box>
            <Box mt={5} />
            <FormControl fullWidth
              onKeyDown={(e) => {
                if (e.key === 'Enter' && !areAllSearchFieldsEmpty()) {
                  e.preventDefault();
                  handleSearch();
                }
              }} 
              variant='outlined'>
              <InputLabel id='demo-simple-select-outlined-label'>
                <Trans>Period</Trans>
              </InputLabel>
              <Select
                fullWidth={true}
                labelId='demo-simple-select-outlined-label'
                id='demo-simple-select-outlined'
                value={timeSpan}
                onChange={hanldeTimespanSelector}
                label={<Trans>Period</Trans>}
                sx={{
                  ...(timeSpan !== timeSpanSelector.yAll && {
                    backgroundColor: '#E8F0FE',
                  }),
                }}
                >
                <MenuItem value={timeSpanSelector.w1}>
                  <Trans>last week</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.m1}>
                  <Trans>last month</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.m2}>
                  <Trans>2 months</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.m3}>
                  <Trans>3 months</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.y1}>
                  <Trans>1 year</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.y2}>
                  <Trans>2 years</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.y3}>
                  <Trans>3 years</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.y4}>
                  <Trans>4 years</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.y5}>
                  <Trans>5 years</Trans>
                </MenuItem>
                <MenuItem value={timeSpanSelector.yAll}>
                  <Trans>All</Trans>
                </MenuItem>
              </Select>
            </FormControl>
            <Box m={2} />
            <FormControl 
              component='fieldset'
               onKeyDown={(e) => {
                if (e.key === 'Enter' && !areAllSearchFieldsEmpty()) {
                  e.preventDefault();
                  handleSearch();
                }
              }}
              >
              <FormLabel component='legend'>
                <Trans>Status</Trans>
              </FormLabel>
              <FormGroup>
                <FormControlLabel
                  control={
                    <Checkbox
                      size='small'
                      checked={ticketStatus.open}
                      onChange={handleStatusCheck}
                      name='open'
                      sx={checkedStyles}
                    />
                  }
                  label={<Trans>Open</Trans>}
                />
                <FormControlLabel
                  control={
                    <Checkbox
                      size='small'
                      checked={ticketStatus.closed}
                      onChange={handleStatusCheck}
                      name='closed'
                      sx={checkedStyles}
                    />
                  }
                  label={<Trans>Done</Trans>}
                />
              </FormGroup>
            </FormControl>
            <Box m={2} />
            {/* <TextField
            value={''}
            onChange={() => {}}
            InputProps={{
              startAdornment: (
                <InputAdornment position='start'>
                  <SearchIcon />
                </InputAdornment>
              )
            }}
            label={<Trans>Search</Trans>}
          /> */}
            <FormControl fullWidth={true} 
              onChange={handleSearchParamForm}
              onKeyDown={(e) => {
                if (e.key === 'Enter' && !areAllSearchFieldsEmpty()) {
                  e.preventDefault();
                  handleSearch();
                }
              }}
              >
              <TextFieldComponent
                name='taskname'
                label={<Trans>Task name</Trans>}
                searchValue={state.search.taskname.search}
                highlight={!!state.search.taskname.search}
              />
              <SplitComponent label={<Trans>And</Trans>} />
              <TextFieldComponent
                name='creator'
                label={<Trans>Creator</Trans>}
                searchValue={state.search.creator.search}
                highlight={!!state.search.creator.search}
              />
              <SplitComponent label={<Trans>And</Trans>} />
              <TextFieldComponent
                name='maincomment'
                label={<Trans>Remark</Trans>}
                searchValue={state.search.maincomment.search}
                highlight={!!state.search.maincomment.search}
              />
              <SplitComponent label={<Trans>And</Trans>} />
              <TextFieldComponent
                name='comment'
                label={<Trans>Comment</Trans>}
                searchValue={state.search.comment.search}
                highlight={!!state.search.comment.search}
              />
              <SplitComponent label={<Trans>And</Trans>} />
              <KeyValueComponent
                options={filterKeysList()}
                highlight={!!state.search.name.search}
                highlightVal={!!state.search.value.search}
              />
            </FormControl>
            <Box m={2} />

            <Box m={2} />
            <Button
              fullWidth={true}
              variant='outlined'
              onClick={handleSearch}
              disabled={areAllSearchFieldsEmpty()}
              sx={{ borderColor: '#0000003A', color: '#000000DE' }}
            >
              <Trans>Search</Trans>
            </Button>
            <Box m={1} />
            <Button
              onClick={handleNewSearchDialogOpen}
              fullWidth={true}
              variant='outlined'
              sx={{ borderColor: '#0000003A', color: '#000000DE' }}
            >
              <Trans>Save</Trans>
            </Button>
            <Box m={1} />
            {state.selectedSavedSearch !== '' && (
              <>
                <Button
                  fullWidth
                  variant='outlined'
                  onClick={handleSavedSearchUpdate}
                  sx={{ borderColor: '#0000003A', color: '#000000DE' }}
                >
                  <Trans>Update</Trans>
                </Button>
                <Box m={1} />
                <Button
                  fullWidth
                  variant='outlined'
                  onClick={handleDeleteSelectedSetting}
                  sx={{ borderColor: '#f50057', color: '#f50057' }}
                >
                  <Trans>Delete</Trans>
                </Button>
              </>
            )}
            <Box m={1} />
            <Button
              onClick={handleClose}
              fullWidth
              variant='outlined'
              sx={{ borderColor: '#f50057', color: '#f50057' }}
            >
              <Trans>Cancel</Trans>
            </Button>
          </Box>
        </Paper>
      </I18nProvider>
    </FilterBox>
  );
};

export default SearchDrawer;
