<script lang="ts">
    import { setReaction, clearReaction, type Reaction } from '$lib/api/reactions';
    import ThumbsUp from '@lucide/svelte/icons/thumbs-up';
    import ThumbsDown from '@lucide/svelte/icons/thumbs-down';

    // Tri-state like/dislike toggle for a manga. Optimistic with rollback,
    // mirroring the bookmark toggle. Rendered inside the detail page's
    // signed-in action row, so it isn't independently login-gated.
    let {
        mangaId,
        initial = null
    }: {
        mangaId: string;
        initial?: Reaction | null;
    } = $props();

    // svelte-ignore state_referenced_locally
    let current = $state<Reaction | null>(initial);
    let busy = $state(false);

    // The detail page reuses this component across manga -> manga navigation
    // (similar / recommendation cards), so `current` must re-seed when the
    // loader hands us a new manga's reaction. `mangaId` is referenced so the
    // effect also re-runs when navigating between two never-reacted mangas
    // (both `initial === null`).
    $effect(() => {
        mangaId;
        current = initial;
    });

    // Click the active reaction to clear it; click the other to switch.
    async function apply(next: Reaction) {
        if (busy) return;
        const prev = current;
        const target: Reaction | null = current === next ? null : next;
        current = target; // optimistic
        busy = true;
        try {
            if (target === null) await clearReaction(mangaId);
            else await setReaction(mangaId, target);
        } catch {
            current = prev; // rollback on failure
        } finally {
            busy = false;
        }
    }
</script>

<div class="reactions" role="group" aria-label="Rate this manga">
    <button
        type="button"
        class="reaction"
        class:active={current === 'like'}
        aria-pressed={current === 'like'}
        aria-label="Like"
        title="Like"
        disabled={busy}
        onclick={() => apply('like')}
        data-testid="reaction-like"
    >
        <ThumbsUp size={16} aria-hidden="true" />
    </button>
    <button
        type="button"
        class="reaction dislike"
        class:active={current === 'dislike'}
        aria-pressed={current === 'dislike'}
        aria-label="Dislike"
        title="Dislike"
        disabled={busy}
        onclick={() => apply('dislike')}
        data-testid="reaction-dislike"
    >
        <ThumbsDown size={16} aria-hidden="true" />
    </button>
</div>

<style>
    .reactions {
        display: inline-flex;
        gap: var(--space-1);
    }

    .reaction {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 40px;
        height: 40px;
        padding: 0;
        background: var(--surface);
        color: var(--text);
        border: 1px solid var(--border-strong);
        border-radius: var(--radius-md);
        cursor: pointer;
        transition:
            background var(--transition),
            border-color var(--transition),
            color var(--transition);
    }

    .reaction:hover:not(:disabled) {
        background: var(--surface-elevated);
    }

    .reaction:disabled {
        opacity: 0.6;
        cursor: default;
    }

    .reaction.active {
        color: var(--primary-contrast);
        background: var(--primary);
        border-color: var(--primary);
    }

    .reaction.dislike.active {
        color: var(--primary-contrast);
        background: var(--danger);
        border-color: var(--danger);
    }

    .reaction:focus-visible {
        outline: 2px solid var(--focus-ring);
        outline-offset: 2px;
    }
</style>
