import {ReactElement, useCallback, useRef, useState} from "react";
import {ProgressBar, Stack} from "react-bootstrap";
import {useAnimationFrame} from "./AnimationHook";
import {isDefined} from "../types/type_check";
import "./TurnTimer.css";
import formatDuration from "format-duration";

export interface TurnTimerArgs {
    readonly title?: string
    readonly startTime?: number
    readonly endTime?: number
    readonly displayedTime?: number
    readonly resolutionMs?: number
}

const DEFAULT_RESOLUTION_MS = 100;

export function TurnTimer({title, startTime, endTime, displayedTime, resolutionMs = DEFAULT_RESOLUTION_MS}: TurnTimerArgs): ReactElement {
    const [currentTime, setCurrentTime] = useState(() => displayedTime ?? Date.now())
    const accumulatedTime = useRef(0)
    const animationCallback = useCallback(isDefined(displayedTime)
        ? () => null
        : (delta: number) => {
            accumulatedTime.current += delta
            if (accumulatedTime.current > resolutionMs) {
                accumulatedTime.current %= resolutionMs
                setCurrentTime(Date.now())
            }
        }, [displayedTime, setCurrentTime, accumulatedTime])
    useAnimationFrame(animationCallback)

    if (isDefined(displayedTime) && displayedTime !== currentTime) {
        setCurrentTime(displayedTime)
        accumulatedTime.current = resolutionMs
    }

    let totalTime: number|null = null
    let timeRemaining: number|null = null
    let timeElapsed: number|null = null
    if (isDefined(startTime)) {
        if (isDefined(endTime)) {
            totalTime = endTime - startTime
            timeRemaining = endTime - currentTime
        } else {
            timeElapsed = currentTime - startTime
        }
    } else if (isDefined(endTime)) {
        timeRemaining = endTime - currentTime
    }

    return <Stack className={"turnTimer"} direction="vertical">
        <h2 className={"turnTimerTitle"}>{title}</h2>
        {(timeRemaining !== null || timeElapsed !== null) && <div className={"turnTimerTime"}>{formatDuration(timeRemaining ?? timeElapsed ?? 0)}</div>}
        {timeRemaining !== null && totalTime !== null && <ProgressBar className={"turnTimerBar"} now={timeRemaining} max={totalTime} />}
    </Stack>
}