<script lang="ts">
    import { onMount } from "svelte";

    let simulations: Array<{
        id: number;
        name: string;
        created_at: string;
        config: string;
    }> = $state([]);
    let error = $state("");

    let searchQuery = $state("");
    let filterDateFrom = $state("");
    let filterDateTo = $state("");
    let filterAltMin = $state("");
    let filterAltMax = $state("");
    let filterUavMin = $state("");
    let filterUavMax = $state("");
    let filterUgvMin = $state("");
    let filterUgvMax = $state("");
    let filterPattern = $state("any");

    let sortOrder = $state("newest");
    let currentPage = $state(1);
    let itemsPerPage = 10;

    function parseConfig(config: string) {
        if (!config)
            return {
                altitude: null,
                uavMin: null,
                uavMax: null,
                ugvMin: null,
                ugvMax: null,
            };
        let alt = config.match(/altitude:\s*([\d\.]+)/);
        let uavMin = config.match(/## UAV[\s\S]*?min_mph:\s*([\d\.]+)/);
        let uavMax = config.match(/## UAV[\s\S]*?max_mph:\s*([\d\.]+)/);
        let ugvMin = config.match(/## UGV[\s\S]*?min_mph:\s*([\d\.]+)/);
        let ugvMax = config.match(/## UGV[\s\S]*?max_mph:\s*([\d\.]+)/);
        let pattern = config.match(/(spiral|lawnmower|levy):/);
        return {
            altitude: alt ? parseFloat(alt[1]) : null,
            uavMin: uavMin ? parseFloat(uavMin[1]) : null,
            uavMax: uavMax ? parseFloat(uavMax[1]) : null,
            ugvMin: ugvMin ? parseFloat(ugvMin[1]) : null,
            ugvMax: ugvMax ? parseFloat(ugvMax[1]) : null,
            pattern: pattern ? pattern[1] : null,
        };
    }

    let filteredSimulations = $derived(
        simulations.filter((sim) => {
            let matchText = sim.id.toString().includes(searchQuery);
            if (!matchText) return false;

            let simDate = new Date(sim.created_at).getTime();
            if (filterDateFrom && simDate < new Date(filterDateFrom).getTime())
                return false;
            if (
                filterDateTo &&
                simDate > new Date(filterDateTo).getTime() + 86400000
            )
                return false;

            let p = parseConfig(sim.config);
            if (
                filterAltMin &&
                p.altitude !== null &&
                p.altitude < parseFloat(filterAltMin)
            )
                return false;
            if (
                filterAltMax &&
                p.altitude !== null &&
                p.altitude > parseFloat(filterAltMax)
            )
                return false;
            if (
                filterUavMin &&
                p.uavMin !== null &&
                p.uavMin < parseFloat(filterUavMin)
            )
                return false;
            if (
                filterUavMax &&
                p.uavMax !== null &&
                p.uavMax > parseFloat(filterUavMax)
            )
                return false;
            if (
                filterUgvMin &&
                p.ugvMin !== null &&
                p.ugvMin < parseFloat(filterUgvMin)
            )
                return false;
            if (
                filterUgvMax &&
                p.ugvMax !== null &&
                p.ugvMax > parseFloat(filterUgvMax)
            )
                return false;

            if (filterPattern !== "any" && p.pattern !== filterPattern)
                return false;

            return true;
        }),
    );

    let sortedSimulations = $derived(
        [...filteredSimulations].sort((a, b) => {
            if (sortOrder === "newest") {
                return (
                    new Date(b.created_at).getTime() -
                    new Date(a.created_at).getTime()
                );
            } else if (sortOrder === "oldest") {
                return (
                    new Date(a.created_at).getTime() -
                    new Date(b.created_at).getTime()
                );
            } else if (sortOrder === "fastest" || sortOrder === "slowest") {
                let pA = parseConfig(a.config);
                let pB = parseConfig(b.config);
                let speedA = (pA.uavMax || 0) + (pA.ugvMax || 0);
                let speedB = (pB.uavMax || 0) + (pB.ugvMax || 0);
                if (sortOrder === "fastest") {
                    return speedB - speedA;
                } else {
                    return speedA - speedB;
                }
            }
            return 0;
        }),
    );

    let totalPages = $derived(
        Math.max(1, Math.ceil(sortedSimulations.length / itemsPerPage)),
    );

    let paginatedSimulations = $derived(
        sortedSimulations.slice(
            (currentPage - 1) * itemsPerPage,
            currentPage * itemsPerPage,
        ),
    );

    function goToPage(page: number) {
        if (page >= 1 && page <= totalPages) {
            currentPage = page;
        }
    }

    $effect(() => {
        if (
            searchQuery ||
            sortOrder ||
            filterDateFrom ||
            filterDateTo ||
            filterAltMin ||
            filterAltMax ||
            filterUavMin ||
            filterUavMax ||
            filterUgvMin ||
            filterUgvMax ||
            filterPattern
        ) {
            currentPage = 1;
        }
    });

    onMount(async () => {
        try {
            const res = await fetch("/api/simulations");
            if (!res.ok) throw new Error("Failed to fetch simulations");
            simulations = await res.json();
        } catch (e: any) {
            error = e.message;
        }
    });
</script>

<h1>Sim-Link Simulation Results</h1>

{#if error}
    <p class="error">Error: {error}</p>
{/if}

<div class="page-layout">
    <aside class="sidebar">
        <details open class="filter-group">
            <summary>Search & Sort</summary>
            <div class="filter-content">
                <input
                    type="text"
                    placeholder="Search ID..."
                    bind:value={searchQuery}
                    class="input-field full-width"
                />
                <select bind:value={sortOrder} class="input-field full-width">
                    <option value="newest">Newest First</option>
                    <option value="oldest">Oldest First</option>
                    <option value="fastest">Fastest</option>
                    <option value="slowest">Slowest</option>
                </select>
            </div>
        </details>

        <details class="filter-group">
            <summary>Algorithm Pattern</summary>
            <div class="filter-content">
                <select
                    bind:value={filterPattern}
                    class="input-field full-width"
                >
                    <option value="any">Any</option>
                    <option value="spiral">Spiral</option>
                    <option value="lawnmower">Lawnmower</option>
                    <option value="levy">Levy</option>
                </select>
            </div>
        </details>

        <details class="filter-group">
            <summary>Date Range</summary>
            <div class="filter-content col">
                <label
                    >From <input
                        type="date"
                        bind:value={filterDateFrom}
                        class="input-field"
                    /></label
                >
                <label
                    >To <input
                        type="date"
                        bind:value={filterDateTo}
                        class="input-field"
                    /></label
                >
            </div>
        </details>

        <details class="filter-group">
            <summary>Flight Altitude</summary>
            <div class="filter-content col">
                <label
                    >Min (ft) <input
                        type="number"
                        step="0.1"
                        bind:value={filterAltMin}
                        class="input-field small-num"
                    /></label
                >
                <label
                    >Max (ft) <input
                        type="number"
                        step="0.1"
                        bind:value={filterAltMax}
                        class="input-field small-num"
                    /></label
                >
            </div>
        </details>

        <details class="filter-group">
            <summary>UAV Speed</summary>
            <div class="filter-content col">
                <label
                    >Min (mph) <input
                        type="number"
                        step="0.1"
                        bind:value={filterUavMin}
                        class="input-field small-num"
                    /></label
                >
                <label
                    >Max (mph) <input
                        type="number"
                        step="0.1"
                        bind:value={filterUavMax}
                        class="input-field small-num"
                    /></label
                >
            </div>
        </details>

        <details class="filter-group">
            <summary>UGV Speed</summary>
            <div class="filter-content col">
                <label
                    >Min (mph) <input
                        type="number"
                        step="0.1"
                        bind:value={filterUgvMin}
                        class="input-field small-num"
                    /></label
                >
                <label
                    >Max (mph) <input
                        type="number"
                        step="0.1"
                        bind:value={filterUgvMax}
                        class="input-field small-num"
                    /></label
                >
            </div>
        </details>
    </aside>

    <main class="table-content">
        <table>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Sim Name</th>
                    <th>Date Run</th>
                    <th>Link</th>
                </tr>
            </thead>
            <tbody>
                {#each paginatedSimulations as sim}
                    <tr>
                        <td>{sim.id}</td>
                        <td>{sim.name}</td>
                        <td>{sim.created_at}</td>
                        <td
                            ><a href={`/simulation/${sim.id}`}>View Details</a
                            ></td
                        >
                    </tr>
                {/each}
            </tbody>
        </table>

        <div class="pagination">
            <button
                onclick={() => goToPage(currentPage - 1)}
                disabled={currentPage === 1}
            >
                Previous
            </button>
            <span>Page {currentPage} of {totalPages}</span>
            <button
                onclick={() => goToPage(currentPage + 1)}
                disabled={currentPage === totalPages}
            >
                Next
            </button>
        </div>
    </main>
</div>

<style>
    :global(body) {
        font-family: "JetBrains Mono", Courier, monospace;
        background-color: #ffffff;
        color: #000000;
    }
    .page-layout {
        display: flex;
        gap: 30px;
        align-items: flex-start;
    }
    .sidebar {
        width: 300px;
        flex-shrink: 0;
    }
    .table-content {
        flex-grow: 1;
        overflow-x: auto;
    }
    table {
        border-collapse: collapse;
        width: 100%;
        margin-bottom: 20px;
    }
    th,
    td {
        border: 1px solid #000000;
        padding: 12px;
        text-align: left;
    }
    th {
        background-color: #e0e0e0;
    }
    tbody tr:nth-child(even) {
        background-color: #f9f9f9;
    }
    h1 {
        font-size: 28px;
        margin-bottom: 30px;
        padding-bottom: 10px;
        border-bottom: 2px solid #000;
    }
    a {
        color: #0000ff;
        text-decoration: underline;
    }
    a:visited {
        color: #800080;
    }
    .error {
        color: red;
        font-weight: bold;
        margin-bottom: 20px;
    }
    .filter-group {
        border: 1px solid #000;
        margin-bottom: 10px;
        background-color: #f9f9f9;
    }
    summary {
        font-weight: bold;
        padding: 10px;
        cursor: pointer;
        background-color: #e0e0e0;
        border-bottom: 1px solid #000;
    }
    details:not([open]) summary {
        border-bottom: none;
    }
    .filter-content {
        padding: 15px;
        display: flex;
        flex-direction: column;
        gap: 15px;
    }
    .filter-content.col {
        gap: 10px;
    }
    .full-width {
        width: 100%;
        box-sizing: border-box;
    }
    label {
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        font-size: 14px;
        font-weight: bold;
    }
    .input-field {
        padding: 5px;
        border: 1px solid #000;
        font-family: inherit;
    }
    .small-num {
        width: 70px;
    }
    .pagination {
        margin-top: 20px;
        display: flex;
        align-items: center;
        gap: 15px;
    }
    button {
        padding: 5px 10px;
        border: 1px solid #000;
        background-color: #e0e0e0;
        cursor: pointer;
        font-family: inherit;
    }
    button:disabled {
        background-color: #f0f0f0;
        color: #888;
        cursor: not-allowed;
    }
</style>
