#!/usr/bin/env python3
"""Read-only report for the production PChome growth mapping backlog."""

from __future__ import annotations

import argparse
import json
import urllib.error
import urllib.parse
import urllib.request
from typing import Any

from scripts.ops import check_production_version_truth as version_guard
from services.pchome_mapping_backlog_service import summarize_pchome_mapping_backlog


DEFAULT_API_URL = "https://mo.wooo.work/api/ai/pchome-growth/opportunities"
DEFAULT_LIMIT = 20


def with_limit(url: str, limit: int) -> str:
    parsed = urllib.parse.urlparse(url)
    query = urllib.parse.parse_qs(parsed.query, keep_blank_values=True)
    query["limit"] = [str(max(5, min(int(limit or DEFAULT_LIMIT), 50)))]
    return urllib.parse.urlunparse(parsed._replace(query=urllib.parse.urlencode(query, doseq=True)))


def fetch_json(url: str, timeout: float) -> dict[str, Any]:
    with urllib.request.urlopen(url, timeout=timeout) as response:
        payload = response.read().decode("utf-8")
    data = json.loads(payload)
    if not isinstance(data, dict):
        raise ValueError("API payload must be a JSON object")
    return data


def summarize_payload(payload: dict[str, Any]) -> dict[str, Any]:
    return summarize_pchome_mapping_backlog(payload)


def build_report(
    api_url: str,
    limit: int,
    timeout: float,
    health_url: str,
    skip_version_truth: bool,
) -> dict[str, Any]:
    version_report = None
    version_errors: list[str] = []
    if not skip_version_truth:
        version_report = version_guard.build_report(health_url, timeout)
        version_ok, version_errors = version_guard.evaluate(version_report, allow_local_version_drift=False)
        if not version_ok:
            return {
                "policy": "read_only_production_pchome_mapping_backlog",
                "result": "BLOCKED",
                "api_url": with_limit(api_url, limit),
                "version_truth": version_report,
                "errors": version_errors,
            }

    final_url = with_limit(api_url, limit)
    payload = fetch_json(final_url, timeout)
    summary = summarize_payload(payload)
    return {
        **summary,
        "policy": "read_only_production_pchome_mapping_backlog",
        "api_url": final_url,
        "version_truth": version_report,
        "errors": version_errors,
    }


def format_text(report: dict[str, Any]) -> str:
    stats = report.get("stats") or {}
    backlog = report.get("backlog") or {}
    version = ((report.get("version_truth") or {}).get("production") or {}).get("version")
    lines = [
        "pchome_mapping_backlog:",
        f"- policy: {report.get('policy')}",
        f"- result: {report.get('result')}",
        f"- production_version: {version or 'not_checked'}",
        f"- api_url: {report.get('api_url')}",
        f"- generated_at: {report.get('generated_at')}",
        f"- cache_state: {report.get('cache_state') or 'unknown'}",
        f"- candidate_count: {stats.get('candidate_count')}",
        f"- mapped_count: {stats.get('mapped_count')}",
        f"- mapping_rate: {stats.get('mapping_rate')}%",
        f"- needs_mapping_count: {stats.get('needs_mapping_count')}",
        f"- review_candidate_count: {stats.get('review_candidate_count')}",
        f"- overall_sales_7d: {stats.get('overall_sales_7d')}",
        f"- action_counts: {json.dumps(stats.get('action_counts') or {}, ensure_ascii=False, sort_keys=True)}",
        f"- direct_mapping_count: {backlog.get('direct_mapping_count')}",
        f"- mapped_opportunity_count: {backlog.get('mapped_opportunity_count')}",
    ]
    for error in report.get("errors") or []:
        lines.append(f"- blocker: {error}")

    top_items = list((backlog.get("top_needs_mapping") or [])[:5])
    if top_items:
        lines.append("- top_needs_mapping:")
        for item in top_items:
            lines.append(
                "  - "
                f"{item.get('pchome_product_id')} | "
                f"sales_7d={item.get('sales_7d')} | "
                f"score={item.get('priority_score')} | "
                f"action={item.get('action_label')}"
            )
    return "\n".join(lines)


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--api-url", default=DEFAULT_API_URL)
    parser.add_argument("--health-url", default=version_guard.DEFAULT_HEALTH_URL)
    parser.add_argument("--limit", type=int, default=DEFAULT_LIMIT)
    parser.add_argument("--timeout", type=float, default=12.0)
    parser.add_argument("--json", action="store_true", help="Print machine-readable report")
    parser.add_argument(
        "--skip-version-truth",
        action="store_true",
        help="Skip production version guard; intended only for offline parser tests.",
    )
    args = parser.parse_args(argv)

    try:
        report = build_report(
            api_url=args.api_url,
            limit=args.limit,
            timeout=args.timeout,
            health_url=args.health_url,
            skip_version_truth=args.skip_version_truth,
        )
    except (OSError, ValueError, urllib.error.URLError) as exc:
        report = {
            "policy": "read_only_production_pchome_mapping_backlog",
            "result": "BLOCKED",
            "api_url": with_limit(args.api_url, args.limit),
            "errors": [str(exc)],
        }
        print(json.dumps(report, ensure_ascii=False, indent=2) if args.json else format_text(report))
        return 2

    if args.json:
        print(json.dumps(report, ensure_ascii=False, indent=2))
    else:
        print(format_text(report))
    return 0 if report.get("result") != "BLOCKED" else 1


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