<script lang="ts">
    import { page } from '$app/stores';
    import { goto } from '$app/navigation';
    import { clearReadProgress, type ReadProgressSummary } from '$lib/api/read_progress';
    import SegmentedControl from '$lib/components/SegmentedControl.svelte';
    import BookmarkList from '$lib/components/BookmarkList.svelte';
    import CollectionsGrid from '$lib/components/CollectionsGrid.svelte';
    import PageTagsList from '$lib/components/PageTagsList.svelte';
    import HistoryList from '$lib/components/HistoryList.svelte';
    import ListRowSkeleton from '$lib/components/ListRowSkeleton.svelte';
    import MangaGridSkeleton from '$lib/components/MangaGridSkeleton.svelte';

    let { data } = $props();

    function clearOne(p: ReadProgressSummary): Promise<void> {
        return clearReadProgress(p.manga_id);
    }

    type Tab = 'bookmarks' | 'collections' | 'page-tags' | 'history';
    const TABS: { label: string; value: Tab }[] = [
        { label: 'Bookmarks', value: 'bookmarks' },
        { label: 'Collections', value: 'collections' },
        { label: 'Page tags', value: 'page-tags' },
        { label: 'History', value: 'history' }
    ];

    // `?tab=` is the source of truth — refreshing or sharing a link
    // lands the user back on the same sub-tab. Bookmarks is the
    // default so visiting /library bare doesn't add noise to the URL.
    const activeTab: Tab = $derived.by(() => {
        const t = $page.url.searchParams.get('tab');
        if (t === 'collections' || t === 'history' || t === 'page-tags') return t;
        return 'bookmarks';
    });

    function setTab(t: Tab) {
        // goto with `replaceState: true` reliably updates the $page
        // store so the activeTab $derived re-fires. `replaceState`
        // alone (the shallow-routing helper) doesn't always trip the
        // url-tracked dependency, leaving the view stuck on the
        // previous sub-tab.
        const url = new URL($page.url);
        if (t === 'bookmarks') url.searchParams.delete('tab');
        else url.searchParams.set('tab', t);
        // Cast away the literal union — the SegmentedControl is
        // generic so its onchange receives `string`.
        void goto(url.toString(), {
            replaceState: true,
            keepFocus: true,
            noScroll: true
        });
    }
</script>

<svelte:head>
    <title>Mangalord | Library</title>
</svelte:head>

<h1 class="library-heading">Library</h1>

<div class="tab-row">
    <SegmentedControl
        ariaLabel="Library section"
        value={activeTab}
        options={TABS}
        onchange={setTab}
        testid="library-tabs"
    />
</div>

{#await data.result}
    {#if activeTab === 'collections'}
        <MangaGridSkeleton count={6} />
    {:else}
        <ListRowSkeleton />
    {/if}
{:then r}
    {#if !r.authenticated}
        <p class="hint" data-testid="library-signin">
            <a href="/login?next=/library">Sign in</a> to see your library.
        </p>
    {:else if r.error}
        <p class="error" role="alert" data-testid="library-error">
            Couldn't load library: {r.error}
        </p>
    {:else if activeTab === 'bookmarks'}
        {#if r.bookmarks.length === 0}
            <p class="hint" data-testid="library-bookmarks-empty">No bookmarks yet.</p>
        {:else}
            <BookmarkList bookmarks={r.bookmarks} testid="library-bookmark-list" />
        {/if}
    {:else if activeTab === 'collections'}
        {#if r.collections.length === 0}
            <p class="hint" data-testid="library-collections-empty">
                You don't have any collections yet. Open any manga and use
                <strong>Add to collection</strong> to start one.
            </p>
        {:else}
            <CollectionsGrid collections={r.collections} />
        {/if}
    {:else if activeTab === 'page-tags'}
        <PageTagsList initialItems={r.pageTags} initialDistinct={r.distinctPageTags} />
    {:else}
        <HistoryList entries={r.history} onClear={clearOne} testid="library-history" />
    {/if}
{/await}

<style>
    .library-heading {
        margin-bottom: var(--space-3);
    }

    .tab-row {
        margin-bottom: var(--space-4);
        display: flex;
    }

    .tab-row :global(.segmented) {
        width: 100%;
    }

    .tab-row :global(.seg) {
        flex: 1;
    }

    .hint {
        color: var(--text-muted);
    }

    .error {
        color: var(--danger);
    }
</style>
