import {
  alpha,
  Grid2,
  IconButton,
  InputAdornment,
  InputBase,
  Theme
} from "@mui/material";
import { makeStyles } from "@mui/styles";
import { Search as SearchIcon, Cancel as CancelIcon } from "@mui/icons-material";
import classNames from "classnames";
import { useDebounce, usePrevious } from "hooks";
import { useEffect, useState } from "react";

const useStyles = makeStyles((theme: Theme) => {
  return ({
    search: {
      position: "relative",
      width: "100%",
      marginLeft: 0,
      backgroundColor: alpha(theme.palette.common.white, 0.15),
      "&:hover": {
        backgroundColor: alpha(theme.palette.common.white, 0.25)
      },
      [theme.breakpoints.up("sm")]: {
        width: "auto"
      }
    },
    inputRoot: {
      position: "relative",
      color: "inherit",
      width: "100%"
    },
    searchInput: {
      width: "100%"
    },
    spacingLeft: {
      marginLeft: theme.spacing(1)
    },
    spacingRight: {
      marginRight: theme.spacing(1)
    },
    mutedIcon: {
      color: theme.palette.text.secondary
    },
    roundBar: {
      borderRadius: theme.shape.borderRadius
    },
    squareBar: {
      borderRadius: 0
    }
  });
});

interface Props {
  value: string;
  onChange: (value: string) => void;
  shape?: "round" | "square";
}

export default function SearchBar(props: Props) {
  const classes = useStyles();
  const { value, onChange, shape } = props;
  const prevValue = usePrevious(value);
  const [search, setSearch] = useState(value);
  const debouncedSearch = useDebounce(search, 500);
  const prevDebouncedSearch = usePrevious(debouncedSearch);

  useEffect(() => {
    if (value !== prevValue) {
      setSearch(value);
    }
  }, [prevValue, value]);

  useEffect(() => {
    if (debouncedSearch !== prevDebouncedSearch) {
      onChange(debouncedSearch);
    }
  }, [debouncedSearch, prevDebouncedSearch, onChange]);

  const handleChange = (newSearch: string) => {
    setSearch(newSearch);
  };

  return (
    <Grid2
      container
      direction="row"
      className={classNames(
        classes.search,
        shape === "square" ? classes.squareBar : classes.roundBar
      )}>
      <InputBase
        autoFocus={false}
        placeholder="Search…"
        classes={{
          root: classes.inputRoot,
          input: classes.searchInput
        }}
        onChange={event => handleChange(event.target.value)}
        value={search}
        fullWidth
        inputProps={{ "aria-label": "Search" }}
        startAdornment={
          <InputAdornment position="start">
            <SearchIcon className={classes.spacingLeft} />
          </InputAdornment>
        }
        endAdornment={
          <InputAdornment position="end">
            <IconButton
              size="small"
              aria-label="Cancel Search"
              onClick={() => handleChange("")}
              className={classes.spacingRight}>
              <CancelIcon fontSize="small" className={classes.mutedIcon} />
            </IconButton>
          </InputAdornment>
        }
      />
    </Grid2>
  );
}
