<script>
    export let station = "";
    export let title = "Loading...";
    import { onMount } from "svelte";
    import Loading from "$lib/navigation/loading.svelte";
    import OverlayIsland from "$lib/islands/overlay-island.svelte";
    import AlertBar from "$lib/ldb/common/nrcc/alert-bar.svelte";
    import Island from "$lib/islands/island.svelte";
    import { getApiUrl } from "$lib/scripts/upstream";
    import TimeBar from "$lib/navigation/TimeBar.svelte";
    import { IconBus, IconSailboat } from "@tabler/icons-svelte";
    import toast from "svelte-french-toast";

    let requestedStation;
    $: requestedStation = station;

    let jsonData = null;
    let services = [];
    let busServices = [];
    let ferryServices = [];
    let dataAge = null;
    let isLoading = true;
    let dataExists = false;
    let alerts = [];
    let serviceDetail;

    $: {
        if (jsonData === null && requestedStation) {
            fetchData();
        }

        if (jsonData?.GetStationBoardResult?.generatedAt) {
            dataAge = new Date(jsonData.GetStationBoardResult.generatedAt);
        }

        if (jsonData?.GetStationBoardResult?.trainServices?.service) {
            services = jsonData.GetStationBoardResult.trainServices.service;
        } else {
            services = [];
        }

        if (jsonData?.GetStationBoardResult?.busServices?.service) {
            busServices = jsonData.GetStationBoardResult.busServices.service;
        }

        if (jsonData?.GetStationBoardResult?.ferryServices?.service) {
            ferryServices = jsonData.GetStationBoardResult.ferryServices.service;
        }

        if (jsonData?.GetStationBoardResult?.locationName) {
            title = jsonData.GetStationBoardResult.locationName;
        } else {
            title = requestedStation.toUpperCase();
        }
    }

    async function fetchData() {
        dataExists = true;
        isLoading = true; // Set loading state
        try {
            console.log(`Requested Station: ${requestedStation}`);
            const data = await fetch(`${getApiUrl()}/api/v2/live/station/${requestedStation}/public`);
            jsonData = await data.json();
        } catch (error) {
            console.error("Error fetching data:", error);
            dataExists = false;
            title = "Not Found";
        } finally {
            isLoading = false; // Clear loading state
        }
        prepareNrcc();
    }

    function parseTime(string) {
        let output;
        let change;
        switch (string) {
            case "Delayed":
                output = "LATE";
                change = "changed";
                break;
            case "Cancelled":
                output = "CANC";
                change = "cancelled";
                break;
            case "On Time":
            case "On time":
                output = "RT";
                change = "";
                break;
            case "":
                output = "-";
                change = "";
                break;
            case undefined:
                output = "-";
                change = "";
                break;
            case "No report":
                output = "-";
                change = "";
                break;
            case "undefined":
                output = false;
                change = "";
                break;
            default:
                output = string;
                change = "changed";
        }
        return { data: output, changed: change };
    }

    async function loadService(sid) {
        for (const service of services) {
            if (service.serviceID == sid) {
                serviceDetail = service;
            }
        }
    }

    async function loadBusService(sid) {
        for (const service of busServices) {
            if (service.serviceID == sid) {
                serviceDetail = service;
            }
        }
    }

    async function closeService() {
        serviceDetail = null;
    }

    async function prepareNrcc() {
        if (jsonData?.GetStationBoardResult?.nrccMessages?.message) {
            const nrcc = jsonData.GetStationBoardResult.nrccMessages.message;
            if (Array.isArray(nrcc)) {
                alerts = nrcc;
                return;
            }
            alerts.push(nrcc);
            return;
        }
    }

    onMount(() => {
        toast("Register for more detailed departure boards")
        if (requestedStation && jsonData === null) {
            fetchData();
        }
    });
</script>

