<script lang="ts">
    import settings from "$lib/state/settings";

    import { donate } from "$lib/env";
    import { device } from "$lib/device";
    import { t } from "$lib/i18n/translations";

    import DonateCardContainer from "$components/donate/DonateCardContainer.svelte";
    import DonationOption from "$components/donate/DonationOption.svelte";

    import IconCoin from "@tabler/icons-svelte/IconCoin.svelte";
    import IconCalendarRepeat from "@tabler/icons-svelte/IconCalendarRepeat.svelte";
    import IconCup from "@tabler/icons-svelte/IconCup.svelte";
    import IconPizza from "@tabler/icons-svelte/IconPizza.svelte";
    import IconToolsKitchen2 from "@tabler/icons-svelte/IconToolsKitchen2.svelte";
    import IconPaperBag from "@tabler/icons-svelte/IconPaperBag.svelte";
    import IconSoup from "@tabler/icons-svelte/IconSoup.svelte";
    import IconFridge from "@tabler/icons-svelte/IconFridge.svelte";
    import IconArmchair from "@tabler/icons-svelte/IconArmchair.svelte";
    import IconDeviceLaptop from "@tabler/icons-svelte/IconDeviceLaptop.svelte";
    import IconApple from "@tabler/icons-svelte/IconApple.svelte";
    import IconPhoto from "@tabler/icons-svelte/IconPhoto.svelte";
    import IconWorldWww from "@tabler/icons-svelte/IconWorldWww.svelte";
    import IconBath from "@tabler/icons-svelte/IconBath.svelte";

    import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte";
    import IconArrowRight from "@tabler/icons-svelte/IconArrowRight.svelte";

    let donateList: HTMLElement;

    let customInput: HTMLInputElement;
    let customInputValue: number | null;
    let customFocused = false;

    const PRESET_DONATION_AMOUNTS = {
        5: IconCup,
        10: IconPizza,
        15: IconSoup,
        30: IconToolsKitchen2,
        50: IconPaperBag,
        100: IconWorldWww,
        200: IconFridge,
        500: IconArmchair,
        1599: IconDeviceLaptop,
        4900: IconApple,
        7398: IconDeviceLaptop,
        8629: IconPhoto,
        9433: IconBath,
    };

    type Processor = "stripe" | "liberapay";
    let processor: Processor = "stripe";

    const donationMethods: Record<Processor, (_: number) => string> = {
        stripe: (amount: number) => {
            const url = new URL(donate.stripe);
            url.searchParams.set("__prefilled_amount", amount.toString());
            return url.toString();
        },
        liberapay: (amount: number) => {
            const url = new URL(donate.liberapay);
            url.searchParams.set("currency", "USD");
            url.searchParams.set("period", "monthly");
            url.searchParams.set("amount", (amount / 100).toString());
            return url.toString();
        },
    };

    const sendCustom = () => {
        if (!customInput.reportValidity()) {
            return;
        }

        const amount = Math.floor(Number(customInputValue) * 100);
        return window.open(donationMethods[processor](amount), "_blank");
    };

    const scrollBehavior = $settings.appearance.reduceMotion
        ? "instant"
        : "smooth";

    $: showLeftScroll = false;
    $: showRightScroll = true;

    const scroll = (direction: "left" | "right") => {
        const currentPos = donateList.scrollLeft;
        const maxPos = donateList.scrollWidth - donateList.getBoundingClientRect().width;
        const newPos = direction === "left" ? currentPos - 150 : currentPos + 150;

        donateList.scroll({
            left: newPos,
            behavior: scrollBehavior,
        });

        setTimeout(() => {
            showLeftScroll = newPos > 0;
            showRightScroll = newPos < maxPos && newPos !== maxPos;
        }, 150)
    };
</script>

