"""
Sophi CLI
Usage:
  sophi compile <file.sph>           — compile and show summary
  sophi compile <file.sph> --json    — output full JSON
  sophi compile <file.sph> --secret  — include secret in output (careful!)
  sophi check   <file.sph>           — verify equilibrium only, no output
"""

import sys
import json
import argparse
from pathlib import Path

from .lexer import LexError
from .parser import parse, ParseError
from .verifier import verify, VerifyError
from .compiler import compile_swap

BANNER = """
  ███████╗ ██████╗ ██████╗ ██╗  ██╗██╗
  ██╔════╝██╔═══██╗██╔══██╗██║  ██║██║
  ███████╗██║   ██║██████╔╝███████║██║
  ╚════██║██║   ██║██╔═══╝ ██╔══██║██║
  ███████║╚██████╔╝██║     ██║  ██║██║
  ╚══════╝ ╚═════╝ ╚═╝     ╚═╝  ╚═╝╚═╝
  balance-based non-custodial swap language  v0.1
"""

def run_compile(source: str, show_json: bool, show_secret: bool):
    # 1. Parse
    try:
        program = parse(source)
    except (LexError, ParseError) as e:
        print(f"\n✗ Syntax error\n  {e}\n")
        sys.exit(1)

    # 2. Verify equilibrium
    try:
        warnings = verify(program)
    except VerifyError as e:
        print(f"\n✗ {e}\n")
        sys.exit(1)

    # 3. Compile
    result = compile_swap(program, warnings)

    # 4. Output
    print(result.summary())

    if show_json:
        output = {
            "intents":     result.intents,
            "htlc_params": {
                k: v for k, v in result.htlc_params.items()
                if k != 'secret' or show_secret
            }
        }
        print("\n── JSON output ─────────────────────────────────")
        print(json.dumps(output, indent=2))

    print("\n✓ Swap compiled successfully.\n")
    return result


def run_check(source: str):
    try:
        program = parse(source)
        warnings = verify(program)
    except (LexError, ParseError) as e:
        print(f"\n✗ Syntax error\n  {e}\n")
        sys.exit(1)
    except VerifyError as e:
        print(f"\n✗ {e}\n")
        sys.exit(1)

    print(f"\n✓ Equilibrium verified — {len(program.parties)} parties, swap is valid.\n")
    for w in warnings:
        print(f"  ⚠ {w}")


def main():
    print(BANNER)

    parser = argparse.ArgumentParser(prog='sophi', add_help=True)
    sub = parser.add_subparsers(dest='command')

    compile_cmd = sub.add_parser('compile', help='Compile a .sph file')
    compile_cmd.add_argument('file', help='Path to .sph file')
    compile_cmd.add_argument('--json', action='store_true', help='Output full JSON')
    compile_cmd.add_argument('--secret', action='store_true', help='Include secret in output')

    check_cmd = sub.add_parser('check', help='Verify equilibrium only')
    check_cmd.add_argument('file', help='Path to .sph file')

    args = parser.parse_args()

    if not args.command:
        parser.print_help()
        sys.exit(0)

    path = Path(args.file)
    if not path.exists():
        print(f"✗ File not found: {args.file}")
        sys.exit(1)

    source = path.read_text()

    if args.command == 'compile':
        run_compile(source, show_json=args.json, show_secret=args.secret)
    elif args.command == 'check':
        run_check(source)


if __name__ == '__main__':
    main()