{#if alerts.length}
    <AlertBar {alerts} />
{/if}

<TimeBar updatedTime={dataAge} />

{#if isLoading}
    <Loading />
{:else if dataAge}
    {#if services.length}
        <table class="ldbTable">
            <tr>
                <th class="from">From</th>
                <th class="to">To</th>
                <th class="plat">Plat.</th>
                <th class="time">Sch Arr.</th>
                <th class="time">Exp Arr.</th>
                <th class="time">Sch Dep.</th>
                <th class="time">Exp Dep.</th>
            </tr>
            {#each services as service}
                <tr>
                    <td class="origdest from" on:click={loadService(service.serviceID)} on:keypress={loadService(service.serviceID)}>
                        {#if Array.isArray(service.origin?.location)}
                            {service.origin.location[0]["locationName"] + " & " + service.origin.location[1]["locationName"]}
                        {:else}
                            {service.origin?.location?.locationName || ""}
                        {/if}
                    </td>
                    <td class="origdest to" on:click={loadService(service.serviceID)} on:keypress={loadService(service.serviceID)}>
                        {#if Array.isArray(service.destination?.location)}
                            {service.destination.location[0]["locationName"] + " & " + service.destination.location[0]["locationName"]}
                        {:else}
                            {service.destination?.location?.locationName || ""}
                        {/if}
                    </td>
                    <td class="plat">{service.platform || "-"}</td>
                    <td class="time">{parseTime(service.sta).data}</td>
                    <td class="time {parseTime(service.eta).changed}">{parseTime(service.eta).data}</td>
                    <td class="time">{parseTime(service.std).data}</td>
                    <td class="time {parseTime(service.etd).changed}">{parseTime(service.etd).data}</td>
                </tr>

                <tr
                    ><td colspan="7">
                        <p class="service-detail">
                            A {service.operator || "Unknown"} service
                            {#if service["length"]}
                                with {service["length"] || "some"} coaches
                            {/if}
                        </p>
                        {#if service.delayReason}
                            <p class="service-detail">{service.delayReason}</p>
                        {/if}
                        {#if service.cancelReason}
                            <p class="service-detail">{service.cancelReason}</p>
                        {/if}
                    </td></tr
                >
            {/each}
        </table>
    {:else}
        <p class="table-head-text">No Scheduled Train Services</p>
    {/if}
    {#if busServices.length}
        <br />
        <IconBus /><br />
        <span class="table-head-text">Bus Services</span>
        <table class="ldbTable">
            <tr>
                <th class="from">From</th>
                <th class="to">To</th>
                <th class="time">Sch Arr.</th>
                <th class="time">Exp Arr.</th>
                <th class="time">Sch Dep.</th>
                <th class="time">Exp Dep.</th>
            </tr>
            {#each busServices as service}
                <tr>
                    <td class="origdest from" on:click={loadBusService(service.serviceID)} on:keypress={loadBusService(service.serviceID)}
                        >{service.origin?.location?.locationName || ""}</td
                    >
                    <td class="origdest to" on:click={loadBusService(service.serviceID)} on:keypress={loadBusService(service.serviceID)}
                        >{service.destination?.location?.locationName || ""}</td
                    >
                    <td class="time">{parseTime(service.sta).data}</td>
                    <td class="time {parseTime(service.eta).changed}">{parseTime(service.eta).data}</td>
                    <td class="time">{parseTime(service.std).data}</td>
                    <td class="time {parseTime(service.etd).changed}">{parseTime(service.etd).data}</td>
                </tr>

                <tr
                    ><td colspan="7">
                        <p class="service-detail">
                            A {service.operator || "Unknown"} service
                        </p>
                        {#if service.delayReason}
                            <p class="service-detail">{service.delayReason}</p>
                        {/if}
                        {#if service.cancelReason}
                            <p class="service-detail">{service.cancelReason}</p>
                        {/if}
                    </td></tr
                >
            {/each}
        </table>
    {/if}
    {#if ferryServices.length}
        <br />
        <IconSailboat /><br />
        <span class="table-head-text">Ferry Services</span>
        <table class="ldbTable">
            <tr>
                <th class="from">From</th>
                <th class="to">To</th>
                <th class="time">Sch Arr.</th>
                <th class="time">Exp Arr.</th>
                <th class="time">Sch Dep.</th>
                <th class="time">Exp Dep.</th>
            </tr>
            {#each ferryServices as service}
                <tr>
                    <td class="origdest from">{service.origin?.location?.locationName || ""}</td>
                    <td class="origdest to">{service.destination?.location?.locationName || ""}</td>
                    <td class="time">{parseTime(service.sta).data}</td>
                    <td class="time {parseTime(service.eta).changed}">{parseTime(service.eta).data}</td>
                    <td class="time">{parseTime(service.std).data}</td>
                    <td class="time {parseTime(service.etd).changed}">{parseTime(service.etd).data}</td>
                </tr>

                <tr
                    ><td colspan="7">
                        {#if service.delayReason}
                            <p class="service-detail">{service.delayReason}</p>
                        {/if}
                        {#if service.cancelReason}
                            <p class="service-detail">{service.cancelReason}</p>
                        {/if}
                    </td></tr
                >
            {/each}
        </table>
    {/if}
{:else}
    <Island>
        <p style="font-weight:600">Unable to load data</p>
    </Island>
{/if}

{#if serviceDetail}
    <OverlayIsland>
        <div id="detailBox">
            <h6>Service Detail</h6>
            <button type="button" id="closeService" on:click={closeService}>X</button>
            <table id="detailTable">
                <tr>
                    <th>Location</th>
                    <th>Sch</th>
                    <th>Exp</th>
                </tr>
                {#if serviceDetail?.previousCallingPoints?.callingPointList?.callingPoint}
                    {#if Array.isArray(serviceDetail?.previousCallingPoints?.callingPointList?.callingPoint)}
                        {#each serviceDetail.previousCallingPoints.callingPointList.callingPoint as prevPoint}
                            <tr>
                                <td>{prevPoint.locationName}</td>
                                <td>{prevPoint.st}</td>
                                <td class="time {parseTime(prevPoint.at || prevPoint.et).changed}">{parseTime(prevPoint.at || prevPoint.et).data}</td>
                            </tr>
                        {/each}
                    {:else}
                        <tr>
                            <td>{serviceDetail.previousCallingPoints.callingPointList.callingPoint.locationName}</td>
                            <td>{serviceDetail.previousCallingPoints.callingPointList.callingPoint.st}</td>
                            <td
                                class="time {parseTime(
                                    serviceDetail.previousCallingPoints.callingPointList.callingPoint.at || serviceDetail.previousCallingPoints.callingPointList.callingPoint.et
                                ).changed}"
                                >{parseTime(
                                    serviceDetail.previousCallingPoints.callingPointList.callingPoint.at || serviceDetail.previousCallingPoints.callingPointList.callingPoint.et
                                ).data}</td
                            >
                        </tr>
                    {/if}
                {/if}
                <tr class="thisStop">
                    <td>{title}</td>
                    <td>{serviceDetail.std || serviceDetail.sta}</td>
                    <td class="time {parseTime(serviceDetail.etd || serviceDetail.eta).changed}">{parseTime(serviceDetail.etd || serviceDetail.eta).data}</td>
                </tr>
                {#if serviceDetail?.subsequentCallingPoints?.callingPointList?.callingPoint}
                    {#if Array.isArray(serviceDetail?.subsequentCallingPoints?.callingPointList?.callingPoint)}
                        {#each serviceDetail.subsequentCallingPoints.callingPointList.callingPoint as nextPoint}
                            <tr>
                                <td>{nextPoint.locationName}</td>
                                <td>{nextPoint.st}</td>
                                <td class="time {parseTime(nextPoint.et).changed}">{parseTime(nextPoint.et).data}</td>
                            </tr>
                        {/each}
                    {:else}
                        <tr class="detailRow">
                            <td>{serviceDetail.subsequentCallingPoints.callingPointList.callingPoint.locationName}</td>
                            <td>{serviceDetail.subsequentCallingPoints.callingPointList.callingPoint.st}</td>
                            <td class="time {parseTime(serviceDetail.subsequentCallingPoints.callingPointList.callingPoint.et).changed}"
                                >{parseTime(serviceDetail.subsequentCallingPoints.callingPointList.callingPoint.et).data}</td
                            >
                        </tr>
                    {/if}
                {/if}
            </table>
        </div>
    </OverlayIsland>
{/if}

<style>
    .ldbTable {
        width: 100%;
        min-width: 300px;
        margin: auto;
        padding-right: 2px;
        padding-left: 0px;
        color: white;
        font-size: 13px;
    }
    .service-detail {
        color: cyan;
        text-align: left;
        font-size: 12px;
        padding: 0;
        margin: 0;
    }
    .transport-mode {
        width: 30px;
    }
    .table-head-text {
        color: white;
        font-size: 14px;
    }
    @media (min-width: 800px) {
        table {
            font-size: 15px;
            max-width: 850px;
        }
        .service-detail {
            font-size: 14px;
        }
        .transport-mode {
            width: 50px;
        }
    }
    @media (min-width: 1000px) {
        table {
            font-size: 17px;
        }
        .service-detail {
            font-size: 16px;
        }
        .table-head-text {
            font-size: 16px;
        }
    }
    @media (min-width: 1600px) {
        table {
            font-size: 19px;
        }
        .service-detail {
            font-size: 18px;
        }
    }
    .origdest {
        color: yellow;
    }
    .from {
        width: 25%;
        text-align: left;
    }
    .to {
        width: 25%;
        text-align: left;
    }
    .plat {
        width: 10%;
    }
    .time {
        width: 10%;
    }
    .changed {
        animation: pulse-change 1.5s linear infinite;
    }

    .cancelled {
        animation: pulse-cancel 1.5s linear infinite;
    }

    @keyframes pulse-change {
        50% {
            color: var(--main-warning-color);
        }
    }

    @keyframes pulse-cancel {
        50% {
            color: var(--main-alert-color);
        }
    }
    #detailBox {
        width: 100%;
    }
    h6 {
        position: absolute;
        top: -25px;
        left: 20px;
        font-size: 18px;
    }
    #closeService {
        position: absolute;
        top: 10px;
        right: 10px;
        border: none;
        border-radius: 60px;
        width: 35px;
        height: 35px;
        background-color: var(--main-bg-color);
        color: white;
        font-weight: 700;
        font-size: 16px;
    }
    #detailTable {
        margin-top: 40px;
        color: white;
        font-size: 15px;
    }
    .thisStop {
        color: yellow;
    }
</style>
