#!/usr/bin/env python3
"""
TokenMoulds CLI Entry Point
Command-line interface for the formulaic design token system
"""

from __future__ import annotations

import argparse
import sys
from typing import List

from tokenmoulds.emitters import (
    TemplateResolver,
)

# Re-export public API so existing callers (tests, __main__) keep working.
from tokenmoulds.cli_generate import create_summary_report, generate_tokens  # noqa: F401
from tokenmoulds.cli_utils import (  # noqa: F401
    _count_tokens,
    parse_font_pair,
    validate_brand_tone,
    validate_content_density,
    validate_hex_color,
)
from tokenmoulds.dtcg.generator import TokenGenerator  # noqa: F401


def run_mcp_server(args: List[str]) -> None:
    """Run the MCP server subcommand."""
    import argparse as mcp_argparse

    parser = mcp_argparse.ArgumentParser(
        prog="tokenmoulds mcp-server",
        description="Start TokenMoulds MCP server for AI document generation",
    )
    parser.add_argument(
        "--tokens",
        type=str,
        help="Path to design tokens directory",
    )
    parser.add_argument(
        "--brands",
        type=str,
        help="Path to multi-brand directory (alternative to --tokens)",
    )
    parser.add_argument(
        "--output",
        type=str,
        default="./generated",
        help="Output directory for generated documents (default: ./generated)",
    )

    parsed = parser.parse_args(args)

    from pathlib import Path

    from tokenmoulds.mcp import run_server

    tokens_path = Path(parsed.tokens) if parsed.tokens else None
    brands_path = Path(parsed.brands) if parsed.brands else None
    output_path = Path(parsed.output)

    print("\U0001f680 Starting TokenMoulds MCP Server...", file=sys.stderr)
    if tokens_path:
        print(f"   Tokens: {tokens_path}", file=sys.stderr)
    if brands_path:
        print(f"   Brands: {brands_path}", file=sys.stderr)
    print(f"   Output: {output_path}", file=sys.stderr)
    print("   Ready for MCP connections", file=sys.stderr)

    run_server(
        tokens_path=tokens_path,
        brands_path=brands_path,
        output_path=output_path,
    )


