"""µFrame CLI — render, compile, check, and deploy .uf files.

Usage:
    python -m uframe.cli render <file.uf> [--ascii | --micron] [--width N]
    python -m uframe.cli compile <file.uf> [--out <file.mu>] [--embed]
    python -m uframe.cli check <file.uf>
    python -m uframe.cli deploy <file.uf> [--dest <dir>]
"""

from __future__ import annotations

import argparse
import os
import sys
from pathlib import Path

import uframe
from uframe.errors import UFrameError


def cmd_render(args: argparse.Namespace) -> int:
    """Render a .uf file to ASCII and/or Micron."""
    source = Path(args.file).read_text(encoding="utf-8")

    try:
        result = uframe.compile(source, width=args.width, theme=getattr(args, 'theme', ''))
    except UFrameError as e:
        print(f"Error: {e}", file=sys.stderr)
        return 1

    if args.ascii:
        print(result.ascii)
    elif args.micron:
        print(result.micron)
    else:
        # Default: show ASCII
        print(result.ascii)

    if result.warnings:
        for w in result.warnings:
            print(f"Warning: {w.message}", file=sys.stderr)

    if result.is_dynamic:
        print(f"\n[Dynamic page — {len(result.script)} bytes of generated script]", file=sys.stderr)

    return 0


def cmd_compile(args: argparse.Namespace) -> int:
    """Compile a .uf file to an executable .mu script (dynamic) or static .mu."""
    source_path = Path(args.file)
    source = source_path.read_text(encoding="utf-8")

    try:
        result = uframe.compile(source, width=args.width, theme=getattr(args, 'theme', ''))
    except UFrameError as e:
        print(f"Error: {e}", file=sys.stderr)
        return 1

    out_path = Path(args.out) if args.out else source_path.with_suffix(".mu")

    if result.is_dynamic and result.script:
        out_path.write_text(result.script, encoding="utf-8")
        out_path.chmod(0o755)
        print(f"Compiled dynamic: {out_path} ({len(result.script)} bytes, +x)")
    else:
        out_path.write_text(result.micron, encoding="utf-8")
        print(f"Compiled static: {out_path} ({len(result.micron)} bytes)")

    return 0


def cmd_check(args: argparse.Namespace) -> int:
    """Validate a .uf file without generating output."""
    source = Path(args.file).read_text(encoding="utf-8")

    try:
        result = uframe.compile(source, width=args.width, theme=getattr(args, 'theme', ''))
    except UFrameError as e:
        print(f"Error: {e}", file=sys.stderr)
        return 1

    status = "dynamic" if result.is_dynamic else "static"
    print(f"OK: {args.file} ({status}, {len(result.ascii)} chars ASCII, {len(result.micron)} chars Micron)")

    if result.warnings:
        for w in result.warnings:
            print(f"  Warning: {w.message}")

    return 0


def cmd_deploy(args: argparse.Namespace) -> int:
    """Compile and deploy a .uf file to the NomadNet pages directory."""
    source_path = Path(args.file)
    source = source_path.read_text(encoding="utf-8")
    dest_dir = Path(args.dest or os.path.expanduser("~/.nomadnetwork/storage/pages"))

    try:
        result = uframe.compile(source, width=args.width, theme=getattr(args, 'theme', ''))
    except UFrameError as e:
        print(f"Error: {e}", file=sys.stderr)
        return 1

    dest_dir.mkdir(parents=True, exist_ok=True)
    out_path = dest_dir / f"{source_path.stem}.mu"

    if result.is_dynamic and result.script:
        out_path.write_text(result.script, encoding="utf-8")
        out_path.chmod(0o755)
        print(f"Deployed dynamic: {out_path}")
    else:
        out_path.write_text(result.micron, encoding="utf-8")
        out_path.chmod(0o644)
        print(f"Deployed static: {out_path}")

    return 0


def cmd_image(args: argparse.Namespace) -> int:
    """Convert an image file to character art."""
    from uframe.imaging import convert_image
    try:
        lines = convert_image(args.file, mode=args.mode, width=args.width,
                              dither=args.dither, invert=args.invert)
        for line in lines:
            print(line)
    except ImportError:
        print("Error: Pillow is required: pip install Pillow", file=sys.stderr)
        return 1
    except FileNotFoundError:
        print(f"Error: Image not found: {args.file}", file=sys.stderr)
        return 1
    return 0


def main() -> int:
    parser = argparse.ArgumentParser(
        prog="uframe",
        description="µFrame — A DSL for rich terminal UIs rendered as ASCII and Micron",
    )
    sub = parser.add_subparsers(dest="command", required=True)

    # render
    p_render = sub.add_parser("render", help="Render a .uf file")
    p_render.add_argument("file", help="Path to .uf source file")
    p_render.add_argument("--ascii", action="store_true", help="Output ASCII only")
    p_render.add_argument("--micron", action="store_true", help="Output Micron only")
    p_render.add_argument("--width", type=int, default=64, help="Page width (default: 64)")
    p_render.add_argument("--theme", default="", help="Theme name (default, nouveau, gothic, bamboo, circuit, brutalist)")

    # compile
    p_compile = sub.add_parser("compile", help="Compile to .mu file")
    p_compile.add_argument("file", help="Path to .uf source file")
    p_compile.add_argument("--out", help="Output file path (default: <name>.mu)")
    p_compile.add_argument("--width", type=int, default=64, help="Page width")
    p_compile.add_argument("--theme", default="", help="Theme name")

    # check
    p_check = sub.add_parser("check", help="Validate a .uf file")
    p_check.add_argument("file", help="Path to .uf source file")
    p_check.add_argument("--width", type=int, default=64, help="Page width")

    # deploy
    p_deploy = sub.add_parser("deploy", help="Compile and deploy to NomadNet")
    p_deploy.add_argument("file", help="Path to .uf source file")
    p_deploy.add_argument("--dest", help="Destination directory (default: ~/.nomadnetwork/storage/pages)")
    p_deploy.add_argument("--width", type=int, default=64, help="Page width")
    p_deploy.add_argument("--theme", default="", help="Theme name")

    # image (standalone conversion)
    p_image = sub.add_parser("image", help="Convert image to character art")
    p_image.add_argument("file", help="Path to image file")
    p_image.add_argument("--mode", default="braille", help="braille, block, ascii, halfblock")
    p_image.add_argument("--width", type=int, default=40, help="Output width")
    p_image.add_argument("--dither", default="floyd", help="floyd, threshold, none")
    p_image.add_argument("--invert", action="store_true", help="Invert light/dark")

    args = parser.parse_args()

    commands = {
        "render": cmd_render,
        "compile": cmd_compile,
        "check": cmd_check,
        "deploy": cmd_deploy,
        "image": cmd_image,
    }

    return commands[args.command](args)


if __name__ == "__main__":
    sys.exit(main())
