<svelte:options runes={true} />

<script lang="ts">
    import * as Card from "$lib/components/ui/card";
    import {Button} from "$lib/components/ui/button";
    import {
        Grids,
        inventorySizes,
        InventoryType,
        localization, metricModifiers, type Thruster,
        ThrusterSize,
        ThrusterType,
        thrustValues, weightPerVolume
    } from "$lib/constants";
    import {Input} from "$lib/components/ui/input";
    import {Label} from "$lib/components/ui/label";
    import {Separator} from "$lib/components/ui/separator";
    import {onMount} from "svelte";

    let locale = $state("en-GB");
    let mounted = $state(false);

    let thrusters: Array<Thruster> = $state([])
    $effect(() => {
        if (mounted) {
            localStorage.setItem("thrusters", JSON.stringify(thrusters));
        }
    })
    let inventories: Array<InventoryType> = $state([])
    $effect(() => {
        if (mounted) {
            localStorage.setItem("inventories", JSON.stringify(inventories));
        }
    })

    let inventoryMultiplier = $state(1);
    $effect(() => {
        if (mounted) {
            localStorage.setItem("inventoryMultiplier", inventoryMultiplier);
        }
    })
    let gridSize = $state(Grids.Small);
    $effect(() => {
        if (mounted) {
            localStorage.setItem("gridSize", gridSize);
        }
    })

    let gravity = $state(1);
    $effect(() => {
        if (mounted) {
            localStorage.setItem("gravity", gravity);
        }
    })


    let newThruster = $state({
        type: ThrusterType.Atmospheric,
        size: ThrusterSize.Small,
    })
    $effect(() => {
        if (mounted) {
            localStorage.setItem("newThruster", JSON.stringify(newThruster))
        }
    })

    let newInventory = $state(InventoryType.CargoSmall)
    $effect(() => {
        if (mounted) {
            localStorage.setItem("newInventory", JSON.stringify(newInventory))
        }
    })

    let totalThrust = $derived.by(() => {
        let thrust = 0;
        thrusters.forEach((thruster) => {
            thrust += getThrusterPower(thruster)
        })
        return thrust
    });
    let totalVolume = $derived.by(() => {
        let volume = 0;
        inventories.forEach((inventory) => {
            volume += getInventoryVolume(inventory);
        })
        return volume;
    })

    let maxWeight = $derived(totalThrust / (gravity * 9.81))

    let maxVehicleWeight = $derived(maxWeight - totalVolume * weightPerVolume)

    function weightConversion(weight: number): string {
        if (weight > 1000) {
            return applyUnits(weight/1000, "t")
        }
        else {
            return `${weight.toFixed(2)}kg`
        }
    }

    function getInventoryVolume(inventory: InventoryType): number {
        return inventorySizes.get(gridSize).get(inventory) * inventoryMultiplier
    }

    function getThrusterPower(thruster: Thruster): number {
        return thrustValues.get(gridSize).get(thruster.type).get(thruster.size)
    }

    function addThruster() {
        thrusters.push({ type: newThruster.type, size: newThruster.size});
    }

    function addInventory() {
        inventories.push(newInventory);
    }

    function localized(key: string): string {
        let localizationObject = localization.get(key)

        if (typeof localizationObject === "undefined") {
            return `missing text: ${key}`
        }
        else {
            let localizedText = localizationObject.get(locale)
            if (typeof localizedText === "undefined") {
                return localizationObject.get("en-GB")
            }
            else {
                return localizedText
            }
        }
    }

    function applyUnits(value: number, unit: string) {
        for (const [power, modifier] of [...metricModifiers.entries()]) {
            if (value > power) {
                if (value / power >= 10000) {
                    let base = value / power;
                    let rest = base % 1000;
                    base = (base - rest) / 1000;
                    rest = Math.round((rest + Number.EPSILON) * 100) / 100
                    return `${base}${localized("separator")}${rest}${modifier}${unit}`
                }
                else {
                    let rounded = Math.round(((value / power) + Number.EPSILON) * 100) / 100
                    return `${rounded}${modifier}${unit}`
                }
            }
        }
        let rounded = Math.round(((value + Number.EPSILON) * 100) / 100)
        return `${rounded}${unit}`
    }

    onMount(() => {
        if (navigator) {
            locale = navigator.language;
        }

        if (localStorage.getItem("thrusters") !== null) {
            thrusters = JSON.parse(localStorage.getItem("thrusters"))
        }

        if (localStorage.getItem("inventories") !== null) {
            inventories = JSON.parse(localStorage.getItem("inventories"))
        }

        if (localStorage.getItem("gridSize") !== null) {
            gridSize = localStorage.getItem("gridSize")
        }

        if (localStorage.getItem("gravity") !== null) {
            gravity = localStorage.getItem("gravity")
        }

        if (localStorage.getItem("inventoryMultiplier") !== null) {
            inventoryMultiplier = localStorage.getItem("inventoryMultiplier")
        }

        if (localStorage.getItem("newThruster") !== null) {
            newThruster = JSON.parse(localStorage.getItem("newThruster"))
        }

        if (localStorage.getItem("newInventory") !== null) {
            newInventory = JSON.parse(localStorage.getItem("newInventory"))
        }

        mounted = true;
    })
