<!--
PlaybackControls — rewind / step-back / play-pause / step-forward
plus a single cycling speed button (1x → 2x → 4x → 6x → 1x) and a
"log" toggle that the orchestrator uses to collapse the always-on
text protocol when the user wants more space for the scene. Owns no
state of its own; binds `playing`, `frameIndex`, `speed`, and
`logOpen` from the orchestrator. Disables step/rewind when there's
nowhere to go and step-forward when the timeline is at its end.
-->
<script lang="ts">
	import { i18n } from "$lib/i18n/index.svelte";

	export type PlaybackSpeed = 1 | 2 | 4 | 6;

	const SPEED_CYCLE: PlaybackSpeed[] = [1, 2, 4, 6];

	let {
		playing = $bindable(),
		frameIndex = $bindable(),
		speed = $bindable(),
		logOpen = $bindable(),
		frameCount,
	}: {
		playing: boolean;
		frameIndex: number;
		speed: PlaybackSpeed;
		logOpen: boolean;
		frameCount: number;
	} = $props();

	function rewind() {
		playing = false;
		frameIndex = 0;
	}
	function stepBack() {
		playing = false;
		if (frameIndex > 0) frameIndex = frameIndex - 1;
	}
	function togglePlay() {
		if (frameIndex >= frameCount - 1) {
			frameIndex = 0;
		}
		playing = !playing;
	}
	function stepForward() {
		playing = false;
		if (frameIndex < frameCount - 1) frameIndex = frameIndex + 1;
	}
	function cycleSpeed() {
		const idx = SPEED_CYCLE.indexOf(speed);
		const next = SPEED_CYCLE[(idx + 1) % SPEED_CYCLE.length];
		speed = next;
	}
	function toggleLog() {
		logOpen = !logOpen;
	}

	const speedLabel = $derived(`${speed}x`);
</script>

<div class="controls" data-testid="battle-controls">
	<button
		type="button"
		onclick={rewind}
		disabled={frameIndex === 0}
		aria-label={i18n.t("game.battle.controls.rewind")}
		data-testid="battle-control-rewind"
	>⏮</button>
	<button
		type="button"
		onclick={stepBack}
		disabled={frameIndex === 0}
		aria-label={i18n.t("game.battle.controls.step_backward")}
		data-testid="battle-control-step-back"
	>◀︎◀︎</button>
	<button
		type="button"
		onclick={togglePlay}
		aria-label={playing
			? i18n.t("game.battle.controls.pause")
			: i18n.t("game.battle.controls.play")}
		data-testid="battle-control-play"
		data-playing={playing ? "true" : "false"}
	>{playing ? "⏸" : "▶︎"}</button>
	<button
		type="button"
		onclick={stepForward}
		disabled={frameIndex >= frameCount - 1}
		aria-label={i18n.t("game.battle.controls.step_forward")}
		data-testid="battle-control-step-forward"
	>▶︎▶︎</button>

	<div class="spacer" aria-hidden="true"></div>

	<button
		type="button"
		class="speed-btn"
		onclick={cycleSpeed}
		title={i18n.t("game.battle.controls.speed_label")}
		aria-label={i18n.t("game.battle.controls.speed_label")}
		data-testid="battle-control-speed"
		data-speed={speed}
	>{speedLabel}</button>

	<button
		type="button"
		class="log-toggle"
		class:active={logOpen}
		onclick={toggleLog}
		aria-pressed={logOpen}
		aria-label={i18n.t("game.battle.controls.log_toggle")}
		data-testid="battle-control-log-toggle"
	>{i18n.t("game.battle.controls.log_toggle")} {logOpen ? "▲" : "▼"}</button>
</div>

<style>
	.controls {
		display: flex;
		align-items: center;
		gap: 0.4rem;
		padding: 0.5rem 0.75rem;
		background: var(--color-surface);
		border: 1px solid var(--color-border-subtle);
		border-radius: 4px;
	}
	.spacer {
		flex: 1 1 auto;
	}
	button {
		appearance: none;
		background: var(--color-surface-raised);
		color: var(--color-text);
		border: 1px solid var(--color-border);
		padding: 0.35rem 0.7rem;
		border-radius: 3px;
		cursor: pointer;
		font-size: 0.9rem;
		font-family: inherit;
		min-width: 2.5rem;
	}
	button:hover:not(:disabled) {
		background: var(--color-surface-hover);
	}
	button:disabled {
		opacity: 0.4;
		cursor: not-allowed;
	}
	.speed-btn {
		min-width: 3rem;
		font-variant-numeric: tabular-nums;
	}
	.log-toggle.active {
		background: var(--color-surface-hover);
	}
</style>