<DonateCardContainer id="donation-box">
    <div id="donation-types" role="tablist" aria-orientation="horizontal">
        <button
            id="donation-type-once"
            class="donation-type"
            on:click={() => (processor = "stripe")}
            class:selected={processor === "stripe"}
            aria-selected={processor === "stripe"}
            role="tab"
        >
            <div class="donation-type-icon"><IconCoin /></div>
            <div class="donation-type-text">
                <div class="donate-card-title">{$t("donate.card.once")}</div>
                <div class="donate-card-subtitle">
                    {$t("donate.card.processor", { value: "stripe" })}
                </div>
            </div>
        </button>

        <button
            id="donation-type-recurring"
            class="donation-type"
            on:click={() => (processor = "liberapay")}
            class:selected={processor === "liberapay"}
            aria-selected={processor === "liberapay"}
            role="tab"
        >
            <div class="donation-type-icon"><IconCalendarRepeat /></div>
            <div class="donation-type-text">
                <div class="donate-card-title">{$t("donate.card.recurring")}</div>
                <div class="donate-card-subtitle">
                    {$t("donate.card.processor", { value: "liberapay" })}
                </div>
            </div>
        </button>
    </div>

    <div
        id="donation-options-container"
        aria-hidden="true"
        class:mask-both={!device.is.mobile && showLeftScroll && showRightScroll}
        class:mask-left={!device.is.mobile && showLeftScroll && !showRightScroll}
        class:mask-right={!device.is.mobile && showRightScroll && !showLeftScroll}
    >
        {#if !device.is.mobile}
            <div id="donation-options-scroll">
                <button
                    class="scroll-button left"
                    class:hidden={!showLeftScroll}
                    on:click={() => {
                        scroll("left");
                    }}
                >
                    <IconArrowLeft />
                </button>
                <button
                    class="scroll-button right"
                    class:hidden={!showRightScroll}
                    on:click={() => {
                        scroll("right");
                    }}
                >
                    <IconArrowRight />
                </button>
            </div>
        {/if}

        <div
            id="donation-options"
            bind:this={donateList}
            on:wheel={() => {
                const currentPos = donateList.scrollLeft;
                const maxPos = donateList.scrollWidth - donateList.getBoundingClientRect().width - 5;
                showLeftScroll = currentPos > 0;
                showRightScroll = currentPos < maxPos && currentPos !== maxPos;
            }}
        >
            {#each Object.entries(PRESET_DONATION_AMOUNTS) as [amount, component]}
                <DonationOption
                    price={+amount}
                    desc={$t(`donate.card.option.${amount}`)}
                    href={donationMethods[processor](+amount * 100)}
                >
                    <svelte:component this={component} />
                </DonationOption>
            {/each}
        </div>
    </div>

    <div id="donation-custom">
        <div id="input-container" class:focused={customFocused}>
            {#if customInputValue || customInput?.validity.badInput}
                <span id="input-dollar-sign">$</span>
            {/if}

            <input
                id="donation-custom-input"
                type="number"
                min="2"
                max="10000"
                step=".01"
                required
                placeholder={$t("donate.card.custom")}
                bind:this={customInput}
                bind:value={customInputValue}
                on:input={() => (customFocused = true)}
                on:focus={() => (customFocused = true)}
                on:blur={() => (customFocused = false)}
                on:keydown={(e) => e.key === "Enter" && sendCustom()}
            />
        </div>

        <button
            id="donation-custom-submit"
            on:click={sendCustom}
            aria-label={$t("donate.card.custom.submit")}
            type="submit"
        >
            <IconArrowRight />
        </button>
    </div>
</DonateCardContainer>

<style>
    :global(#donation-box) {
        min-width: 300px;
        padding: var(--donate-card-main-padding) 0;
    }

    #donation-types,
    #donation-options,
    #donation-custom {
        padding: 0 var(--donate-card-main-padding);
    }

    #donation-types {
        display: flex;
        flex-direction: row;
        gap: calc(var(--donate-card-main-padding) / 2);
        overflow: scroll;
    }

    .donation-type {
        width: 100%;
        overflow: hidden;
        gap: 2px;
    }

    .donation-type-icon {
        display: flex;
    }

    .donation-type-icon :global(svg) {
        width: 28px;
        height: 28px;
        stroke-width: 1.8px;
    }

    .donation-type-text {
        display: flex;
        flex-direction: column;
    }

    #donation-options {
        display: flex;
        overflow-x: scroll;
        gap: 6px;
        mask-image: linear-gradient(
            90deg,
            rgba(0, 0, 0, 0) 0%,
            rgba(0, 0, 0, 1) 3%,
            rgba(0, 0, 0, 1) 50%,
            rgba(0, 0, 0, 1) 97%,
            rgba(0, 0, 0, 0) 100%
        );
    }

    #donation-custom {
        display: flex;
        gap: 6px;
        overflow: scroll;
    }

    #input-container {
        padding: 0 18px;
        width: 100%;
        border-radius: 12px;
        color: var(--white);
        background-color: rgba(255, 255, 255, 0.1);
        display: flex;
        align-items: center;
        gap: 4px;
    }

    #input-dollar-sign {
        animation: grow-in 0.05s linear;
        display: block;
    }

    @keyframes grow-in {
        from {
            font-size: 0;
        }
        to {
            font-size: inherit;
        }
    }

    #input-container,
    #donation-custom-input {
        font-size: 13px;
    }

    #donation-custom-input {
        flex: 1;
        background-color: transparent;
        color: var(--white);
        border: none;
        padding-block: 0;
        padding-inline: 0;
        padding: 12px 0;
        appearance: textfield;
    }

    #donation-custom-input::placeholder {
        color: var(--white);
        opacity: 0.5;
    }

    #donation-custom-input:focus-visible {
        box-shadow: unset !important;
    }

    #input-container.focused {
        box-shadow: 0 0 0 2px var(--white) inset;
    }

    #donation-custom-submit {
        color: var(--white);
        background-color: rgba(255, 255, 255, 0.1);
        aspect-ratio: 1/1;
        padding: 0px 10px;
    }

    #donation-custom-submit :global(svg) {
        width: 24px;
        height: 24px;
    }

    #donation-custom-input::-webkit-outer-spin-button,
    #donation-custom-input::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }

    #donation-options-container {
        display: flex;
        flex-direction: column;
        gap: calc(var(--donate-card-main-padding) / 2);
        position: relative;
    }

    #donation-options-scroll {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
        position: absolute;
        pointer-events: none;
        width: 100%;
        height: 100%;
        z-index: 3;
        overflow: hidden;
        opacity: 0;
        transition: opacity 0.2s;
    }

    .scroll-button {
        pointer-events: all;
        color: white;
        padding: 0 16px;
        background-color: transparent;
        height: 100%;
        transition: opacity 0.2s;
    }

    #donation-options-container:hover #donation-options-scroll {
        opacity: 1;
    }

    .scroll-button.hidden {
        opacity: 0;
        visibility: hidden;
    }

    #donation-options-container.mask-both:hover #donation-options {
        mask-image: linear-gradient(
            90deg,
            rgba(0, 0, 0, 0) 0%,
            rgba(0, 0, 0, 1) 20%,
            rgba(0, 0, 0, 1) 50%,
            rgba(0, 0, 0, 1) 80%,
            rgba(0, 0, 0, 0) 100%
        );
    }

    #donation-options-container.mask-left:hover #donation-options {
        mask-image: linear-gradient(
            90deg,
            rgba(0, 0, 0, 0) 0%,
            rgba(0, 0, 0, 1) 20%,
            rgba(0, 0, 0, 1) 50%,
            rgba(0, 0, 0, 1) 97%,
            rgba(0, 0, 0, 0) 100%
        );
    }

    #donation-options-container.mask-right:hover #donation-options {
        mask-image: linear-gradient(
            90deg,
            rgba(0, 0, 0, 0) 0%,
            rgba(0, 0, 0, 1) 3%,
            rgba(0, 0, 0, 1) 50%,
            rgba(0, 0, 0, 1) 80%,
            rgba(0, 0, 0, 0) 100%
        );
    }

    @media screen and (max-width: 550px) {
        :global(#donation-box) {
            --donate-card-main-padding: 14px;
            min-width: unset;
        }

        :global(#donation-box .donate-card-title) {
            font-size: 14px;
        }

        :global(#donation-box .donate-card-subtitle) {
            font-size: 12px;
        }

        .donation-type-icon :global(svg) {
            width: 26px;
            height: 26px;
        }
    }
</style>