def main() -> None:
    """Main CLI entry point."""

    # Check for mcp-server subcommand
    if len(sys.argv) > 1 and sys.argv[1] == "mcp-server":
        run_mcp_server(sys.argv[2:])
        return

    parser = argparse.ArgumentParser(
        prog="tokenmoulds",
        description="TokenMoulds Formulaic Design Token Generator",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Generate design tokens and templates from manual inputs
  tokenmoulds --org-id="acme" --font-pair="inter-roboto" --primary-color="#2563EB" --secondary-color="#DC2626" --locale="GB" --brand-tone=0.3

  tokenmoulds --org-id="startup" --font-pair="work-sans-source" --primary-color="#6366F1" --locale="US" --brand-tone=0.8 --generate-templates

  # Generate templates from a DTCG tokens file
  tokenmoulds --org-id="acme" --tokens-file="design.tokens.json" --generate-templates

  # Generate templates from layered DTCG files (ADR 017)
  tokenmoulds --org-id="acme" --layers-dir="data/layers/" --generate-templates
  tokenmoulds --org-id="acme" --layers-manifest="data/manifest.json" --generate-templates

  # Start MCP server for AI document generation
  tokenmoulds mcp-server --tokens ./data/
  tokenmoulds mcp-server --brands ./brands/ --output ./generated/
        """,
    )

    # Brand source — URL, manifest, or manual
    parser.add_argument(
        "--url",
        type=str,
        default=None,
        help="Extract brand from website URL and generate templates",
    )

    parser.add_argument(
        "--manifest",
        type=str,
        default=None,
        help="Path to brand-manifest.yaml — builds templates from manifest config",
    )

    parser.add_argument(
        "--output",
        type=str,
        default=None,
        dest="output_alias",
        help="Output directory (alias for --output-dir)",
    )

    parser.add_argument(
        "--format",
        type=str,
        default=None,
        dest="format_filter",
        help="Comma-separated list of output formats (e.g., potx,dotx,xltx)",
    )

    parser.add_argument(
        "--dry-run",
        action="store_true",
        default=False,
        help="Resolve tokens and build IR, but skip template emission",
    )

    # Organization ID (required unless --url or --manifest provides it)
    parser.add_argument(
        "--org-id",
        required=False,
        default=None,
        help='Organization identifier (e.g., "acme", "startup")',
    )

    parser.add_argument(
        "--font-pair",
        choices=["inter-roboto", "work-sans-source", "public-sans-spectral"],
        help="Font pair selection (required unless using --tokens-file)",
    )

    parser.add_argument(
        "--primary-color",
        help='Primary brand color (hex, e.g., "#2563EB") (required unless using --tokens-file)',
    )

    parser.add_argument(
        "--secondary-color",
        help='Secondary brand color (hex, e.g., "#DC2626") (required unless using --tokens-file)',
    )

    parser.add_argument(
        "--locale",
        choices=["GB", "US", "DE", "FR", "JP", "HE", "NL"],
        help="Locale for formatting and punctuation (required unless using --tokens-file)",
    )

    parser.add_argument(
        "--brand-tone",
        type=float,
        help="Brand tone: 0.0 = formal, 1.0 = casual (required unless using --tokens-file)",
    )

    # Optional arguments
    parser.add_argument(
        "--content-density",
        type=float,
        default=0.4,
        help="Content density: 0.0 = sparse, 1.0 = dense (default: 0.4)",
    )

    parser.add_argument(
        "--accessibility-level",
        choices=["AA", "AAA"],
        default="AA",
        help="Accessibility compliance level (default: AA)",
    )

    parser.add_argument(
        "--license-id",
        help="License identifier to validate before generation (defaults to lic_local_dev)",
    )

    parser.add_argument(
        "--license-token",
        help="Signed license token for future remote validation (optional)",
    )

    parser.add_argument(
        "--license-repo",
        help="GitHub repository slug associated with this license (e.g., tokenmoulds/acme-suite)",
    )

    parser.add_argument(
        "--output-dir",
        default="generated",
        help="Output directory (default: generated/)",
    )

    parser.add_argument(
        "--token-format",
        choices=["legacy", "dtcg", "both"],
        default="dtcg",
        help="Token output format: legacy (internal), dtcg (W3C standard), or both (default: dtcg)",
    )

    parser.add_argument(
        "--tokens-file",
        type=str,
        default=None,
        help="Path to DTCG tokens file (.tokens.json) to generate templates from. "
        "When provided, skips token generation and uses pre-computed token values.",
    )

    parser.add_argument(
        "--layers-dir",
        type=str,
        default=None,
        help="Directory containing DTCG layer files (core.tokens.json, fork.tokens.json, etc.). "
        "Layers are merged in precedence order: core -> fork -> org -> group -> personal.",
    )

    parser.add_argument(
        "--layers-manifest",
        type=str,
        default=None,
        help="Path to manifest JSON file pointing to DTCG layer files. "
        "Alternative to --layers-dir for explicit layer configuration.",
    )

    parser.add_argument(
        "--template-root",
        default=None,
        help="Override directory containing format-specific template subfolders (word/excel/powerpoint)",
    )

    parser.add_argument(
        "--fonts-dir",
        default=None,
        help="Directory containing vendored font files for embedding",
    )

    parser.add_argument(
        "--disable-font-embedding",
        action="store_true",
        help="Skip font embedding during packaging",
    )

    parser.add_argument(
        "--embed-fonts",
        action="store_true",
        help="Force-enable font embedding (alias for the default behavior)",
    )

    parser.add_argument(
        "--skip-validation",
        action="store_true",
        help="Skip validate-template checks on packaged outputs",
    )

    parser.add_argument(
        "--generate-templates",
        action="store_true",
        help="Generate OOXML templates (.potx, .dotx, .xltx)",
    )

    parser.add_argument(
        "--generate-odf",
        action="store_true",
        help="Generate ODF templates (.ott, .otp)",
    )

    parser.add_argument(
        "--compare-baselines",
        action="store_true",
        help="After generating templates, compare screenshots against stored baselines",
    )

    parser.add_argument(
        "--baselines-workspace",
        default="tests/baselines",
        help="Path to baseline workspace (default: tests/baselines)",
    )

    parser.add_argument(
        "--create-summary",
        action="store_true",
        default=True,
        help="Create generation summary report (default: True)",
    )

    parser.add_argument("--verbose", action="store_true", help="Enable verbose output")

    parser.add_argument(
        "--preload-templates",
        action="store_true",
        help="Preload and cache all XML templates at startup for faster batch generation",
    )

    # Parse arguments
    args = parser.parse_args()

    # Validate required arguments when not using --tokens-file, --layers-dir, or --layers-manifest
    if not args.tokens_file and not args.layers_dir and not args.layers_manifest:
        missing = []
        if not args.font_pair:
            missing.append("--font-pair")
        if not args.primary_color:
            missing.append("--primary-color")
        if not args.secondary_color:
            missing.append("--secondary-color")
        if not args.locale:
            missing.append("--locale")
        if args.brand_tone is None:
            missing.append("--brand-tone")
        if missing:
            parser.error(
                f"The following arguments are required when not using --tokens-file, "
                f"--layers-dir, or --layers-manifest: {', '.join(missing)}"
            )

    # Set verbose mode
    if args.verbose:
        print("\U0001f50d Verbose mode enabled")

    # Preload templates if requested
    if args.preload_templates:
        if args.verbose:
            print("\u26a1 Preloading template cache...")
        count = TemplateResolver.preload_all()
        if args.verbose:
            print(f"   Cached {count} templates")

    # Generate tokens
    generate_tokens(args)


if __name__ == "__main__":
    main()
