from __future__ import annotations

import json
import shutil
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

from packages.pet_package_schema import ALLOWED_ACTIONS, load_pet_package


SCHEMA_VERSION = "0.1.0"
CELL_WIDTH = 192
CELL_HEIGHT = 208


def export_fixture_build(fixture_dir: str | Path, output_root: str | Path) -> Path:
    fixture_path = Path(fixture_dir)
    output_path = Path(output_root)
    package = load_pet_package(fixture_path)
    build_id = f"build-public-{package['id']}"
    package_id = f"package-public-{package['id']}"
    build_dir = output_path / package["id"]
    qa_dir = build_dir / "qa"
    qa_dir.mkdir(parents=True, exist_ok=True)

    shutil.copy2(fixture_path / package["asset"]["spritesheetPath"], build_dir / "spritesheet.webp")

    manifest = _build_manifest(package, build_id, package_id)
    validation = _build_validation(manifest, package)
    contact_sheet = _build_contact_sheet(package)
    summary = _build_summary(package, manifest)

    _write_json(build_dir / "manifest.json", manifest)
    _write_json(build_dir / "validation.json", validation)
    (qa_dir / "contact-sheet.html").write_text(contact_sheet, encoding="utf-8")
    _write_json(qa_dir / "run-summary.json", summary)
    return build_dir


def _build_manifest(package: dict[str, Any], build_id: str, package_id: str) -> dict[str, Any]:
    created_at = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
    return {
        "package_id": package_id,
        "build_id": build_id,
        "pet_id": package["id"],
        "display_name": package["displayName"],
        "runtime_version": package["runtimeVersion"],
        "schema_version": SCHEMA_VERSION,
        "cell_width": CELL_WIDTH,
        "cell_height": CELL_HEIGHT,
        "states": [
            {
                "name": action,
                "frames": int(package["animations"][action]["frames"]),
                "mode": "low_disturbance",
            }
            for action in ALLOWED_ACTIONS
        ],
        "spritesheet_path": "spritesheet.webp",
        "checksum_algorithm": package["asset"]["checksumAlgorithm"],
        "checksum": package["asset"]["checksum"],
        "created_at": created_at,
        "user_approved": False,
        "source": {
            "kind": "public_synthetic_fixture",
            "asset_style": "high_fidelity_reference_preserving",
            "raw_media_included": False,
            "memory_text_included": False,
        },
    }


def _build_validation(manifest: dict[str, Any], package: dict[str, Any]) -> dict[str, Any]:
    checks = {
        "manifest_complete": True,
        "spritesheet_exists": True,
        "checksum_sha256": len(package["asset"]["checksum"]) == 64,
        "states_allowed": [state["name"] for state in manifest["states"]] == list(ALLOWED_ACTIONS),
        "high_fidelity_asset": manifest["source"].get("asset_style") == "high_fidelity_reference_preserving",
        "user_approval_required": manifest["user_approved"] is False,
        "no_sensitive_payloads": True,
    }
    return {
        "ok": all(checks.values()),
        "checks": checks,
        "failure_reason": None,
    }


def _build_contact_sheet(package: dict[str, Any]) -> str:
    rows = "\n".join(
        f"<li><strong>{action}</strong><span>低打扰动作，{package['animations'][action]['frames']} frames</span></li>"
        for action in ALLOWED_ACTIONS
    )
    return f"""<!doctype html>
<html lang="zh-CN">
<meta charset="utf-8" />
<title>{package['displayName']} QA contact sheet</title>
<style>
  body {{ font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif; background: #fbf7f0; color: #2e2a26; }}
  main {{ max-width: 880px; margin: 32px auto; padding: 24px; background: #fff; border-radius: 18px; }}
  img {{ width: 256px; height: 256px; object-fit: cover; object-position: left top; }}
  li {{ margin: 8px 0; display: flex; gap: 12px; }}
</style>
<main>
  <h1>{package['displayName']} 本地 QA contact sheet</h1>
  <p>公开合成样例，仅用于第一版结构校验和高保真预览，不包含真实用户素材。</p>
  <img src="../spritesheet.webp" alt="{package['displayName']} spritesheet preview" />
  <ul>{rows}</ul>
</main>
</html>
"""


def _build_summary(package: dict[str, Any], manifest: dict[str, Any]) -> dict[str, Any]:
    return {
        "ok": True,
        "package_id": manifest["package_id"],
        "build_id": manifest["build_id"],
        "pet_id": package["id"],
        "manifest": "manifest.json",
        "spritesheet": "spritesheet.webp",
        "validation": "validation.json",
        "contact_sheet": "qa/contact-sheet.html",
    }


def _write_json(path: Path, payload: dict[str, Any]) -> None:
    path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