</script>

<svelte:head>
    <title>{localized("title")}</title>
    <meta name="robots" content="noindex nofollow" />
</svelte:head>

<div class="gap-4 grid grid-cols-3 h-full">
    <Card.Root class="col-span-1">
        <Card.Header>
            <Card.Title>{localized("title")}</Card.Title>
        </Card.Header>
        <Card.Content class="flex flex-col gap-3">
            <Separator />
            <Label for="gravity">{localized("gravity")}</Label>
            <Input type="number" step="0.01" id="gravity" bind:value={gravity}/>
            <Separator />
            <Label for="gridSize">{localized("gridSize")}</Label>
            <div id="gridSize" class="flex">
                {#each Object.values(Grids) as size}
                    {#if gridSize === size}
                        <Button variant="primary">{localized(size)}</Button>
                    {:else}
                        <Button variant="secondary" onclick={() => gridSize = size}>{localized(size)}</Button>
                    {/if}
                {/each}
            </div>
            <Separator />
            <p>{localized("liftableVehcileWeight")}: {weightConversion(maxVehicleWeight)}</p>
            <p>{localized("liftableWeight")}: {weightConversion(maxWeight)}</p>
        </Card.Content>
    </Card.Root>
    <Card.Root class="col-span-1 flex flex-col flex-grow">
        <Card.Header>
            <Card.Title>{localized("thrusterSettings")}</Card.Title>
        </Card.Header>
        <Card.Content class="flex flex-col flex-grow gap-3">
            <Separator />
            <Card.Root>
                <Card.Content class="flex flex-col gap-3 pt-6">
                    <div class="flex gap-2">
                        {#each Object.values(ThrusterType) as thruster}
                            {#if newThruster.type === thruster}
                                <Button variant="primary">{localized(thruster)}</Button>
                            {:else}
                                <Button variant="secondary" onclick={() => newThruster.type = thruster}>{localized(thruster)}</Button>
                            {/if}
                        {/each}
                    </div>
                    <div class="flex gap-2">
                        {#each Object.values(ThrusterSize) as size}
                            {#if newThruster.size === size}
                                <Button variant="primary">{localized(size)}</Button>
                            {:else}
                                <Button variant="secondary" onclick={() => newThruster.size = size}>{localized(size)}</Button>
                            {/if}
                        {/each}
                    </div>
                    <Button variant="secondary" onclick={() => addThruster()}>{localized("addThruster")}</Button>
                </Card.Content>
            </Card.Root>
            <Card.Root class="flex flex-col h-0 flex-grow">
                <Card.Header>
                    <Card.Title>{localized("thrusters")} ({applyUnits(totalThrust, "N")})</Card.Title>
                </Card.Header>
                <Card.Content class="overflow-hidden">
                    <Separator />
                    <div class="max-h-full overflow-y-auto">
                        {#each thrusters as thruster, index}
                            <p class="p-1">
                                - {localized(thruster.size)} {localized(thruster.type)} {localized("thruster")}: {applyUnits(getThrusterPower(thruster), "N")}
                                <Button variant="destructive" onclick={() => thrusters.splice(index, 1)}>X</Button>
                            </p>
                        {/each}
                    </div>
                </Card.Content>
            </Card.Root>
        </Card.Content>
    </Card.Root>

    <Card.Root class="col-span-1 flex flex-col flex-grow">
        <Card.Header>
            <Card.Title>{localized("inventorySettings")}</Card.Title>
        </Card.Header>
        <Card.Content class="flex flex-col flex-grow gap-3">
            <Separator />
            <Label for="inventorySize">{localized("inventory")} {localized("multiplier")}</Label>
            <Input id="inventorySize" type="number" bind:value={inventoryMultiplier}/>
            <Card.Root>
                <Card.Content class="pt-6 flex flex-col gap-3">
                    <div class="flex gap-2 flex-wrap">
                        {#each Object.values(InventoryType) as inventory}
                            {#if newInventory === inventory}
                                <Button variant="primary">{localized(inventory)}</Button>
                            {:else}
                                <Button variant="secondary" onclick={() => newInventory = inventory}>{localized(inventory)}</Button>
                            {/if}
                        {/each}
                    </div>
                    <Button variant="secondary" onclick={() => addInventory()}>{localized("addInventory")}</Button>
                </Card.Content>
            </Card.Root>
            <Card.Root class="flex flex-col h-0 flex-grow">
                <Card.Header>
                    <Card.Title>{localized("inventories")} ({applyUnits(totalVolume, "l")})</Card.Title>
                </Card.Header>
                <Card.Content class="overflow-hidden">
                    <Separator />
                    <div class="max-h-full overflow-y-auto">
                        {#each inventories as inventory, index}
                            <p class="p-1">
                                - {localized(inventory)} {localized("volume")}: {applyUnits(getInventoryVolume(inventory), "l")}
                                <Button variant="destructive" onclick={() => inventories.splice(index, 1)}>X</Button>
                            </p>
                        {/each}
                    </div>
                </Card.Content>
            </Card.Root>
        </Card.Content>
    </Card.Root>
</div>