"""
Dashboard-Widgets × Feature-System: Sichtbarkeit aus check_feature_access.

Katalog-Einträge optional `requires_feature` (features.id). Fehlt der Key → immer erlaubt.
"""
from __future__ import annotations

import copy
from typing import Any

from widget_catalog import WIDGET_CATALOG
from widget_feature_requirements_db import get_widget_required_feature_ids


def _check_feature_access(profile_id: str, feature_id: str, conn) -> dict:
    """Indirection für Tests (monkeypatch) und spätes Laden von auth (bcrypt)."""
    from auth import check_feature_access

    return check_feature_access(profile_id, feature_id, conn)

_WIDGET_ENTRY_BY_ID: dict[str, dict[str, Any]] = {e["id"]: e for e in WIDGET_CATALOG}


def widget_id_allowed(widget_id: str, profile_id: str, conn) -> bool:
    if _WIDGET_ENTRY_BY_ID.get(widget_id) is None:
        return False
    fids = get_widget_required_feature_ids(widget_id, conn)
    if not fids:
        return True
    for fid in fids:
        if not _check_feature_access(profile_id, fid, conn)["allowed"]:
            return False
    return True


def _public_row(entry: dict[str, Any], *, allowed: bool) -> dict[str, Any]:
    return {
        "id": entry["id"],
        "title": entry["title"],
        "description": entry["description"],
        "allowed": allowed,
    }


def widgets_catalog_for_profile(profile_id: str, conn) -> list[dict[str, Any]]:
    """Zeilen für GET /api/app/widgets/catalog (ohne internes requires_feature-Feld)."""
    out: list[dict[str, Any]] = []
    for e in WIDGET_CATALOG:
        allowed = widget_id_allowed(e["id"], profile_id, conn)
        out.append(_public_row(e, allowed=allowed))
    return out


def widgets_catalog_payload(profile_id: str, conn) -> dict[str, Any]:
    return {
        "catalog_version": 1,
        "widgets": widgets_catalog_for_profile(profile_id, conn),
    }


def widgets_catalog_admin_payload() -> dict[str, Any]:
    """Admin: alle Widgets als auswählbar (ohne Feature-Filter)."""
    return {
        "catalog_version": 1,
        "widgets": [_public_row(e, allowed=True) for e in WIDGET_CATALOG],
    }


def apply_entitlements_to_layout_dict(layout: dict[str, Any], profile_id: str, conn) -> dict[str, Any]:
    """
    Setzt enabled=False für Widgets ohne Berechtigung. Mindestens ein Widget bleibt aktiv (welcome).
    """
    out = copy.deepcopy(layout)
    widgets = out.get("widgets") or []
    for w in widgets:
        wid = w.get("id")
        if not wid:
            continue
        if w.get("enabled") and not widget_id_allowed(wid, profile_id, conn):
            w["enabled"] = False
    if not any(w.get("enabled") for w in widgets):
        for w in widgets:
            if w.get("id") == "welcome":
                w["enabled"] = True
                break
    return out

