import React, { useState, useContext } from "react";

import { usePipelineMappings } from "@qltr/queries";
import StoreContext from "@qltr/store";
import { useJobCore, jobStatus } from "@qltr/jobcore";

import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";
import Accordion from "@mui/material/Accordion";
import AccordionDetails from "@mui/material/AccordionDetails";
import AccordionSummary from "@mui/material/AccordionSummary";
import Typography from "@mui/material/Typography";

import IconButton from "@mui/material/IconButton";
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
import ViewColumnIcon from "@mui/icons-material/ViewColumn";

import Box from "@mui/material/Box";
import Stack from "@mui/material/Stack";
import { asTree, asBranches, as1d } from "@qltr/util/pipelines.js";

export default function CatalogBox(props) {
  const { catalogTest } = props;

  const {
    name: testName,
    class: testClass,
    repo: testRepo,
    isPipeline,
    type: testType,
    job,
    pipeline,
  } = catalogTest;

  const { data: pipelineMappings, isLoading } = usePipelineMappings();
  const { state: store } = useContext(StoreContext);
  const { jobCompose, toPipeline, toJob, jobIcon, pipelineIcon } = useJobCore();
  const [open, setOpen] = useState(false);
  const toggleOpen = () => setOpen(!open);
  const theme = useTheme();
  const minifyActions = useMediaQuery(theme.breakpoints.down("sm"));

  const navigateToJob = () => {
    if (pipeline) return toPipeline(pipeline.id);
    toJob(job.jobId);
  };

  const runTest = () => {
    if (isPipeline) return runPipelineTest();
    const jobId = jobCompose({
      testNames: [testName],
      isTriage: store.triageFailing,
    });
    if (store.focusJob) toJob(jobId);
  };

  const runPipelineTest = () => {
    if (isLoading) {
      console.log("Pipeline mappings are loading, retrying in 5 seconds");
      setTimeout(runPipelineTest, 5000);
    }
    const primaries = pipelineMappings.filter((m) =>
      m.find((t) => t.name === testName)
    );
    const builderCache = {
      branches: asBranches(primaries),
      tree: asTree(primaries),
      selectedBranches: as1d(primaries),
      isTriage: true,
    };
    const pipeline = jobCompose(builderCache);
    if (store.focusJob) toPipeline(pipeline.id);
  };

  const jobOnClick = (e) => {
    e.preventDefault();
    e.stopPropagation();
    if (pipeline) return navigateToJob();
    if (!job) return runTest();
    navigateToJob();
  };

  function boxIcon() {
    if (pipeline) return pipelineIcon(pipeline);
    if (!job) return <PlayArrowIcon />;
    return jobIcon(job);
  }

  return (
    <Accordion
      expanded={open}
      disableGutters={true}
      onChange={toggleOpen}
      square
    >
      <AccordionSummary
        style={{
          backgroundColor: "rgba(0, 0, 0, .03)",
          flexWrap: "wrap",
        }}
      >
        <Typography
          component={"span"}
          style={{ wordBreak: "break-word", margin: "auto 0" }}
        >
          {`${testClass}#`}
          <Box fontWeight="bold" display="inline">
            {testName}
            {isPipeline && (
              <IconButton component="span">
                <ViewColumnIcon />
              </IconButton>
            )}
          </Box>
          <br />
        </Typography>
        <Stack
          direction={minifyActions ? "column" : "row"}
          sx={{ ml: "auto", mb: "auto", mt: "auto", whiteSpace: "nowrap" }}
        >
          <IconButton
            color="success"
            aria-label="play"
            component="span"
            onClick={jobOnClick}
          >
            {boxIcon()}
          </IconButton>
        </Stack>
      </AccordionSummary>
      <AccordionDetails>
        <Typography component={"span"} style={{ wordBreak: "break-word" }}>
          {"Test info"}
        </Typography>
      </AccordionDetails>
    </Accordion>
  );
}
