"""
TENGWAR REPL

Interactive Read-Eval-Print Loop for TENGWAR.
Designed for AI interaction but functional for any user.
"""
import sys
import os
from .lexer import tokenize
from .parser import parse
from .interpreter import Interpreter
from .errors import TengwarError


BANNER = """
╔═══════════════════════════════════════════════════╗
║   ▄▀▄ ▀▄▀ █ █▀█ █▄ █                             ║
║   █▀█ █ █ █ █▄█ █ ▀█                             ║
║                                                   ║
║   The AI-Native Programming Language  v0.1.0      ║
║   tengwarlang.dev                                   ║
║                                                   ║
║   Type expressions to evaluate. :q to quit.       ║
║   :h for help.                                    ║
╚═══════════════════════════════════════════════════╝
"""

HELP = """
TENGWAR REPL Commands:
  :q, :quit     Exit the REPL
  :h, :help     Show this help
  :env          Show current bindings
  :trace        Toggle execution trace
  :reset        Reset environment
  :load <file>  Load and execute a .tw file

Syntax Quick Reference:
  (λ x y (+ x y))           Lambda / function
  expr → name                Bind result to name
  (? cond then else)         Conditional
  (~ val pat1 res1 ...)      Pattern match
  (>> e1 e2 ...)             Sequence
  (∥ e1 e2 ...)              Parallel
  (:= name value)            Define
  (↺ f (λ n ...))            Recursion
  ⟨a b c⟩                    Tuple
  ⟦a b c⟧                    Vector
  (⊢ assertion)              Proof check

ASCII alternatives:
  \\ = λ    -> = →    || = ∥    <| |> = ⟨⟩    [| |] = ⟦⟧
  := = :=   |- = ⊢    +> = ⊕
"""


def repl(interpreter: Interpreter = None):
    """Start the TENGWAR REPL"""
    if interpreter is None:
        interpreter = Interpreter()

    print(BANNER)

    buffer = ""
    prompt = "λ> "

    while True:
        try:
            line = input(prompt)
        except (EOFError, KeyboardInterrupt):
            print("\n∅")
            break

        # Commands
        stripped = line.strip()
        if stripped in (':q', ':quit'):
            print("∅")
            break
        if stripped in (':h', ':help'):
            print(HELP)
            continue
        if stripped == ':env':
            for name, val in sorted(interpreter.global_env.bindings.items()):
                print(f"  {name} = {repr(val)}")
            print(f"\n  Content store: {len(interpreter.global_env.content_store)} entries")
            continue
        if stripped == ':trace':
            interpreter.trace = not interpreter.trace
            print(f"  Trace: {'on' if interpreter.trace else 'off'}")
            continue
        if stripped == ':reset':
            interpreter = Interpreter()
            print("  Environment reset.")
            continue
        if stripped.startswith(':load '):
            path = stripped[6:].strip()
            try:
                with open(path, 'r', encoding='utf-8') as f:
                    source = f.read()
                result = interpreter.run_source(source)
                print(f"  → {repr(result)}")
            except FileNotFoundError:
                print(f"  Error: File not found: {path}")
            except TengwarError as e:
                print(f"  Error: {e}")
            continue

        if not stripped:
            continue

        # Accumulate multiline input (count parens)
        buffer += line + "\n"
        open_parens = buffer.count('(') - buffer.count(')')
        open_parens += buffer.count('⟨') - buffer.count('⟩')
        open_parens += buffer.count('⟦') - buffer.count('⟧')

        if open_parens > 0:
            prompt = ".. "
            continue

        # Evaluate
        try:
            source = buffer.strip()
            buffer = ""
            prompt = "λ> "

            result = interpreter.run_source(source)
            if result is not None:
                print(f"  → {repr(result)}")
        except TengwarError as e:
            print(f"  Error: {e}")
        except Exception as e:
            print(f"  Internal error: {e}")


def run_file(path: str, trace: bool = False):
    """Execute an TENGWAR source file"""
    interpreter = Interpreter()
    interpreter.trace = trace

    with open(path, 'r', encoding='utf-8') as f:
        source = f.read()

    try:
        result = interpreter.run_source(source)
        return result
    except TengwarError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == '__main__':
    repl()
