<script lang="ts">
    import { goto } from "$app/navigation";
    import Text from "$lib/components/inputs/Text.svelte";
    import Textarea from "$lib/components/inputs/Textarea.svelte";
    import Navbar from "$lib/components/Navbar.svelte";
    import crossUrl from "$lib/assets/cross.svg";
    import Button from "$lib/components/Button.svelte";
    import Images from "$lib/components/inputs/Images.svelte";
    import type { Table } from "$lib";
    import { availableStudySpaceTags, wifiTags, powerOutletTags, volumeTags } from "$lib";
    const { data } = $props();
    const { supabase } = $derived(data);

    let spaceImgs = $state<FileList>();
    let uploading = $state(false);
    let studySpaceData = $state<Omit<Table<"study_spaces">, "id" | "created_at" | "updated_at">>({
        description: "",
        building_location: "",
        location: "",
        tags: [],
        volume: "",
        power: "",
        wifi: ""
    });

    async function uploadStudySpace() {
        if (!spaceImgs || spaceImgs.length < 1) return alert("Please select an image file.");

        const { data: studySpaceInsert, error: studySpaceError } = await supabase
            .from("study_spaces")
            .insert(studySpaceData)
            .select()
            .single();
        if (studySpaceError)
            return alert(`Error uploading study space: ${studySpaceError.message}`);

        const imgUploads = await Promise.all(
            Array(spaceImgs.length)
                .keys()
                .map(async (i) => {
                    const imageFile = spaceImgs![i];
                    const resp = await supabase.storage
                        .from("files_bucket")
                        .upload(`public/${studySpaceInsert.id}-${imageFile.name}`, imageFile, {
                            contentType: imageFile.type
                        });
                    return resp;
                })
        );
        const imageError = imgUploads.find(({ error }) => error)?.error;
        if (imageError) return alert(`Error uploading image: ${imageError.message}`);

        const { error: imageInsertError } = await supabase
            .from("study_space_images")
            .insert(
                imgUploads.map(({ data }) => ({
                    study_space_id: studySpaceInsert.id,
                    image_path: data!.path
                }))
            )
            .select();
        if (imageInsertError) return alert(`Error creating image: ${imageInsertError.message}`);

        alert("Thank you for your contribution!");
        // Redirect to the new study space page
        await goto(`/space/${studySpaceInsert.id}`, {
            invalidate: ["db:study_spaces"]
        });
    }

    // Tag
    let tagFilter = $state("");
    let tagFilterElem = $state<HTMLInputElement>();
    let filteredTags = $derived(
        availableStudySpaceTags
            .filter((tag) => tag.toLowerCase().includes(tagFilter.toLowerCase()))
            .filter((tag) => !studySpaceData.tags.includes(tag))
    );
    let dropdownVisible = $state(false);

    function deleteTag(tagName: string) {
        return () => {
            studySpaceData.tags = studySpaceData.tags.filter((tag) => tag !== tagName);
        };
    }

    function addTag(tagName: string) {
        return () => {
            if (!studySpaceData.tags.includes(tagName)) {
                studySpaceData.tags.push(tagName);
            }
            tagFilter = "";
        };
    }
</script>

<Navbar>
    <a href="/">
        <img src={crossUrl} alt="close" />
    </a>
</Navbar>

<form
    onsubmit={async (event) => {
        event.preventDefault();
        uploading = true;
        await uploadStudySpace();
        uploading = false;
    }}
