import { useQuery } from '@apollo/client';
import { faPlayCircle, faVial } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { CircularProgress, Collapse, IconButton, LinearProgress, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, makeStyles, useTheme } from '@material-ui/core';
import { Cancel, CheckCircle, CloudDownload, ShoppingCart, Timer } from '@material-ui/icons';
import { format } from 'date-fns';
import React, { FC, Fragment, ReactNode, useState } from 'react';
import { Commit, Pipeline, PipelineTask, TaskStatuses } from '../generated/graphql';
import { COMMITS } from './queries';

interface Props {
  pipeline: Pipeline;
}

const useStyles = makeStyles((theme) => ({
  root: {
    flex: "1 1 100%",
  },
  nested: {
    paddingLeft: theme.spacing(4),
  },
}));

export const CommitList: FC<Props> = ({pipeline}) => {
  const { data, loading } = useQuery<{ commits: Commit[] }>(COMMITS, {
    variables: {
      pipelineId: pipeline.id,
    },
  });

  const classes = useStyles();

  return (
    <section className={classes.root}>
      {(() => {
        if (loading) {
          return <LinearProgress color="secondary" />;
        }

        return <List>
          {data?.commits.map(commit => (
            <Item key={commit.hash} commit={commit} />
          ))}
        </List>;
      })()}
    </section>
  )
}

const Item: FC<{commit: Commit}> = ({commit}) => {
  const [isOpen, setOpen] = useState(() => false);
  const classes = useStyles();
  return (
    <Fragment>
      <ListItem button onClick={() => setOpen(!isOpen)}>
        <ListItemText
          primary={commit.message}
          secondary={format(commit.date, "yyyy-MM-dd HH:mm:ss")}
        />
        <ListItemSecondaryAction>
          <IconButton edge="end" aria-label="delete">
            <ShoppingCart />
          </IconButton>
          <IconButton edge="end" aria-label="delete">
            <CloudDownload />
          </IconButton>
          <IconButton edge="end" aria-label="delete">
            <FontAwesomeIcon icon={faVial} />
          </IconButton>
          <IconButton edge="end" aria-label="delete">
            <FontAwesomeIcon icon={faPlayCircle} />
          </IconButton>
        </ListItemSecondaryAction>
      </ListItem>
      <Collapse in={isOpen} timeout="auto" unmountOnExit>
        <List component="div" disablePadding>
          {
            commit.tasks.map(task => (<TaskItem key={task.id} task={task} />))
          }
        </List>
      </Collapse>
    </Fragment>
  );
}

const TaskItem: FC<{task: PipelineTask}> = ({task}) => {
  const classes = useStyles();
  const theme = useTheme();
  const statusIcon: ReactNode = (() => {
    switch (task.status) {
      case TaskStatuses.Pending:
        return <Timer style={{ color: theme.palette.info.main }} />;
      case TaskStatuses.Success:
        return <CheckCircle style={{ color: theme.palette.success.main }} />;
      case TaskStatuses.Failed:
        return <Cancel style={{ color: theme.palette.error.main }} />;
      case TaskStatuses.Working:
        return <CircularProgress style={{ color: theme.palette.secondary.main }} />;

    }
  }
  )()
  return (
    <ListItem button className={classes.nested}>
      <ListItemIcon>{statusIcon}</ListItemIcon>
      <ListItemText primary={format(task.startedAt, "yyyy-MM-dd HH:mm:ss")} />
    </ListItem>
  );
};