<script lang="ts">
    import Button from "$shared/components/button.svelte";
    import {Textarea} from "$shared/components/form";
    import {StorageKeys} from "$shared/lib/configuration";
    import {StoreType, writable_persistent} from "$shared/lib/persistent-store";
    import {Temporal} from "@js-temporal/polyfill";
    import {createEventDispatcher, onMount} from "svelte";

    const state = writable_persistent({
        initialState: {
            hours: 0,
            minutes: 0,
            seconds: 0,
            startTime: null as Temporal.PlainDateTime,
            lastStep: null as Temporal.PlainDateTime,
            isRunning: false,
            intervalId: 0,
            note: "",
        },
        options: {
            store: StoreType.LOCAL
        },
        name: StorageKeys.stopwatch,
    });

    let timeString;

    $: if ($state.hours || $state.minutes || $state.seconds) {
        timeString = $state.hours.toLocaleString(undefined, {minimumIntegerDigits: 2})
            + ":" + $state.minutes.toLocaleString(undefined, {minimumIntegerDigits: 2})
            + ":" + $state.seconds.toLocaleString(undefined, {minimumIntegerDigits: 2});
    } else {
        timeString = "--:--:--";
    }

    onMount(() => {
        start_if_running();
    });

    function start_if_running() {
        if ($state.isRunning) {
            if (Temporal.PlainDateTime.compare($state.lastStep, Temporal.Now.plainDateTimeISO()) == -1) {
                const duration = Temporal.Now.plainDateTimeISO().since($state.lastStep, {smallestUnit: "second"});
                console.log("lastStep",$state.lastStep.toString());
                console.log("duration", duration.toString());
                console.log(duration.seconds);
                // for (let i = 0; i < steps; i++) {
                //     step();
                // }
            }
            clearInterval($state.intervalId);
            $state.intervalId = setInterval(step, 1000);
        }
    }

    window.addEventListener("focus", () => {
        start_if_running();
    });

    const dispatch = createEventDispatcher();

    function step() {
        $state.seconds = $state.seconds + 1;

        if ($state.seconds == 60) {
            $state.minutes = $state.minutes + 1;
            $state.seconds = 0;
        }

        if ($state.minutes == 60) {
            $state.hours = $state.hours + 1;
            $state.minutes = 0;
            $state.seconds = 0;
        }

        if (!$state.startTime) $state.startTime = Temporal.Now.plainDateTimeISO();
        $state.lastStep = Temporal.Now.plainDateTimeISO();
    }

    function reset() {
        clearInterval($state.intervalId);
        $state.isRunning = false;
        $state.hours = 0;
        $state.minutes = 0;
        $state.seconds = 0;
        $state.startTime = null;
        $state.intervalId = 0;
        $state.note = "";
    }

    let roundUpToNearest = 30;
    let roundDownToNearest = 30;

    function on_round_up() {
        const newTime = Temporal.PlainTime
            .from({hour: $state.hours, minute: $state.minutes, second: $state.seconds})
            .round({
                roundingIncrement: roundUpToNearest,
                smallestUnit: "minute",
                roundingMode: "ceil"
            });
        $state.hours = newTime.hour;
        $state.minutes = newTime.minute;
        $state.seconds = newTime.second;
    }

    function on_round_down() {
        const newTime = Temporal.PlainTime
            .from({hour: $state.hours, minute: $state.minutes, second: $state.seconds,})
            .round({
                roundingIncrement: roundDownToNearest,
                smallestUnit: "minute",
                roundingMode: "trunc"
            });
        $state.hours = newTime.hour;
        $state.minutes = newTime.minute;
        $state.seconds = newTime.second;
    }

    function on_start_stop() {
        if ($state.isRunning) {
            clearInterval($state.intervalId);
            $state.isRunning = false;
            return;
        }
        step();
        $state.intervalId = setInterval(step, 1000);
        $state.isRunning = true;
    }

    function on_create_entry() {
        if (!$state.startTime) return;
        const plainStartTime = Temporal.PlainDateTime.from($state.startTime);
        dispatch("create", {
            from: plainStartTime,
            to: plainStartTime.add({hours: $state.hours, minutes: $state.minutes, seconds: $state.seconds}),
            description: $state.note
        });
        reset();
    }
</script>

<div class="grid">
    <div class="col-6">
        <slot name="header"></slot>
        <pre class="text-xxl padding-y-sm">{timeString}</pre>
    </div>
    <div class="col-6 flex align-bottom flex-column text-xs">
        <Button title="{$state.isRunning ? 'Stop' : 'Start'}"
                text="{$state.isRunning ? 'Stop' : 'Start'}"
                variant="link"
                on:click={on_start_stop}/>

        {#if $state.startTime}
            <Button title="Reset"
                    text="Reset"
                    variant="link"
                    class="bg-error-lighter@hover color-white@hover"
                    on:click={reset}/>
            {#if !$state.isRunning}
                <Button title="Round up"
                        text="Round up"
                        variant="link"
                        on:click={on_round_up}/>
                <Button title="Round down"
                        text="Round down"
                        variant="link"
                        on:click={on_round_down}/>
                {#if $state.minutes > 0 || $state.hours > 0}
                    <Button title="Create entry"
                            text="Create entry"
                            variant="link"
                            on:click={on_create_entry}/>
                {/if}
            {/if}
        {/if}
    </div>
</div>
<Textarea class="width-100% margin-top-xs"
          placeholder="What's your focus?"
          rows="1"
          bind:value={$state.note}
/>