>
    <Images name="study-space-image" minHeight="16rem" bind:files={spaceImgs} required />

    <label for="location">Enter the name:</label>
    <Text
        name="location"
        bind:value={studySpaceData.location}
        placeholder="Room 123, Floor 1"
        required
    />

    <div class="compulsoryTags">
        <div class="compulsoryContainer">
            <label for="volume">Sound level:</label>
            <select bind:value={studySpaceData.volume} name="volume" class="compulsoryTagSelect">
                <option value="" disabled selected>How noisy is it?</option>
                {#each volumeTags as volumeTag (volumeTag)}
                    <option value={volumeTag}>{volumeTag}</option>
                {/each}
            </select>
        </div>
        <div class="compulsoryContainer">
            <label for="powerOutlets">Power outlets:</label>
            <select
                bind:value={studySpaceData.power}
                name="poweOutlets"
                class="compulsoryTagSelect"
            >
                <option value="" disabled selected>Power outlets?</option>
                {#each powerOutletTags as powerOutletTag (powerOutletTag)}
                    <option value={powerOutletTag}>{powerOutletTag}</option>
                {/each}
            </select>
        </div>
        <div class="compulsoryContainer">
            <label for="wifi">Wifi:</label>
            <select bind:value={studySpaceData.wifi} name="wifi" class="compulsoryTagSelect">
                <option value="" disabled selected>How's the wifi?</option>
                {#each wifiTags as wifiTag (wifiTag)}
                    <option value={wifiTag}>{wifiTag}</option>
                {/each}
            </select>
        </div>
    </div>

    <label for="tags">Additional tags:</label>
    <div class="tagDisplay">
        {#each studySpaceData.tags as tagName (tagName)}
            <button class="tag" onclick={deleteTag(tagName)} type="button">
                {tagName}
                <img src={crossUrl} alt="delete" /></button
            >
        {/each}
        <input
            type="text"
            name="tagInput"
            class="tagInput"
            bind:value={tagFilter}
            bind:this={tagFilterElem}
            onfocus={() => {
                dropdownVisible = true;
            }}
            onblur={() => {
                dropdownVisible = false;
            }}
            onkeypress={(event) => {
                if (event.key === "Enter") {
                    const tag = filteredTags[0];
                    if (tag) addTag(tag)();
                }
            }}
            placeholder="Add tags..."
        />
        {#if dropdownVisible}
            <div class="tagDropdown">
                {#each filteredTags as avaliableTag (avaliableTag)}
                    <button
                        class="avaliableTag"
                        onclick={addTag(avaliableTag)}
                        onmousedown={(e) => {
                            // Keep input focused
                            e.preventDefault();
                            e.stopPropagation();
                        }}
                        type="button"
                    >
                        {avaliableTag}
                    </button>
                {/each}
            </div>
        {/if}
    </div>

    <label for="description">Optional brief description:</label>
    <Textarea
        name="description"
        bind:value={studySpaceData.description}
        placeholder="A quiet room with a lovely view of the park."
        rows={2}
    />

    <label for="building-location">Add the building location:</label>
    <Text
        name="building-location"
        bind:value={studySpaceData.building_location}
        placeholder="Huxley Building, Imperial South Kensington Campus"
        required
    />

    <div class="submit">
        <Button
            type="submit"
            disabled={(spaceImgs?.length || 0) === 0 ||
                !studySpaceData.location ||
                !studySpaceData.wifi ||
                !studySpaceData.volume ||
                !studySpaceData.power ||
                !studySpaceData.building_location ||
                uploading}
        >
            Share this study space!
        </Button>
    </div>
</form>

<style>
    form {
        display: flex;
        flex-direction: column;
        padding: 1.5rem;
        gap: 0.5rem;
        max-width: 32rem;
        margin: 0 auto;
    }

    label {
        color: #ffffff;
        margin-top: 0.5rem;
    }
    .submit {
        position: sticky;
        display: flex;
        flex-direction: column;
        margin-top: 0.5rem;
        bottom: 0;
        margin-left: -0.5rem;
        width: calc(100% + 1rem);
    }
    .tagDisplay {
        display: flex;
        gap: 0.4rem;
        flex-wrap: wrap;
        align-items: left;
        justify-content: left;
        position: relative;
        width: 100%;
        height: auto;
        padding: 0.5rem;
        border-radius: 0.5rem;
        border: 2px solid #eaffeb;
        background: none;
        color: #eaffeb;
        font-size: 1rem;
    }
    .tagInput {
        width: 100%;
        height: 100%;
        background: none;
        color: #eaffeb;
        font-size: 1rem;
        border: none;
        outline: none;
    }
    ::placeholder {
        color: #859a90;
        opacity: 1;
    }
    .tag {
        display: flex;
        align-items: center;
        border-radius: 0.25rem;
        background-color: #2e4653;
        color: #eaffeb;
        font-size: 0.9rem;
        cursor: pointer;
        border-width: 0rem;
    }
    .tag img {
        width: 1rem;
        height: 1rem;
        margin-left: 0.2rem;
    }

    .tagDropdown {
        width: 100%;
        display: flex;
        gap: 0.4rem;
        flex-wrap: wrap;
        position: absolute;
        background-color: #2e4653;
        box-shadow: 1px 1px 0.5rem rgba(0, 0, 0, 0.5);
        border-radius: 0.5rem;
        overflow-y: auto;
        max-height: 10rem;
        top: 100%;
        left: 50%;
        transform: translateX(-50%);
    }

    .avaliableTag {
        width: 100%;
        text-align: left;
        background: none;
        border: none;
        color: #eaffeb;
        font-size: 0.9rem;
        margin: 0%;
        padding: 0 0.8rem 0.4rem;
    }
    .avaliableTag:first-child {
        padding-top: 0.6rem;
        background-color: hsl(201, 26%, 60%);
    }
    .avaliableTag:last-child {
        padding-bottom: 0.6rem;
    }

    .compulsoryTags {
        display: grid;
        gap: 0.4rem;
        border-radius: 0.5rem;
        background-color: none;
        width: 100%;
        font-size: 1rem;
        grid-template-columns: repeat(3, 1fr);
    }

    .compulsoryContainer {
        display: flex;
        flex-direction: column;
        align-items: left;
        justify-content: top;
        border-radius: 0.5rem;
        background-color: none;
    }

    .compulsoryTagSelect {
        width: 100%;
        height: 100%;
        padding: 0.5rem;
        border-radius: 0.5rem;
        border: 2px solid #eaffeb;
        background: none;
        color: #eaffeb;
        font-size: 0.9rem;
        text-align: left;
    }

    .compulsoryTagSelect option {
        background-color: #2e4653;
        color: #eaffeb;
    }
</style>
