<svelte:options runes={true} />

<script lang="ts">
    import * as Card from "$lib/components/ui/card";
    import {Button} from "$lib/components/ui/button";
    import {
        applyUnits,
        getFromLocalStorage,
        Localization, weightConversion
    } 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 * as DropdownMenu from "$lib/components/ui/dropdown-menu";
    import {onMount} from "svelte";
    import {CargoMaterial} from "$lib/materials";
    import ThrusterList from "$lib/components/ThrusterList.svelte";
    import {Ship} from "$lib/ship.svelte";
    import {Grid} from "$lib/grid";
    import NewThruster from "$lib/components/NewThruster.svelte";
    import NewInventory from "$lib/components/NewInventory.svelte";
    import {Inventory} from "$lib/containers.svelte";
    import InventoryList from "$lib/components/InventoryList.svelte";

    const STORAGE_VERSION = "2";
    let i18n = $state(new Localization("en-GB"));
    let mounted = $state(false);

    let ship = $state(new Ship(Grid.Small));
    $effect(() => {
        ship.thrusters;
        if (mounted) {
            localStorage.setItem("ship", JSON.stringify(ship.save()));
        }
    })

    let inventoryMultiplier: number = $state(3);
    $effect(() => {
        if (mounted) {
            localStorage.setItem("inventoryMultiplier", inventoryMultiplier);
        }
    })

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

    let material: CargoMaterial = $state(CargoMaterial.Ore);
    $effect(() => {
        if (mounted) {
            localStorage.setItem("density", material.save());
        }
    })

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

    let maxWeight: number = $derived(ship.getTotalMaxThrust() / (gravity * 9.81))

    let maxVehicleWeight: number = $derived(maxWeight - ship.getTotalVolume(inventoryMultiplier) * material.density)

    function addInventory(newInventory: Inventory) {
        ship.addInventory(newInventory);
    }

    function removeInventory(index: number) {
        ship.removeInventory(index);
    }

    function addThruster(newThruster: Thruster) {
        ship.addThruster(newThruster);
    }

    function removeThruster(index: number) {
        ship.removeThruster(index);
    }

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

        let ret = getFromLocalStorage("version");
        if (ret.result) {
            if (ret.value !== STORAGE_VERSION) {
                localStorage.clear();
                localStorage.setItem("version", STORAGE_VERSION);
            }
        }
        else {
            localStorage.clear();
            localStorage.setItem("version", STORAGE_VERSION);
        }

        ret = getFromLocalStorage("ship");
        if (ret.result) {
            ship.load(JSON.parse(ret.value));
        }

        ret = getFromLocalStorage("gravity");
        if (ret.result) {
            gravity = ret.value;
        }

        ret = getFromLocalStorage("density");
        if (ret.result) {
            let parsed = ret.value;
            Object.values(CargoMaterial).forEach((cargoMaterial) => {
                if (cargoMaterial.name === parsed) {
                    material = cargoMaterial
                }
            })
        }

        ret = getFromLocalStorage("atmosphericDensity");
        if (ret.result) {
            atmosphericDensity = ret.value;
        }

        ret = getFromLocalStorage("inventoryMultiplier");
        if (ret.result) {
            inventoryMultiplier = ret.value;
        }

        mounted = true;
    })
</script>

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

