from __future__ import annotations

import argparse
import os
from pathlib import Path

import uvicorn
from dotenv import load_dotenv

from iterfact import __version__


def _apply_optional_env(name: str, value: str | None) -> None:
    if value is not None and str(value).strip():
        os.environ[name] = str(value).strip()


def _load_runtime_env(env_file: str | None) -> None:
    candidate_paths: list[Path] = []
    if env_file:
        candidate_paths.append(Path(env_file).expanduser())
    candidate_paths.extend([Path.cwd() / ".env", Path.cwd() / ".env.local"])
    for candidate in candidate_paths:
        if candidate.exists():
            load_dotenv(candidate, override=False)


def _build_mcp_parser(parser: argparse.ArgumentParser) -> None:
    parser.add_argument("--host", help="Bind host for the MCP HTTP server.")
    parser.add_argument("--port", type=int, help="Bind port for the MCP HTTP server.")
    parser.add_argument("--env-file", help="Optional path to a dotenv file.")
    parser.add_argument("--output-dir", help="Override ITERFACT_OUTPUT_DIR.")
    parser.add_argument("--analytics-dir", help="Override ITERFACT_ANALYTICS_DIR.")
    parser.add_argument("--vault-path", help="Override ITERFACT_VAULT_PATH.")
    parser.add_argument(
        "--public-artifact-base-url",
        help="Override ITERFACT_PUBLIC_ARTIFACT_BASE_URL.",
    )
    parser.add_argument(
        "--public-app-base-url",
        help="Override NEXT_PUBLIC_SITE_URL.",
    )
    parser.add_argument(
        "--reload",
        action="store_true",
        help="Run uvicorn with reload enabled for local development.",
    )


def _run_mcp(args: argparse.Namespace) -> int:
    _load_runtime_env(getattr(args, "env_file", None))
    _apply_optional_env("HOST", getattr(args, "host", None))
    _apply_optional_env("PORT", str(args.port) if getattr(args, "port", None) else None)
    _apply_optional_env("ITERFACT_OUTPUT_DIR", getattr(args, "output_dir", None))
    _apply_optional_env("ITERFACT_ANALYTICS_DIR", getattr(args, "analytics_dir", None))
    _apply_optional_env("ITERFACT_VAULT_PATH", getattr(args, "vault_path", None))
    _apply_optional_env(
        "ITERFACT_PUBLIC_ARTIFACT_BASE_URL",
        getattr(args, "public_artifact_base_url", None),
    )
    _apply_optional_env("NEXT_PUBLIC_SITE_URL", getattr(args, "public_app_base_url", None))

    from MCP import server as mcp_server

    host = getattr(args, "host", None) or mcp_server.SETTINGS.host
    port = int(getattr(args, "port", None) or mcp_server.SETTINGS.port)
    if getattr(args, "reload", False):
        uvicorn.run("MCP.server:app", host=host, port=port, reload=True)
    else:
        uvicorn.run(mcp_server.app, host=host, port=port)
    return 0


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="iterfact",
        description="IterFact CLI for running the MCP server.",
    )
    parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
    subparsers = parser.add_subparsers(dest="command")

    mcp_parser = subparsers.add_parser("mcp", help="Run the IterFact MCP server.")
    _build_mcp_parser(mcp_parser)
    mcp_parser.set_defaults(handler=_run_mcp)

    serve_parser = subparsers.add_parser("serve", help="Alias for `iterfact mcp`.")
    _build_mcp_parser(serve_parser)
    serve_parser.set_defaults(handler=_run_mcp)

    return parser


def main(argv: list[str] | None = None) -> int:
    parser = build_parser()
    args = parser.parse_args(argv)
    handler = getattr(args, "handler", None)
    if handler is None:
        parser.print_help()
        return 0
    return int(handler(args) or 0)


def mcp_main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        prog="iterfact-mcp",
        description="Run the IterFact MCP server.",
    )
    parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
    _build_mcp_parser(parser)
    args = parser.parse_args(argv)
    return _run_mcp(args)


if __name__ == "__main__":
    raise SystemExit(main())
