/**
 * tui-walkthrough-scroll.test.ts — 스크롤/네비게이션 키 전체 검증
 *
 * - page up/down
 * - ctrl+page up/down (half page)
 * - ctrl+up/down (line)
 * - ctrl+g / home (first message)
 * - ctrl+alt+g / end (last message)
 * - tab / shift+tab (agent cycle)
 * - f2 / shift+f2 (model cycle)
 * - ctrl+p (command palette)
 * - ctrl+t (variant cycle)
 * - escape (interrupt)
 */

import { describe, expect, test, beforeAll, afterAll } from "bun:test"
import { tmpdir, disposeAllInstances } from "../fixture/fixture"
import * as Log from "@saeeol/core/util/log"
import { Flag } from "@saeeol/core/flag/flag"
import { TuiDriver, Key } from "./tui-walkthrough-driver"

void Log.init({ print: false })

describe("TUI walkthrough: scroll & navigation", () => {
	let driver: TuiDriver
	let tmp: Awaited<ReturnType<typeof tmpdir>>

	beforeAll(async () => {
		tmp = await tmpdir({ git: true, config: {} })
		Flag.SAEEOL_EXPERIMENTAL_HTTPAPI = false
		driver = new TuiDriver(tmp.path)
		await driver.wait(6000)
	})

	afterAll(async () => {
		await driver.saveReport(".tui-scroll-report.txt")
		await driver.kill()
		await disposeAllInstances()
		Flag.SAEEOL_EXPERIMENTAL_HTTPAPI = true
	})

	// ── 페이지 스크롤 ──

	test("page up", async () => {
		driver.write(Key.pageUp)
		await driver.wait(300)
		driver.snapshot("scroll-page-up")
		expect(driver.errors()).toHaveLength(0)
	})

	test("page down", async () => {
		driver.write(Key.pageDown)
		await driver.wait(300)
		driver.snapshot("scroll-page-down")
		expect(driver.errors()).toHaveLength(0)
	})

	test("ctrl+page up (half page)", async () => {
		driver.write(Key.ctrlPageUp)
		await driver.wait(300)
		driver.snapshot("scroll-ctrl-page-up")
		expect(driver.errors()).toHaveLength(0)
	})

	test("ctrl+page down (half page)", async () => {
		driver.write(Key.ctrlPageDown)
		await driver.wait(300)
		driver.snapshot("scroll-ctrl-page-down")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 라인 스크롤 ──

	test("ctrl+up (line up)", async () => {
		driver.write(Key.ctrlUp)
		await driver.wait(300)
		driver.snapshot("scroll-ctrl-up")
		expect(driver.errors()).toHaveLength(0)
	})

	test("ctrl+down (line down)", async () => {
		driver.write(Key.ctrlDown)
		await driver.wait(300)
		driver.snapshot("scroll-ctrl-down")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 첫/마지막 메시지 ──

	test("ctrl+g (first message)", async () => {
		driver.write(Key.ctrlG)
		await driver.wait(300)
		driver.snapshot("scroll-ctrl-g-first")
		expect(driver.errors()).toHaveLength(0)
	})

	test("home (first message)", async () => {
		driver.write(Key.home)
		await driver.wait(300)
		driver.snapshot("scroll-home")
		expect(driver.errors()).toHaveLength(0)
	})

	test("end (last message)", async () => {
		driver.write(Key.end)
		await driver.wait(300)
		driver.snapshot("scroll-end")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 에이전트/모델 사이클 ──

	test("tab (next agent)", async () => {
		driver.write(Key.tab)
		await driver.wait(500)
		driver.snapshot("nav-tab-agent-next")
		expect(driver.errors()).toHaveLength(0)
	})

	test("shift+tab (prev agent)", async () => {
		driver.write(Key.shiftTab)
		await driver.wait(500)
		driver.snapshot("nav-shift-tab-agent-prev")
		expect(driver.errors()).toHaveLength(0)
	})

	test("f2 (next model)", async () => {
		driver.write(Key.f2)
		await driver.wait(500)
		driver.snapshot("nav-f2-model-next")
		expect(driver.errors()).toHaveLength(0)
	})

	test("shift+f2 (prev model)", async () => {
		driver.write(Key.shiftF2)
		await driver.wait(500)
		driver.snapshot("nav-shift-f2-model-prev")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 커맨드 팔레트 ──

	test("ctrl+p (command palette)", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.snapshot("nav-ctrl-p-palette")
		expect(driver.errors()).toHaveLength(0)
		await driver.dismiss()
	})

	// ── variant 사이클 ──

	test("ctrl+t (variant cycle)", async () => {
		driver.write(Key.ctrlT)
		await driver.wait(500)
		driver.snapshot("nav-ctrl-t-variant")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 인터럽트 ──

	test("escape (interrupt)", async () => {
		driver.write(Key.esc)
		await driver.wait(500)
		driver.snapshot("nav-escape-interrupt")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── ctrl+d (종료 시도) ──

	test("ctrl+d (exit attempt)", async () => {
		driver.write(Key.ctrlD)
		await driver.wait(1000)
		driver.snapshot("nav-ctrl-d-exit")
		expect(driver.errors()).toHaveLength(0)
	})
})
