<script lang="ts">
    import SpaceCard from "$lib/components/SpaceCard.svelte";
    import defaultImg from "$lib/assets/study_space.png";
    import crossUrl from "$lib/assets/cross.svg";
    import Navbar from "$lib/components/Navbar.svelte";
    import { allTags, volumeTags, wifiTags, powerOutletTags } from "$lib";

    const { data } = $props();
    const { studySpaces, supabase } = $derived(data);

    let selectedTags = $state<string[]>([]);
    let tagFilter = $state("");
    let openingFilter = $state("");
    let closingFilter = $state("");
    let tagFilterElem = $state<HTMLInputElement>();

    function categorySelected(category: string[]) {
        return category.some((tag) => selectedTags.includes(tag));
    }

    let filteredTags = $derived(
        allTags
            .filter((tag) => tag.toLowerCase().includes(tagFilter.toLowerCase()))
            .filter((tag) => !selectedTags.includes(tag))
            .filter((tag) => {
                if (selectedTags.includes(tag)) return false;

                if (categorySelected(volumeTags) && volumeTags.includes(tag)) return false;
                if (categorySelected(wifiTags) && wifiTags.includes(tag)) return false;
                if (categorySelected(powerOutletTags) && powerOutletTags.includes(tag))
                    return false;

                return true;
            })
    );

    // Convert "HH:MM" or "HH:MM:SS" to minutes since midnight
    function toMinutes(timeStr: string): number {
        const [h, m] = timeStr.slice(0, 5).split(":").map(Number);
        return h * 60 + m;
    }

    // Combine tag and time filtering
    let filteredStudySpaces = $derived(
        studySpaces
            // tag filtering
            .filter((space) => {
                if (selectedTags.length === 0) return true;
                const allTags = [
                    ...(space.tags || []),
                    space.volume,
                    space.wifi,
                    space.power
                ].filter(Boolean);
                return selectedTags.every((tag) => allTags.includes(tag));
            })
            // opening time filter
            .filter((space) => {
                if (!openingFilter) return true;
                const entry = space.study_space_hours?.find(
                    (h) => h.day_of_week === new Date().getDay()
                );
                if (!entry) return false;
                if (entry.is_24_7) return true;
                const openMin = toMinutes(entry.opens_at);
                let closeMin = toMinutes(entry.closes_at);
                // Treat midnight as end of day and handle overnight spans
                if (closeMin === 0) closeMin = 24 * 60;
                if (closeMin <= openMin) closeMin += 24 * 60;
                const filterMin = toMinutes(openingFilter);
                // Include spaces open at the filter time
                return filterMin >= openMin && filterMin < closeMin;
            })
            // closing time filter
            .filter((space) => {
                if (!closingFilter) return true;
                const entry = space.study_space_hours?.find(
                    (h) => h.day_of_week === new Date().getDay()
                );
                if (!entry) return false;
                if (entry.is_24_7) return true;
                const openMin = toMinutes(entry.opens_at);
                let closeMin = toMinutes(entry.closes_at);
                if (closeMin === 0) closeMin = 24 * 60;
                if (closeMin <= openMin) closeMin += 24 * 60;
                const filterMin =
                    toMinutes(closingFilter) === 0 ? 24 * 60 : toMinutes(closingFilter);
                // Include spaces still open at the filter time
                return filterMin > openMin && filterMin <= closeMin;
            })
    );

    let dropdownVisible = $state(false);

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

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

<Navbar>
    <a href="/space/new/edit">
        <img src={crossUrl} alt="new" class="new-space" />
    </a>
</Navbar>

<main>
    <a href="/space/reports" class="checkReports">Check Reports</a>
    <div class="time-filter-container">
        <label>
            Open from:
            <input type="time" bind:value={openingFilter} />
        </label>
        <label>
            Open until:
            <input type="time" bind:value={closingFilter} />
        </label>
    </div>
    <div class="tag-filter-container">
        <form>
            <div class="tagDisplay">
                {#each selectedTags 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") {
                            event.preventDefault();
                            const tag = filteredTags[0];
                            if (tag) addTag(tag)();
                        }
                    }}
                    placeholder="Search by 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>
        </form>
    </div>

    {#each filteredStudySpaces as studySpace (studySpace.id)}
        {@const imgUrl =
            studySpace.study_space_images.length > 0
                ? supabase.storage
                      .from("files_bucket")
                      .getPublicUrl(studySpace.study_space_images[0].image_path).data.publicUrl
                : defaultImg}
        <SpaceCard
            alt="Photo of {studySpace.description}"
            href="/space/{studySpace.id}"
            imgSrc={imgUrl}
            space={studySpace}
            hours={studySpace.study_space_hours}
        />
    {/each}
</main>

<style>
    main {
        display: grid;
        box-sizing: border-box;
        grid-template-columns: 1fr 1fr;
        gap: 1rem;
        padding: 1rem;
        max-width: 600px;
        width: 100%;
        margin: 0 auto;
    }

    .new-space {
        transform: rotate(45deg);
    }

    .tag-filter-container {
        grid-column: 1 / -1;
        display: flex;
        justify-content: center;
        margin-bottom: 0.5rem;
    }

    .time-filter-container {
        grid-column: 1 / -1;
        display: flex;
        gap: 1rem;
        justify-content: center;
        margin-bottom: 0.5rem;
    }
    .time-filter-container label {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        font-size: 1rem;
        color: #eaffeb;
    }
    .time-filter-container input[type="time"] {
        background: none;
        border: 2px solid #eaffeb;
        border-radius: 0.5rem;
        padding: 0.25rem 0.5rem;
        color: #eaffeb;
    }

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

    .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 {
        flex: 1 1 100%;
        min-width: 10rem;
        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;
    }
    .checkReports {
        grid-column: 1 / -1;
        display: block;
        text-align: center;
        color: #ffeaea;
        font-size: 1.2rem;
        text-decoration: none;
        padding: 0.5rem;
        background-color: #bd4949;
        border-radius: 0.5rem;
    }

    @media (max-width: 20rem) {
        main {
            grid-template-columns: 1fr;
        }
    }
</style>
