# Copyright (c) 2025 CoReason, Inc.
#
# This software is proprietary and dual-licensed.
# Licensed under the Prosperity Public License 3.0 (the "License").
# A copy of the license is available at https://prosperitylicense.com/versions/3.0.0
# For details, see the LICENSE file.
# Commercial use beyond a 30-day trial requires a separate license.
#
# Source Code: https://github.com/CoReason-AI/coreason_navigator

import argparse
import asyncio

from coreason_identity.models import UserContext

from coreason_navigator import server
from coreason_navigator.utils.logger import logger


async def run_maps(args: argparse.Namespace) -> None:
    """Executes the Maps command logic."""
    context = UserContext(
        sub="cli-user",
        email="cli-user@example.com",
        permissions=["system"],
    )

    request = {"command": args.subcommand}
    if args.subcommand == "navigate":
        if not args.url:
            print("Error: --url is required for navigate")
            return
        request["url"] = args.url
    elif args.subcommand == "interact":
        request["action"] = args.interaction_type
        if args.target_id:
            request["target_id"] = args.target_id
        if args.text:
            request["text"] = args.text
        if args.coordinate:
            request["coordinate"] = args.coordinate
        if args.scroll_direction:
            request["direction"] = args.scroll_direction
        if args.scroll_amount:
            request["amount"] = args.scroll_amount
        # Handle 'goto' interaction needing url or text
        if args.interaction_type == "goto" and args.url:
            request["url"] = args.url

    elif args.subcommand == "extract":
        request["format"] = args.format

    try:
        result = await server.handle_request(request, context)
        print(result)
    except Exception as e:
        logger.exception("Maps command failed")
        print(f"Error: {e}")


def run_serve(args: argparse.Namespace) -> None:
    """Executes the serve command logic."""
    context = UserContext(
        sub="system-server",
        email="system-server@example.com",
        permissions=["system"],
    )

    # Inject context into server for MCP tools to use
    server.set_server_context(context)

    # Run the FastMCP server
    logger.info("Starting Coreason Navigator MCP Server...")
    server.mcp.run()


def main() -> None:
    """Entry point for the CLI."""
    parser = argparse.ArgumentParser(description="CoReason Navigator CLI")
    subparsers = parser.add_subparsers(dest="command", required=True)

    # Maps Command
    maps_parser = subparsers.add_parser("Maps", help="Directly control the navigator")
    maps_subparsers = maps_parser.add_subparsers(dest="subcommand", required=True)

    # Maps navigate
    nav_parser = maps_subparsers.add_parser("navigate", help="Navigate to a URL")
    nav_parser.add_argument("--url", required=True, help="URL to navigate to")

    # Maps interact
    interact_parser = maps_subparsers.add_parser("interact", help="Interact with the page")
    interact_parser.add_argument(
        "interaction_type",
        choices=["click", "type", "scroll", "wait", "goto", "screenshot"],
        help="Type of interaction",
    )
    interact_parser.add_argument("--target-id", help="Target element ID")
    interact_parser.add_argument("--text", help="Text to type")
    interact_parser.add_argument("--coordinate", nargs=2, type=float, help="X Y coordinates")
    interact_parser.add_argument("--scroll-direction", choices=["up", "down", "left", "right"], help="Scroll direction")
    interact_parser.add_argument("--scroll-amount", type=int, help="Scroll amount")
    interact_parser.add_argument("--url", help="URL for goto interaction")

    # Maps extract
    extract_parser = maps_subparsers.add_parser("extract", help="Extract page content")
    extract_parser.add_argument("--format", choices=["markdown", "html"], default="markdown", help="Output format")

    # Serve Command
    subparsers.add_parser("serve", help="Start the MCP server")

    args = parser.parse_args()

    if args.command == "Maps":
        asyncio.run(run_maps(args))
    elif args.command == "serve":
        run_serve(args)


if __name__ == "__main__":  # pragma: no cover
    main()
