"use client";

import { FC, useState, useEffect } from "react";
import {
  Box,
  Button,
  Grid,
  Popover,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Dialog,
  Divider,
  Paper,
  MenuList,
  MenuItem,
  ListItemText,
  ListItemIcon,
  TextField,
} from "@mui/material";
import {
  ExpandMore as ExpandMoreIcon,
  AddCircleOutline as AddCircleOutlineIcon,
  SavedSearch as SavedSearchIcon,
  RemoveCircle as RemoveCircleIcon,
} from "@mui/icons-material";
import { useTranslate } from "react-polyglot";
import { QueryBuilder } from "@/app/_components/QueryBuilder";
import { QueryText } from "@/app/_components/QueryText";
import { LiveDataViewer } from "@/app/_components/LiveDataViewer";
import { Tooltip } from "@/app/_components/Tooltip";
import visualizationMap from "app/_config/visualizationMap.json";
import { VisualizationSelectCard } from "./VisualizationSelectCard";
import { MetricSelectCard } from "./MetricSelectCard";
import { useAppContext } from "./AppProvider";

interface VisualizationBuilderProps {
  templates: any[];
}

export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
  templates,
}) => {
  const t = useTranslate();
  const {
    typography: { h4 },
    colors: { white, leafcutterElectricBlue, cdrLinkOrange },
    foundCount,
    query,
    replaceQuery,
    clearQuery,
  } = useAppContext();
  const { visualizations } = visualizationMap;
  const [selectedVisualizationType, setSelectedVisualizationType] = useState(
    null as any
  );
  const toggleSelectedVisualizationType = (visualizationType: string) => {
    if (visualizationType === selectedVisualizationType) {
      setSelectedVisualizationType(null);
    } else {
      setSelectedVisualizationType(visualizationType);
    }
  };
  const [dialogOpen, setDialogOpen] = useState(false);
  const [savedSearches, setSavedSearches] = useState([]);
  const [savedSearchName, setSavedSearchName] = useState("");
  const [anchorEl, setAnchorEl] = useState(null);

  const updateSearches = async () => {
    const result = await fetch("/api/searches/list");
    const existingSearches = await result.json();
    setSavedSearches(existingSearches);
  };
  useEffect(() => {
    updateSearches();
  }, [setSavedSearches]);

  const showSavedSearchPopup = (event: any) => {
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    setSavedSearchName("");
    setAnchorEl(null);
  };
  const closeDialog = () => {
    setDialogOpen(false);
  };
  const createSavedSearch = async (name: string, q: any) => {
    await fetch("/api/searches/create", {
      method: "POST",
      body: JSON.stringify({ name, query: q }),
    });
    await updateSearches();
    handleClose();
    closeDialog();
  };

  const deleteSavedSearch = async (name: string) => {
    await fetch("/api/searches/delete", {
      method: "POST",
      body: JSON.stringify({ name }),
    });
    await updateSearches();
    closeDialog();
  };

  const updateSearch = (name: string) => {
    handleClose();
    closeDialog();
    const found: any = savedSearches.find(
      (search: any) => search.name === name
    );
    replaceQuery(found?.query);
  };

  const clearSearch = () => clearQuery();

  const open = Boolean(anchorEl);
  const elementID = open ? "simple-popover" : undefined;
  const [queryExpanded, setQueryExpanded] = useState(true);
  const [resultsExpanded, setResultsExpanded] = useState(false);
  const minHeight = "42px";
  const maxHeight = "42px";
  const summaryStyles = {
    backgroundColor: leafcutterElectricBlue,
    height: "14px",
    minHeight,
    maxHeight,
    "&.Mui-expanded": {
      minHeight,
      maxHeight,
    },
  };
  const buttonStyles = {
    fontFamily: "Poppins, sans-serif",
    fontWeight: 700,
    color: `${white} !important`,
    borderRadius: 999,
    backgroundColor: leafcutterElectricBlue,
    padding: "6px 30px",
    margin: "20px 0px",
    whiteSpace: "nowrap",
  };

  return (
    <Box>
      <Dialog open={dialogOpen}>
        <Box sx={{ pt: 3, pl: 3, pr: 3 }}>
          <Grid container direction="column" spacing={2}>
            <Grid item>
              <TextField
                size="small"
                placeholder="Saved search name"
                sx={{ width: 400 }}
                onChange={(e) => setSavedSearchName(e.target.value)}
              />
            </Grid>
            <Grid item container direction="row" justifyContent="space-between">
              <Grid item>
                <Button sx={buttonStyles} onClick={closeDialog}>
                  Cancel
                </Button>
              </Grid>
              <Grid item>
                <Button
                  sx={buttonStyles}
                  onClick={async () => {
                    await createSavedSearch(savedSearchName, query);
                  }}
                >
                  Save
                </Button>
              </Grid>
            </Grid>
          </Grid>
        </Box>
      </Dialog>
      <Grid
        container
        direction="row"
        sx={{ mt: 4, mb: 2 }}
        justifyContent="space-between"
      >
        <Grid item>
          <Tooltip
            title={t("searchAndCreateTitle")}
            description={t("searchAndCreateDescription")}
            tooltipID="searchCreate"
            nextURL="/create?tooltip=categories"
            previousURL="/?tooltip=profile"
            placement="top"
          >
            <Box sx={h4}>Search Criteria</Box>
          </Tooltip>
        </Grid>
        <Grid item>
          <Button
            aria-describedby={elementID}
            variant="contained"
            onClick={showSavedSearchPopup}
            sx={{
              backgroundColor: cdrLinkOrange,
              textTransform: "none",
              fontStyle: "italic",
              fontWeight: "bold",
            }}
          >
            <SavedSearchIcon sx={{ mr: 1 }} />
            {t("savedSearch")}
          </Button>
          <Button
            variant="contained"
            onClick={clearSearch}
            sx={{
              backgroundColor: leafcutterElectricBlue,
              textTransform: "none",
              fontWeight: "bold",
              ml: 3,
            }}
          >
            {t("clear")}
          </Button>
          <Popover
            id={elementID}
            open={open}
            anchorEl={anchorEl}
            onClose={handleClose}
            anchorOrigin={{
              vertical: "bottom",
              horizontal: "right",
            }}
            transformOrigin={{ vertical: "top", horizontal: "right" }}
          >
            <Paper>
              <MenuList>
                <MenuItem
                  onClick={() => {
                    handleClose();
                    setDialogOpen(true);
                  }}
                >
                  <ListItemIcon>
                    <AddCircleOutlineIcon fontSize="small" />
                  </ListItemIcon>
                  <ListItemText>{t("saveCurrentSearch")}</ListItemText>
                </MenuItem>
                <Divider />
                {savedSearches.map((savedSearch: any) => (
                  <MenuItem
                    key={savedSearch.name}
                    onClick={() => updateSearch(savedSearch.name)}
                  >
                    <ListItemIcon />
                    <ListItemText>{savedSearch.name}</ListItemText>
                    <Box
                      onClick={() => deleteSavedSearch(savedSearch.name)}
                      sx={{ p: 0, m: 0, zIndex: 100 }}
                    >
                      <RemoveCircleIcon
                        sx={{
                          color: cdrLinkOrange,
                          p: 0,
                          m: 0,
                          ":hover": { color: leafcutterElectricBlue },
                        }}
                      />
                    </Box>
                  </MenuItem>
                ))}
              </MenuList>
            </Paper>
          </Popover>
        </Grid>
      </Grid>
      <QueryBuilder />
      <Accordion
        expanded={queryExpanded}
        onClick={() => setQueryExpanded(!queryExpanded)}
      >
        <AccordionSummary
          expandIcon={<ExpandMoreIcon sx={{ color: white, fontSize: 28 }} />}
          sx={summaryStyles}
        >
          <Box sx={{ ...h4, color: white }}>{t("query")}</Box>
        </AccordionSummary>
        <AccordionDetails sx={{ p: 2 }}>
          <QueryText />
        </AccordionDetails>
      </Accordion>
      <Accordion
        sx={{ mt: 2 }}
        expanded={resultsExpanded}
        onClick={() => setResultsExpanded(!resultsExpanded)}
      >
        <AccordionSummary
          expandIcon={<ExpandMoreIcon sx={{ color: white, fontSize: 28 }} />}
          sx={summaryStyles}
        >
          <Box sx={{ ...h4, color: white }}>{`${t(
            "results"
          )} (${foundCount})`}</Box>
        </AccordionSummary>
        <Tooltip
          title={`${t("queryResultsCardTitle")}`}
          description={t("queryResultsCardDescription")}
          tooltipID="queryResults"
          placement="top"
          previousURL="/create?tooltip=advancedOptions"
          nextURL="/create?tooltip=viewResults"
        >
          <AccordionDetails sx={{ p: 2, pb: 4 }}>
            <LiveDataViewer />
          </AccordionDetails>
        </Tooltip>
      </Accordion>
      <Tooltip
        title={t("viewResultsCardTitle")}
        description={t("viewResultsCardDescription")}
        tooltipID="viewResults"
        placement="top"
        previousURL="/create?tooltip=queryResults"
      >
        <Box sx={{ ...h4, mt: 6, mb: 2 }}>{t("selectVisualization")}:</Box>
      </Tooltip>
      <Box display="grid" gridTemplateColumns="repeat(5, 1fr)" gap={2}>
        {Object.keys(visualizations).map((key: string) => (
          <VisualizationSelectCard
            key={key}
            visualizationType={key}
            // @ts-expect-error
            title={visualizations[key].name}
            enabled={
              selectedVisualizationType === key ||
              selectedVisualizationType === null
            }
            selected={selectedVisualizationType === key}
            toggleSelected={toggleSelectedVisualizationType}
          />
        ))}
      </Box>
      <Box sx={{ ...h4, mt: 6, mb: 2 }}>{t("selectFieldVisualize")}:</Box>
      <Box
        display="grid"
        gridTemplateColumns="repeat(5, 1fr)"
        gap={2}
        sx={{ minHeight: 200 }}
      >
        {templates
          .filter(
            (template: any) => template.type === selectedVisualizationType
          )
          .map((template: any) => {
            const { id, type, title, description } = template;
            const cleanTitle = title
              .replace("Templated", "")
              // @ts-expect-error
              .replace(visualizations[type].name, "");
            const metricType = cleanTitle.replace(/\s/g, "").toLowerCase();
            return (
              <MetricSelectCard
                key={id}
                visualizationID={id}
                metricType={metricType}
                title={`By ${cleanTitle}`}
                description={description}
                enabled
              />
            );
          })}
      </Box>
    </Box>
  );
};
