import hashlib

from fastapi import APIRouter, Depends, Query
from fastapi.responses import Response

from fastpluggy.core.dependency import get_fastpluggy

service_worker_router = APIRouter()

# Cached composed service worker JS and its content hash
_sw_cache: str | None = None
_sw_hash: str | None = None


def _build_composed_sw(fast_pluggy) -> str:
    """Compose the service worker from base skeleton + plugin handler files."""
    base_dir = fast_pluggy.base_dir
    base_path = f"{base_dir}/static/service-worker-base.js"

    with open(base_path) as f:
        parts = [f.read()]

    manager = fast_pluggy.get_manager()
    for name, plugin_state in manager.modules.items():
        if not manager.is_module_loaded(plugin_state):
            continue
        plugin = plugin_state.plugin
        handler_files = getattr(plugin, "sw_handler_files", [])
        if not handler_files:
            continue
        # Resolve each handler file relative to the plugin's static dir
        static_dir = (plugin.module_path or plugin_state.path) / "static"
        for rel_path in handler_files:
            handler_path = static_dir / rel_path
            if handler_path.exists():
                parts.append(f"\n// --- Plugin handler: {name}/{rel_path} ---\n")
                parts.append(handler_path.read_text())

    return "".join(parts)


def _get_sw(fast_pluggy) -> tuple[str, str]:
    """Return (composed_js, content_hash), building and caching on first call."""
    global _sw_cache, _sw_hash
    if _sw_cache is None:
        _sw_cache = _build_composed_sw(fast_pluggy)
        _sw_hash = hashlib.md5(_sw_cache.encode(), usedforsecurity=False).hexdigest()[:12]  # nosec B324
    return _sw_cache, _sw_hash


@service_worker_router.get("/service-worker.js")
async def serve_service_worker(fast_pluggy=Depends(get_fastpluggy), v: str = Query(None)):
    """Serve the composed service worker (base + plugin handlers)."""
    js, _ = _get_sw(fast_pluggy)
    return Response(
        content=js,
        media_type="application/javascript",
        headers={
            "Service-Worker-Allowed": "/",
            "Cache-Control": "no-cache, no-store, must-revalidate",
        },
    )


@service_worker_router.get("/sw_info.json")
async def get_sw_info(fast_pluggy=Depends(get_fastpluggy)):
    """Return SW version info for cache busting."""
    _, content_hash = _get_sw(fast_pluggy)
    return {"version": content_hash}
