import { useState, useContext } from "react";
import { useNavigate } from "react-router-dom";
import { useCurrentlyFailing, useSilencedAlerts } from "@qltr/queries";
import StoreContext from "@qltr/store";
import JobContext from "@qltr/jobs";
import SilenceDialog from "../alerting/SilenceDialog.jsx";
import FailingBox from "./FailingBox.jsx";

import SpeedDial from "@mui/material/SpeedDial";

import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogTitle from "@mui/material/DialogTitle";
import ReplayIcon from "@mui/icons-material/Replay";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";

export default function Failing() {
  const { state: jobState, retryAll } = useContext(JobContext);
  const navigate = useNavigate();
  const { state: store, silenceRequest } = useContext(StoreContext);
  const { isLoading, data: failing } = useCurrentlyFailing();
  const { isSilencedLoading, data: silencedAlerts } = useSilencedAlerts();
  const [silenceEntry, setSilenceEntry] = useState({ open: false });

  const closeSilence = () => setSilenceEntry({ ...silenceEntry, open: false });

  const handleSilenceClose = (silenceReq) => {
    closeSilence();
    if (!silenceReq) return;
    silenceRequest(silenceReq);
  };

  const editSilence = (silence) => () => {
    setSilenceEntry({ ...silence, open: true });
  };

  const [retryAllOpen, setRetryAllOpen] = useState(false);
  const retryAllClick = () => setRetryAllOpen(!retryAllOpen);

  const handleClose = (confirmed) => () => {
    retryAllClick();
    if (!confirmed) return;
    const jobId = retryAll(store.failing);

    if (!store.focusJob) return;
    navigate(`/qualiteer/jobs#${jobId}`);
  };

  const failingTestsWithJobs = () => {
    const silences = silencedAlerts ?? [];
    for (var test of failing) {
      const silence = silences.find(
        (s) => s.name === test.name || s.class === test.class
      );

      if (silence) test.silencedUntil = silence;
      if (test.isPipeline) {
        const pipeline = jobState.pipelines.find((p) =>
          p.selectedBranches.includes(test.name)
        );
        if (!pipeline) continue;
        const pipelineJob = jobState.jobs.find(
          (j) =>
            j.isPipeline &&
            j.pipelineId === pipeline.id &&
            j.branchId === test.name
        );
        if (!pipelineJob) test.pipeline = pipeline;
        test.job = pipelineJob;
        continue;
      }
      const job = jobState.jobs.find(
        (j) => !j.isPipeline && j.builderCache.testNames.includes(test.name)
      );
      if (job) test.job = job;
    }
    return failing;
  };

  return (
    <div className="failing">
      {isLoading
        ? null
        : failingTestsWithJobs().map((v, i) => (
            <FailingBox key={i} failingTest={v} silenceClick={editSilence(v)} />
          ))}

      <Dialog
        open={retryAllOpen}
        onClose={handleClose()}
        sx={{ "& .MuiDialog-paper": { width: "80%", maxHeight: 435 } }}
        maxWidth="xs"
      >
        <DialogTitle>Retry all failing tests?</DialogTitle>
        <DialogContent>
          <DialogContentText>
            This will create x jobs and run y tests
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose()}>Cancel</Button>
          <Button onClick={handleClose(true)} autoFocus>
            Yes
          </Button>
        </DialogActions>
      </Dialog>
      <SilenceDialog
        keepMounted
        open={silenceEntry.open}
        onClose={handleSilenceClose}
        silence={silenceEntry}
      />
      {(failing ?? []).length === 0 ? (
        <Box display="flex" alignItems="center" justifyContent="center">
          <Typography variant="h4">No tests failing!</Typography>
        </Box>
      ) : null}

      {(failing ?? []).length === 0 ? null : (
        <SpeedDial
          ariaLabel="Retry All"
          sx={{ position: "fixed", bottom: 16, right: 16 }}
          icon={<ReplayIcon />}
          onClick={retryAllClick}
          open={false}
        />
      )}
    </div>
  );
}