<div class="gap-4 flex flex-row flex-wrap h-full">
    <Card.Root class="flex-1">
        <Card.Header>
            <Card.Title>{i18n.localize("title")}</Card.Title>
        </Card.Header>
        <Card.Content class="flex flex-col gap-3">
            <Separator />
            <Card.Root>
                <Card.Header>
                    <Card.Title>{i18n.localize("settings")}</Card.Title>
                </Card.Header>
                <Card.Content class="flex flex-col gap-3">
                    <Separator />
                    <Label for="grid">{i18n.localize("gridSize")}</Label>
                    <div id="grid" class="flex gap-2">
                        {#each Object.values(Grid) as size}
                            {#if ship.grid === size}
                                <Button class="bg-primary">{i18n.localize(size)}</Button>
                            {:else}
                                <Button variant="secondary" onclick={() => ship.grid = size}>{i18n.localize(size)}</Button>
                            {/if}
                        {/each}
                    </div>
                    <Label for="gravity">{i18n.localize("gravity")}</Label>
                    <Input type="number" step="0.01" id="gravity" bind:value={gravity}/>
                    <Label for="density">{i18n.localize("density")}</Label>
                    <div id="density" class="flex gap-2">
                        {#each Object.values(CargoMaterial) as value}
                            {#if material === value}
                                <Button class="bg-primary">{i18n.localize(value.name)}</Button>
                            {:else}
                                <Button variant="secondary" onclick={() => material = value}>{i18n.localize(value.name)}</Button>
                            {/if}
                        {/each}
                    </div>
                    <Label for="atmosDensity">{i18n.localize("atmosDensity")}</Label>
                    <Input type="number" step="0.01" id="atmosDensity" bind:value={atmosphericDensity}/>
                </Card.Content>
            </Card.Root>
            <Card.Root>
                <Card.Header>
                    <Card.Title>{i18n.localize("results")}</Card.Title>
                </Card.Header>
                <Card.Content class="flex flex-col gap-3">
                    <Separator />
                    <div class="flex gap-2">
                        <p>{i18n.localize("liftableVehcileWeight")}:</p>
                        {#if maxVehicleWeight < 0}
                            <p class="text-destructive">{weightConversion(i18n, maxVehicleWeight)}</p>
                        {:else}
                            <p>{weightConversion(i18n, maxVehicleWeight)}</p>
                        {/if}
                    </div>
                    <p>{i18n.localize("liftableWeight")}: {weightConversion(i18n, maxWeight)}</p>
                    <Separator />
                    <p>{i18n.localize("fuels")}:
                        {ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") }
                    </p>
                </Card.Content>
            </Card.Root>
        </Card.Content>
    </Card.Root>
    <Card.Root class="flex-1 flex flex-col flex-grow">
        <Card.Header>
            <Card.Title>{i18n.localize("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">
                    <NewThruster i18n={i18n} onAddThruster={addThruster} />
                </Card.Content>
            </Card.Root>
            <Card.Root class="flex flex-col h-60 flex-grow">
                <Card.Header>
                    <Card.Title>{i18n.localize("thrusters")} ({applyUnits(i18n, ship.getTotalThrust(atmosphericDensity), "N")})</Card.Title>
                </Card.Header>
                <Card.Content class="flex flex-col gap-3 overflow-hidden">
                    <Separator />
                    <ThrusterList i18n={i18n} thrusters={ship.thrusters} onRemoveThruster={removeThruster} grid={ship.grid} atmosphere={atmosphericDensity}/>
                </Card.Content>
            </Card.Root>
        </Card.Content>
    </Card.Root>

    <Card.Root class="flex-1 flex flex-col flex-grow">
        <Card.Header>
            <Card.Title>{i18n.localize("inventorySettings")}</Card.Title>
        </Card.Header>
        <Card.Content class="flex flex-col flex-grow gap-3">
            <Separator />
            <Label for="inventorySize">{i18n.localize("inventory")} {i18n.localize("multiplier")}</Label>
            <Input id="inventorySize" type="number" bind:value={inventoryMultiplier}/>
            <Card.Root>
                <Card.Content class="pt-6 flex flex-col gap-3">
                    <NewInventory i18n={i18n} grid={ship.grid} onAddInventory={addInventory} />
                </Card.Content>
            </Card.Root>
            <Card.Root class="flex flex-col h-60 flex-grow">
                <Card.Header>
                    <Card.Title>{i18n.localize("inventories")} ({applyUnits(i18n, ship.getTotalVolume(inventoryMultiplier), "l")})</Card.Title>
                </Card.Header>
                <Card.Content class="flex flex-col gap-3 overflow-hidden">
                    <Separator />
                    <InventoryList i18n={i18n} inventories={ship.inventories} onRemoveInventory={removeInventory} grid={ship.grid} multiplier={inventoryMultiplier} />
                </Card.Content>
            </Card.Root>
        </Card.Content>
    </Card.Root>
</div>