/**
 * tui-walkthrough-system.test.ts — 시스템 토글 + 부팅 + 종료 검증
 *
 * - TUI 부팅 (alternate screen 진입)
 * - Home 화면 렌더링
 * - 커맨드 팔레트에서 시스템 명령 선택
 * - 모든 토글 명령: notifications, animations, file_context,
 *   paste_summary, diffwrap, terminal_title, session_directory_filter
 * - debug overlay, console toggle
 * - /restart, /exit, /quit, /q, /rs
 * - 전체 스냅샷 에러 재검사
 */

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, hasError } from "./tui-walkthrough-driver"
import path from "path"

void Log.init({ print: false })

describe("TUI walkthrough: system + boot + exit", () => {
	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-system-report.txt")
		await driver.kill()
		await disposeAllInstances()
		Flag.SAEEOL_EXPERIMENTAL_HTTPAPI = true
	})

	// ── 부팅 검증 ──

	test("boot: TUI enters alternate screen", async () => {
		driver.snapshot("boot")
		expect(driver.output).toMatch(/\x1b\[\?9001h|\x1b\[\?1004h/)
		expect(driver.errors()).toHaveLength(0)
	})

	test("home: renders content", async () => {
		const { plain } = driver.snapshot("home")
		expect(plain.length).toBeGreaterThan(0)
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 시스템 슬래시 명령 ──

	test("/restart → restart attempt", async () => {
		await driver.slash("restart")
		driver.snapshot("slash-restart")
		expect(driver.errors()).toHaveLength(0)
		// restart 후 재부팅 대기
		await driver.wait(6000)
	})

	test("/rs → restart alias", async () => {
		await driver.slash("rs")
		driver.snapshot("slash-rs")
		expect(driver.errors()).toHaveLength(0)
		await driver.wait(6000)
	})

	// ── 시스템 토글 (커맨드 팔레트로 진입) ──
	// 이들은 슬래시 명령이 아니라 커맨드 팔레트(ctrl+p)에서 검색으로 선택

	test("toggle: notifications via palette", async () => {
		// 커맨드 팔레트 열고 명령 검색
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("notifications")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("toggle-notifications")
		expect(driver.errors()).toHaveLength(0)
	})

	test("toggle: animations via palette", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("animations")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("toggle-animations")
		expect(driver.errors()).toHaveLength(0)
	})

	test("toggle: file context via palette", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("file context")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("toggle-file-context")
		expect(driver.errors()).toHaveLength(0)
	})

	test("toggle: paste summary via palette", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("paste summary")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("toggle-paste-summary")
		expect(driver.errors()).toHaveLength(0)
	})

	test("toggle: diffwrap via palette", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("diffwrap")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("toggle-diffwrap")
		expect(driver.errors()).toHaveLength(0)
	})

	test("toggle: session directory filter via palette", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("session directory filter")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("toggle-session-dir-filter")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 디버그/콘솔 ──

	test("debug overlay via palette", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("debug")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("debug-overlay")
		expect(driver.errors()).toHaveLength(0)
	})

	test("console toggle via palette", async () => {
		driver.write(Key.ctrlP)
		await driver.wait(1000)
		driver.write("console")
		await driver.wait(500)
		driver.write(Key.enter)
		await driver.wait(500)
		driver.snapshot("console-toggle")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── org 전환 (조건부) ──

	test("/org → org switch dialog", async () => {
		await driver.slash("org")
		driver.snapshot("slash-org")
		expect(driver.errors()).toHaveLength(0)
		await driver.dismiss()
	})

	test("/orgs → alias", async () => {
		await driver.slash("orgs")
		driver.snapshot("slash-orgs")
		expect(driver.errors()).toHaveLength(0)
		await driver.dismiss()
	})

	test("/switch-org → alias", async () => {
		await driver.slash("switch-org")
		driver.snapshot("slash-switch-org")
		expect(driver.errors()).toHaveLength(0)
		await driver.dismiss()
	})

	// ── 종료 ──

	test("/q → exit alias", async () => {
		await driver.slash("q")
		await driver.wait(2000)
		driver.snapshot("slash-q-exit")
		expect(driver.errors()).toHaveLength(0)
	})

	// ── 전체 스냅샷 에러 재검사 ──

	test("all snapshots: no errors in any screen", async () => {
		const allErrors: string[] = []
		for (const snap of driver.snapshots) {
			const snapErrors = hasError(snap.plain)
			if (snapErrors.length > 0) {
				allErrors.push(`[${snap.name}]: ${snapErrors.join("; ")}`)
			}
		}
		expect(allErrors).toHaveLength(0)
	})
})
