import React, { useMemo } from "react";

import { AppBar, Box, Stack, Toolbar, Typography } from "@mui/material";
import { useTheme } from "@mui/material/styles";

import { Header } from "../components/Header";
import ComponentLoader from "../containers/ComponentLoader";
import Content from "../containers/Content";
import { useApi } from "../contexts/ApiContext";
import DashboardFilterContextProvider, {
  dashboardFilterToSearchParams,
  useDashboardFilter,
} from "../contexts/DashboardFilterContext";
import { useUser } from "../contexts/UserContext";
import DashboardFilter from "../extensions/pos/components/DashboardFilter";
import { hasGroup } from "../util/has_group";

/**
 * `WidgetLoader` is a separate component in order to access `DashboardFilterContext`.
 */
const WidgetLoader: React.FC = () => {
  const api = useApi();
  const { filter } = useDashboardFilter();

  const contrib = useMemo(() => api.findContrib("dashboard"), [api]);

  return contrib.map((operation, i) => (
    <ComponentLoader
      key={operation.id}
      operation={operation}
      // NOTE: For some godforsaken reason, the `query` prop is not typed as `Record<string, string>` but as `object`. Oh well.
      query={dashboardFilterToSearchParams(filter) as object}
      sx={{ "--i": `${(i + 1) * 10}` }}
    />
  ));
};

/**
 * `DashboardPage` is the main page for the dashboard.
 * It uses a manual css-grid layout, since MUI's `Grid` is
 * not actually a grid, but a 12-col, bootstrap-like layout.
 */
const DashboardPage: React.FC = () => {
  const theme = useTheme();
  const { user } = useUser();

  const title = null; // TODO: Get title from project

  if (!hasGroup(user, "analytics")) {
    return null; // TODO: Redirect to some accessible page
  }

  return (
    <DashboardFilterContextProvider>
      <Header>
        <AppBar elevation={0} position="static" sx={{ flexGrow: 1, bgcolor: "transparent" }}>
          <Toolbar variant="dense">
            <Stack
              alignItems={"center"}
              flexDirection={"row"}
              flexGrow={1}
              justifyContent={"space-between"}
            >
              <Stack>
                {title != null && (
                  <Typography color={theme.palette.text.primary} fontWeight={600} variant="h6">
                    {title}
                  </Typography>
                )}
              </Stack>

              <DashboardFilter />
            </Stack>
          </Toolbar>
        </AppBar>
      </Header>

      <Content layout="fixedWidth">
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { sm: "repeat(1, 1fr)", md: "repeat(12, 1fr)" },
            gridAutoRows: "minmax(180px, auto)",
            gridAutoFlow: "dense",
            gap: 2,
            width: "100%",
            height: "fit-content",

            // Hide spinners since we get one per card.
            ".MuiCircularProgress-root": { opacity: "0 !important" },
          }}
        >
          <WidgetLoader />
        </Box>
      </Content>
    </DashboardFilterContextProvider>
  );
};

export default DashboardPage;
