import styles from './styles.module.css'
import {useEffect, useState} from "react";
import DeleteForever from "@mui/icons-material/DeleteForever";
import StopCircle from "@mui/icons-material/StopCircle";
import PauseCircleOutline from "@mui/icons-material/PauseCircleOutline";
import PlayCircleOutline from "@mui/icons-material/PlayCircleOutline";
import HourglassEmpty from "@mui/icons-material/HourglassEmpty";
import CheckCircleOutline from "@mui/icons-material/CheckCircleOutline";
import ErrorOutline from "@mui/icons-material/ErrorOutline";
import Replay from "@mui/icons-material/Replay";
import RunCircle from "@mui/icons-material/RunCircle";
import {IconButton, LinearProgress, Table, TableBody, TableCell, TableHead, TableRow} from "@mui/material";

export interface ProcessExceptionInterface {
    message: string,
    file: string,
    line: number,
    code: number,
    trace: any[],
}

export interface ProcessProgressInterface {
    total: number,
    progress: number,
    memory: any[],
}

export interface ProcessInterface {
    id: string,
    lock: string | null,
    containerUuid: string | null,
    pid: bigint | null,
    name: string,
    options: Record<string, any>,
    arguments: Record<string, any>,
    exception: ProcessExceptionInterface | null,
    progress: ProcessProgressInterface | null,
    createdAt: string,
    updatedAt: string | null,
    startedAt: string | null,
    pausedAt: string | null,
    cancelledAt: string | null
    completedAt: string | null
}

enum Status {
    Wait,
    Running,
    Cancelled,
    Error,
    Success
}

export default function Processes() {
    const [processes, setProcesses] = useState<ProcessInterface[]>([]);

    let refreshProcesses = async () => {
        let response = await fetch('http://fmw.sipachev.sv/system-monitoring/processes', {
            method: 'GET',
            headers: {
                'X-Plugin-Token': 'passw0rd'
            },
        });
        const processes: ProcessInterface[] = await response.json()
        setProcesses(processes)
        setTimeout(() => refreshProcesses, 1000)
    }

    useEffect(() => {
        refreshProcesses()
    }, [])

    let isFinished = (process: ProcessInterface) => process.cancelledAt || process.completedAt
    let canPlay = (process: ProcessInterface) => !isFinished(process) && process.progress && process.pausedAt
    let canPause = (process: ProcessInterface) => !isFinished(process) && process.progress && !process.pausedAt
    let canRepeat = (process: ProcessInterface) => isFinished(process)
    let canStop = (process: ProcessInterface) => !isFinished(process) && process.progress
    let canKill = (process: ProcessInterface) => !isFinished(process)
    let progress = (progress: ProcessProgressInterface) => progress.progress / progress.total * 100

    let status = (process: ProcessInterface): Status => {
        if (process.cancelledAt && process.completedAt) {
            return Status.Cancelled
        }
        if (process.exception && process.completedAt) {
            return Status.Error
        }
        if (!process.exception && process.completedAt) {
            return Status.Success
        }
        if (process.startedAt && !process.completedAt) {
            return Status.Running
        }
        return Status.Wait
    }

    return (
        <Table>
            <TableHead>
                <TableRow>
                    <TableCell>Name</TableCell>
                    <TableCell>Progress</TableCell>
                    <TableCell>Action</TableCell>
                    <TableCell>Status</TableCell>
                </TableRow>
            </TableHead>
            <TableBody>
                {processes.map((process: ProcessInterface, index: number) => (
                    <TableRow key={process.id}>
                        <TableCell>{process.name}</TableCell>
                        <TableCell>
                            {!process.progress && <LinearProgress/>}
                            {process.progress && <LinearProgress value={progress(process.progress)}/>}
                            {process.progress && <span>
                                {`${process.progress.progress}`} / {`${process.progress.total}`} - 50% [53Mb] / 20 sec
                            </span>}
                            {canPlay(process) && <IconButton aria-label="Play">
                                <PlayCircleOutline/>
                            </IconButton>}
                            {canPause(process) && <IconButton aria-label="Pause">
                                <PauseCircleOutline/>
                            </IconButton>}
                            {canStop(process) && <IconButton aria-label="Stop">
                                <StopCircle/>
                            </IconButton>}
                        </TableCell>
                        <TableCell>
                            {canRepeat(process) && <IconButton aria-label="Repeat">
                                <Replay/>
                            </IconButton>}
                            {canKill(process) && <IconButton aria-label="Kill">
                                <DeleteForever/>
                            </IconButton>}
                        </TableCell>
                        <TableCell>
                            {Status.Error === status(process) && <IconButton aria-label="Error">
                                <ErrorOutline/>
                            </IconButton>}
                            {Status.Success === status(process) && <IconButton aria-label="Success">
                                <CheckCircleOutline/>
                            </IconButton>}
                            {Status.Running === status(process) && <IconButton aria-label="Running">
                                <RunCircle/>
                            </IconButton>}
                            {Status.Cancelled === status(process) && <IconButton aria-label="Cancelled">
                                <StopCircle/>
                            </IconButton>}
                            {Status.Wait === status(process) && <IconButton aria-label="Wait">
                                <HourglassEmpty/>
                            </IconButton>}
                        </TableCell>
                    </TableRow>
                ))}
            </TableBody>
        </Table>
    )
}
