from __future__ import annotations

import argparse
import sys
from pathlib import Path

THIS_FILE = Path(__file__).resolve()
PYTHON_ROOT = THIS_FILE.parent.parent
if str(PYTHON_ROOT) not in sys.path:
    sys.path.insert(0, str(PYTHON_ROOT))

from interactive.interactive_config import (
    load_interactive_profile,
    validate_normalize_mode,
    validate_output_mode,
)
from interactive.interactive_keyboard import read_keypress
from interactive.interactive_profiles import list_builtin_profiles
from interactive.interactive_renderer import render_event_lines, render_startup_panel
from interactive.interactive_session import InteractiveSession


def build_argument_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="grownet interactive runner",
        description="Live keyboard-driven GrowNet probing mode (Python-first).",
    )
    parser.add_argument("--lang", default="python")
    parser.add_argument("--interactive", action="store_true")
    parser.add_argument("--profile", default="single_scalar", choices=list_builtin_profiles())
    parser.add_argument("--config")
    parser.add_argument("--normalize-inputs", choices=["normalized", "raw"])
    parser.add_argument("--interactive-output", choices=["compact", "verbose", "jsonl"])
    parser.add_argument("--interactive-trace", choices=["on", "off"])
    return parser


def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    parser = build_argument_parser()
    return parser.parse_args(list(sys.argv[1:] if argv is None else argv))


def build_session_from_args(args: argparse.Namespace) -> InteractiveSession:
    profile = load_interactive_profile(args.profile, args.config)
    normalize_inputs = (
        validate_normalize_mode(args.normalize_inputs)
        if args.normalize_inputs is not None
        else profile.default_normalize_inputs
    )
    output_mode = (
        validate_output_mode(args.interactive_output)
        if args.interactive_output is not None
        else profile.default_output
    )
    trace_enabled = profile.default_trace
    if args.interactive_trace is not None:
        trace_enabled = str(args.interactive_trace).strip().lower() == "on"
    return InteractiveSession(
        profile=profile,
        normalize_inputs=normalize_inputs,
        output_mode=output_mode,
        trace_enabled=trace_enabled,
    )


def main(argv: list[str] | None = None, key_reader=read_keypress, output_writer=None) -> int:
    args = parse_args(argv)
    selected_lang = str(args.lang or "python").strip().lower()
    if selected_lang != "python":
        print(
            f"GrowNet interactive runner: --lang {selected_lang} is not implemented in this repository.",
            file=sys.stderr,
        )
        return 2

    if not bool(args.interactive):
        print("GrowNet interactive runner requires --interactive.", file=sys.stderr)
        return 2

    session = build_session_from_args(args)
    writer = output_writer if output_writer is not None else sys.stdout
    _write_block(writer, render_startup_panel(session))

    try:
        while True:
            raw_key = key_reader()
            if not raw_key:
                continue
            event = session.handle_key(raw_key)
            rendered_lines = render_event_lines(session, event)
            for rendered_line in rendered_lines:
                _write_block(writer, rendered_line)
            if event.should_quit:
                break
    except KeyboardInterrupt:
        _write_block(writer, "Interactive session interrupted.")
    return 0


def _write_block(writer, payload: str) -> None:
    writer.write(str(payload) + "\n")
    writer.flush()


if __name__ == "__main__":
    raise SystemExit(main())
