import Typography from "@material-ui/core/Typography";
import { CheckCircle, Error, RadioButtonUnchecked } from "@material-ui/icons";
import clsx from "clsx";
import React, { useEffect, useState } from "react";

import CircularProgress from "../CircularProgress";
import s from "./Statuses";

const AwaitStatus = -1;
const ErrorStatus = -100;
const CompleteStatus = 100;

const PHASES = [
  {
    label: "Pending",
    events: [s.Pending, s.Sent],
    progress: () => CompleteStatus,
  },
  {
    label: "Received",
    events: [s.ManifestAccepted, s.ManifestReceived, s.ManifestRejected, s.ManifestError],
    progress: (msg) => {
      if (msg === s.ManifestRejected || msg === s.ManifestError) return ErrorStatus;
      return CompleteStatus;
    },
  },
  {
    label: "Precondition",
    events: [s.PreconditionAwait, s.PreconditionSuceeded],
    progress: () => CompleteStatus,
  },
  {
    label: "Download",
    events: [
      s.Downloading,
      s.DownloadStarted,
      s.DownloadCompleted,
      s.DownloadFailed,
      s.PackageDownloadStarted,
    ],
    progress: (msg, progress) => {
      if (msg === s.DownloadFailed) return ErrorStatus;
      return progress;
    },
  },
  {
    label: "Approved",
    events: [s.PackageDownloadCompleted, s.InstallApprovalAwait],
    progress: () => AwaitStatus,
  },
  {
    label: "Install",
    events: [
      s.InstallApprovalReceived,
      s.InstallStarted,
      s.Installing,
      s.InstallSucceeded,
      s.InstallFailed,
      s.RequirementsFailed,
      s.InstallScheduled,
    ],
    progress: (msg, progress) => {
      if (msg === s.InstallFailed || msg === s.RequirementsFailed) return ErrorStatus;
      if (msg === s.PackageInstallCompleted) return CompleteStatus;
      return progress;
    },
  },
  {
    label: "Updated",
    events: [s.ManifestSucceeded, s.CleanupFailed, s.CleanupSucceeded, s.RollbackSucceeded, s.RollbackFailed],
    progress: (msg, _progress) => {
      if (msg === s.ManifestSucceeded) return CompleteStatus;
      return ErrorStatus;
    }
  },
];

const Progress = ({ value, classes }) => {
  if (value === 100)
    return (
      <CheckCircle
        className={clsx(classes.progressIcon, classes.progressSuccess)}
      />
    );
  if (value >= 0) return <CircularProgress value={value} />;
  if (value < -1)
    return (
      <Error className={clsx(classes.progressIcon, classes.progressError)} />
    );

  return <RadioButtonUnchecked className={classes.progressIcon} />;
};

const getProgress = (index, phase, progress) => {
  if (index === phase) return progress;
  if (index < phase) return CompleteStatus;
  return -1;
};

const CarUpdateStatus = ({ status, classes }) => {
  const [phase, setPhase] = useState(0);
  const [progress, setProgress] = useState(-1);

  useEffect(() => {
    if (!status) return;

    for (let i = 0, len = PHASES.length; i < len; i++) {
      const PHASE = PHASES[i];
      if (PHASE.events.indexOf(status.msg) > -1) {
        setPhase(i);
        setProgress(PHASE.progress(status.msg, status.progress));
        break;
      }
    }
  }, [status]);

  return (
    <div
      style={{
        width: "100%",
        display: "flex",
        justifyContent: "space-between",
        flexWrap: "wrap",
      }}
    >
      {PHASES.map((item, index) => {
        return (
          <div key={index} className={classes.textCenterAlign}>
            <Progress
              value={getProgress(index, phase, progress)}
              classes={classes}
            />
            <Typography>{item.label}</Typography>
          </div>
        );
      })}
    </div>
  );
};

export default CarUpdateStatus;
