"""
Nexa Language — REPL (nexa shell)
Interactive Read-Eval-Print Loop for Nexa v21
"""
from __future__ import annotations
import sys, traceback

def run_repl():
    from nexa_lang.lexer import Lexer  # type: ignore[import]
    from nexa_lang.parser import Parser  # type: ignore[import]
    from nexa_lang.interpreter import Interpreter  # type: ignore[import]
    from nexa_lang.interpreter import Environment  # type: ignore[import]
    from nexa_lang.builtins import BUILTINS  # type: ignore[import]

    interp = Interpreter()
    env = Environment()
    for k, v in BUILTINS.items():
        env.set(k, v)

    import os
    try: import readline
    except ImportError: readline = None

    histfile = os.path.join(os.path.expanduser("~"), ".nexa_history")
    if readline and os.path.exists(histfile):
        try: readline.read_history_file(histfile)
        except: pass

    print("┌─────────────────────────────────────────────────────┐")
    print("│  Nexa REPL  v21  —  type 'exit' or Ctrl+C to quit   │")
    print("└─────────────────────────────────────────────────────┘")

    buffer = ""
    while True:
        try:
            prompt = "... " if buffer else ">>> "
            line = input(prompt)
        except (EOFError, KeyboardInterrupt):
            print("\nBye! 👋")
            break

        cmd = line.strip()
        if cmd in ("exit", ".exit", "quit"):
            print("Bye! 👋"); break

        if cmd == ".history":
            if readline:
                for i in range(1, readline.get_current_history_length() + 1):  # type: ignore[union-attr]
                    print(f"{i}: {readline.get_history_item(i)}")  # type: ignore[union-attr]
            else:
                print("History not supported on this platform without readline.")
            continue

        if cmd == ".clear":
            print("\033[H\033[J", end="")
            continue

        if cmd.startswith(".type "):
            expr = cmd[6:].strip()  # type: ignore[index]
            src = f"let __tmp = {expr};\ntypeof(__tmp);"
            buffer = src
        else:
            buffer += line + "\n"

        open_braces = buffer.count("{") - buffer.count("}")
        if open_braces > 0:
            continue

        src = buffer.strip()
        buffer = ""
        if not src: continue

        if readline:
            try:
                readline.write_history_file(histfile)  # type: ignore[union-attr]
            except: pass

        try:
            tokens = Lexer(src).tokenize()
            ast = Parser(tokens).parse()
            result = None
            for stmt in ast.statements:
                result = interp._exec(stmt, env)
            if result is not None:
                # Type inference helper
                if cmd.startswith(".type "):
                    print(f"  \033[95mType: {result}\033[0m")
                else:
                    print(f"  \033[96m→ {repr(result)}\033[0m")
        except KeyboardInterrupt:
            print()
        except Exception as e:
            print(f"  \033[91m✘ {type(e).__name__}: {e}\033[0m")

# ── Backward-compatible exports expected by __init__.py ───────────────────────

def run_source(src: str, debug: bool = False):
    from nexa_lang.lexer import Lexer  # type: ignore[import]
    from nexa_lang.parser import Parser  # type: ignore[import]
    from nexa_lang.interpreter import Interpreter, Environment  # type: ignore[import]
    from nexa_lang.builtins import BUILTINS  # type: ignore[import]
    env = Environment()
    for k, v in BUILTINS.items(): env.set(k, v)
    interp = Interpreter()
    tokens = Lexer(src).tokenize()
    ast = Parser(tokens).parse()
    for stmt in ast.statements:
        interp._exec(stmt, env)


def run_file(path: str, debug: bool = False):
    import os
    with open(path, encoding="utf-8") as f: src = f.read()
    print(f"\n▶  Running {os.path.basename(path)}\n")
    run_source(src, debug=debug)


def repl(debug: bool = False):
    run_repl()

