# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
System Module - Main Module.
Registers system-level RBAC objects (UI, DATA, RESOURCE) that are not part of any feature.
These are global system pages and resources available to all users with appropriate roles.

Also defines the navigation structure for the frontend.
"""

import logging
from typing import Dict, List, Any, Optional

from modules.shared.i18nRegistry import t

logger = logging.getLogger(__name__)

# System metadata
FEATURE_CODE = "system"
FEATURE_LABEL = "System"
FEATURE_ICON = "mdi-cog"

# =============================================================================
# Navigation Structure (Single Source of Truth)
# =============================================================================
# 
# Block Order (gemäss Navigation-API-Konzept):
# - System: 10
# - <dynamic/features>: 15 (wird in routeSystem.py eingefügt)
# - Basisdaten: 30
# - Administration: 200
#
# NOTE: Workflows and Migrate sections removed - now handled as features
#
# Item Order: Default-Abstand 10 pro Item
# uiComponent: Abgeleitet von objectKey (ui.system.home -> page.system.home)
# icon: Wird intern gehalten aber NICHT in der API Response zurückgegeben

NAVIGATION_SECTIONS = [
    # ─── Meine Sicht (with top-level item + subgroups) ───
    {
        "id": "system",
        "title": t("Meine Sicht"),
        "order": 10,
        "items": [
            {
                "id": "home",
                "objectKey": "ui.system.home",
                "label": t("Start"),
                "icon": "FaHome",
                "path": "/",
                "order": 10,
                "public": True,
            },
        ],
        "subgroups": [
            # ── Übersichten ──
            {
                "id": "system-overviews",
                "title": t("Übersichten"),
                "order": 15,
                "items": [
                    {
                        "id": "integrations",
                        "objectKey": "ui.system.integrations",
                        "label": t("Integrationen"),
                        "icon": "FaProjectDiagram",
                        "path": "/integrations",
                        "order": 10,
                        "public": True,
                    },
                    {
                        "id": "compliance-audit",
                        "objectKey": "ui.system.complianceAudit",
                        "label": t("Compliance & Audit"),
                        "icon": "FaShieldAlt",
                        "path": "/compliance-audit",
                        "order": 20,
                    },
                ],
            },
            # ── Basisdaten ──
            {
                "id": "system-basedata",
                "title": t("Basisdaten"),
                "order": 20,
                "items": [
                    {
                        "id": "connections",
                        "objectKey": "ui.system.connections",
                        "label": t("Verbindungen"),
                        "icon": "FaLink",
                        "path": "/basedata/connections",
                        "order": 10,
                        "public": True,
                    },
                    {
                        "id": "files",
                        "objectKey": "ui.system.files",
                        "label": t("Dateien"),
                        "icon": "FaRegFileAlt",
                        "path": "/basedata/files",
                        "order": 20,
                        "public": True,
                    },
                    {
                        "id": "prompts",
                        "objectKey": "ui.system.prompts",
                        "label": t("Prompts"),
                        "icon": "FaLightbulb",
                        "path": "/basedata/prompts",
                        "order": 30,
                        "public": True,
                    },
                ],
            },
            # ── Nutzung ──
            {
                "id": "system-usage",
                "title": t("Nutzung"),
                "order": 30,
                "items": [
                    {
                        "id": "billing-admin",
                        "objectKey": "ui.system.billingAdmin",
                        "label": t("Abrechnung"),
                        "icon": "FaMoneyBillAlt",
                        "path": "/billing/admin",
                        "order": 10,
                    },
                    {
                        "id": "statistics",
                        "objectKey": "ui.system.statistics",
                        "label": t("Statistiken"),
                        "icon": "FaChartBar",
                        "path": "/billing/transactions",
                        "order": 20,
                    },
                    {
                        "id": "automations",
                        "objectKey": "ui.system.automations",
                        "label": t("Automations"),
                        "icon": "FaRobot",
                        "path": "/automations",
                        "order": 30,
                    },
                    {
                        "id": "store",
                        "objectKey": "ui.system.store",
                        "label": t("Store"),
                        "icon": "FaStore",
                        "path": "/store",
                        "order": 40,
                        "public": True,
                    },
                    {
                        "id": "settings",
                        "objectKey": "ui.system.settings",
                        "label": t("Einstellungen"),
                        "icon": "FaCog",
                        "path": "/settings",
                        "order": 50,
                        "public": True,
                    },
                ],
            },
        ],
    },
    # ─── Administration (with subgroups) ───
    {
        "id": "admin",
        "title": t("Administration"),
        "order": 200,
        "subgroups": [
            # ── Wizards ──
            {
                "id": "admin-wizards",
                "title": t("Wizards"),
                "order": 10,
                "items": [
                    {
                        "id": "admin-mandate-wizard",
                        "objectKey": "ui.admin.mandateWizard",
                        "label": t("Mandanten-Wizard"),
                        "icon": "FaMagic",
                        "path": "/admin/mandate-wizard",
                        "order": 10,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-invitation-wizard",
                        "objectKey": "ui.admin.invitationWizard",
                        "label": t("Einladungs-Wizard"),
                        "icon": "FaEnvelopeOpenText",
                        "path": "/admin/invitation-wizard",
                        "order": 20,
                        "adminOnly": True,
                    },
                ],
            },
            # ── Users ──
            {
                "id": "admin-users-group",
                "title": t("Benutzer"),
                "order": 20,
                "items": [
                    {
                        "id": "admin-users",
                        "objectKey": "ui.admin.users",
                        "label": t("Benutzer"),
                        "icon": "FaUsers",
                        "path": "/admin/users",
                        "order": 10,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-invitations",
                        "objectKey": "ui.admin.invitations",
                        "label": t("Benutzer-Einladungen"),
                        "icon": "FaEnvelopeOpenText",
                        "path": "/admin/invitations",
                        "order": 20,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-user-access-overview",
                        "objectKey": "ui.admin.userAccessOverview",
                        "label": t("Benutzer-Zugriffsübersicht"),
                        "icon": "FaClipboardList",
                        "path": "/admin/user-access-overview",
                        "order": 30,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-subscriptions",
                        "objectKey": "ui.admin.subscriptions",
                        "label": t("Abonnements"),
                        "icon": "FaFileContract",
                        "path": "/admin/subscriptions",
                        "order": 40,
                        "adminOnly": True,
                    },
                ],
            },
            # ── System ──
            {
                "id": "admin-system-group",
                "title": t("System"),
                "order": 30,
                "items": [
                    {
                        "id": "admin-roles",
                        "objectKey": "ui.admin.roles",
                        "label": t("Rollen"),
                        "icon": "FaUserTag",
                        "path": "/admin/mandate-roles",
                        "order": 10,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-mandate-role-permissions",
                        "objectKey": "ui.admin.mandateRolePermissions",
                        "label": t("Rollen-Berechtigungen"),
                        "icon": "FaKey",
                        "path": "/admin/mandate-role-permissions",
                        "order": 20,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-mandates",
                        "objectKey": "ui.admin.mandates",
                        "label": t("Mandanten"),
                        "icon": "FaBuilding",
                        "path": "/admin/mandates",
                        "order": 30,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-user-mandates",
                        "objectKey": "ui.admin.userMandates",
                        "label": t("Mandanten-Mitglieder"),
                        "icon": "FaUserFriends",
                        "path": "/admin/user-mandates",
                        "order": 40,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-access",
                        "objectKey": "ui.admin.access",
                        "label": t("Zugriffsverwaltung"),
                        "icon": "FaBuilding",
                        "path": "/admin/access",
                        "order": 50,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-feature-instances",
                        "objectKey": "ui.admin.featureInstances",
                        "label": t("Feature-Instanzen"),
                        "icon": "FaCubes",
                        "path": "/admin/feature-instances",
                        "order": 60,
                        "adminOnly": True,
                    },
                    {
                        "id": "admin-feature-roles",
                        "objectKey": "ui.admin.featureRoles",
                        "label": t("Features Rollen-Vorlagen"),
                        "icon": "FaShieldAlt",
                        "path": "/admin/feature-roles",
                        "order": 70,
                        "adminOnly": True,
                        "sysAdminOnly": True,
                    },
                    {
                        "id": "admin-logs",
                        "objectKey": "ui.admin.logs",
                        "label": t("Logs"),
                        "icon": "FaFileAlt",
                        "path": "/admin/logs",
                        "order": 90,
                        "adminOnly": True,
                        "sysAdminOnly": True,
                    },
                    {
                        "id": "admin-languages",
                        "objectKey": "ui.admin.languages",
                        "label": t("UI-Sprachen"),
                        "icon": "FaGlobe",
                        "path": "/admin/languages",
                        "order": 95,
                        "adminOnly": True,
                        "sysAdminOnly": True,
                    },
                    {
                        "id": "admin-demo-config",
                        "objectKey": "ui.admin.demoConfig",
                        "label": t("Demo Config"),
                        "icon": "FaCubes",
                        "path": "/admin/demo-config",
                        "order": 100,
                        "adminOnly": True,
                        "sysAdminOnly": True,
                    },
                ],
            },
        ],
    },
]


def _objectKeyToUiComponent(objectKey: str) -> str:
    """
    Convert objectKey to uiComponent.
    
    Example: ui.system.home -> page.system.home
             ui.admin.users -> page.admin.users
             ui.feature.trustee.dashboard -> page.feature.trustee.dashboard
    """
    if objectKey.startswith("ui."):
        return "page." + objectKey[3:]
    return objectKey


def _buildUiObjectsFromNavigation() -> List[Dict[str, Any]]:
    """Build UI_OBJECTS list from NAVIGATION_SECTIONS for RBAC registration."""
    uiObjects = []
    for section in NAVIGATION_SECTIONS:
        # Process direct items
        for item in section.get("items", []):
            uiObjects.append({
                "objectKey": item["objectKey"],
                "label": item["label"],
                "meta": {
                    "area": section["id"],
                    "public": item.get("public", False),
                    "adminOnly": item.get("adminOnly", False),
                    "deprecated": item.get("deprecated", False),
                    "path": item["path"],
                    "icon": item["icon"],
                }
            })
        # Process subgroups (nested items within section)
        for subgroup in section.get("subgroups", []):
            for item in subgroup.get("items", []):
                uiObjects.append({
                    "objectKey": item["objectKey"],
                    "label": item["label"],
                    "meta": {
                        "area": section["id"],
                        "subgroup": subgroup["id"],
                        "public": item.get("public", False),
                        "adminOnly": item.get("adminOnly", False),
                        "deprecated": item.get("deprecated", False),
                        "path": item["path"],
                        "icon": item["icon"],
                    }
                })
    return uiObjects


# Generate UI_OBJECTS from navigation structure
UI_OBJECTS = _buildUiObjectsFromNavigation()

# =============================================================================
# System DATA Objects
# =============================================================================
# Namespace structure:
# - data.uam.*        → User Access Management (mandantenübergreifend)
# - data.chat.*       → Chat/AI-Daten (benutzer-eigen, kein Mandantenkontext)
# - data.files.*      → Dateien (benutzer-eigen)
# - data.feature.*    → Mandanten-/Feature-spezifische Daten (dynamisch)
# =============================================================================

DATA_OBJECTS = [
    # UAM (User Access Management) - mandantenübergreifend
    {
        "objectKey": "data.uam.UserInDB",
        "label": "Benutzer",
        "meta": {"table": "UserInDB", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.AuthEvent",
        "label": "Auth-Ereignis",
        "meta": {"table": "AuthEvent", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.UserConnection",
        "label": "Verbindung",
        "meta": {"table": "UserConnection", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.Mandate",
        "label": "Mandant",
        "meta": {"table": "Mandate", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.UserMandate",
        "label": "Benutzer-Mandant",
        "meta": {"table": "UserMandate", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.Invitation",
        "label": "Einladung",
        "meta": {"table": "Invitation", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.Role",
        "label": "Rolle",
        "meta": {"table": "Role", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.AccessRule",
        "label": "Zugriffsregel",
        "meta": {"table": "AccessRule", "namespace": "uam"}
    },
    {
        "objectKey": "data.uam.FeatureInstance",
        "label": "Feature-Instanz",
        "meta": {"table": "FeatureInstance", "namespace": "uam"}
    },
    # Chat - benutzer-eigen, kein Mandantenkontext
    {
        "objectKey": "data.chat.Prompt",
        "label": "Prompt",
        "meta": {"table": "Prompt", "namespace": "chat", "groupDisabled": True}
    },
    {
        "objectKey": "data.chat.ChatWorkflow",
        "label": "Chat-Workflow",
        "meta": {"table": "ChatWorkflow", "namespace": "chat", "groupDisabled": True}
    },
    # Files - benutzer-eigen
    {
        "objectKey": "data.files.FileItem",
        "label": "Datei",
        "meta": {"table": "FileItem", "namespace": "files", "groupDisabled": True}
    },
]

# =============================================================================
# System RESOURCE Objects
# =============================================================================

RESOURCE_OBJECTS = [
    {
        "objectKey": "resource.store.teamsbot",
        "label": "Store: Teams Bot",
        "meta": {"category": "store", "featureCode": "teamsbot"}
    },
    {
        "objectKey": "resource.store.workspace",
        "label": "Store: AI Workspace",
        "meta": {"category": "store", "featureCode": "workspace"}
    },
    {
        "objectKey": "resource.store.commcoach",
        "label": "Store: CommCoach",
        "meta": {"category": "store", "featureCode": "commcoach"}
    },
    {
        "objectKey": "resource.system.api.auth",
        "label": "Authentifizierungs-API",
        "meta": {"endpoint": "/api/auth/*"}
    },
    {
        "objectKey": "resource.system.api.users",
        "label": "Benutzer-API",
        "meta": {"endpoint": "/api/users/*"}
    },
    {
        "objectKey": "resource.system.api.mandates",
        "label": "Mandanten-API",
        "meta": {"endpoint": "/api/mandates/*"}
    },
    {
        "objectKey": "resource.system.api.rbac",
        "label": "RBAC-API",
        "meta": {"endpoint": "/api/rbac/*"}
    },
]


def _discoverAicoreProviderObjects() -> List[Dict[str, Any]]:
    """
    Dynamically discover AICore provider resources for the RBAC catalog.
    Providers are discovered from the model registry at startup.
    """
    providerLabels = {
        "anthropic": "Anthropic (Claude)",
        "openai": "OpenAI (GPT)",
        "mistral": "Mistral (Le Chat)",
        "perplexity": "Perplexity",
        "tavily": "Tavily (Websuche)",
        "privatellm": "Private LLM",
        "internal": "Intern",
    }
    
    try:
        from modules.aicore.aicoreModelRegistry import modelRegistry
        connectors = modelRegistry.discoverConnectors()
        providers = [c.getConnectorType() for c in connectors]
        
        objects = []
        for provider in providers:
            label = providerLabels.get(provider, provider)
            objects.append({
                "objectKey": f"resource.aicore.{provider}",
                "label": label,
                "meta": {"provider": provider, "category": "aicore"}
            })
        
        if objects:
            logger.info(f"Discovered {len(objects)} AICore provider catalog objects: {providers}")
        return objects
        
    except Exception as e:
        logger.warning(f"Failed to discover AICore providers for catalog: {e}")
        return []


def registerFeature(catalogService) -> bool:
    """
    Register system RBAC objects in the catalog.
    
    Args:
        catalogService: The RBAC catalog service instance
        
    Returns:
        True if registration was successful
    """
    try:
        # Register UI objects
        for uiObj in UI_OBJECTS:
            catalogService.registerUiObject(
                featureCode=FEATURE_CODE,
                objectKey=uiObj["objectKey"],
                label=uiObj["label"],
                meta=uiObj.get("meta")
            )
        
        # Register DATA objects
        for dataObj in DATA_OBJECTS:
            catalogService.registerDataObject(
                featureCode=FEATURE_CODE,
                objectKey=dataObj["objectKey"],
                label=dataObj["label"],
                meta=dataObj.get("meta")
            )
        
        # Register RESOURCE objects
        for resObj in RESOURCE_OBJECTS:
            catalogService.registerResourceObject(
                featureCode=FEATURE_CODE,
                objectKey=resObj["objectKey"],
                label=resObj["label"],
                meta=resObj.get("meta")
            )
        
        # Register dynamically discovered AICore provider resources
        aicoreObjects = _discoverAicoreProviderObjects()
        for aicoreObj in aicoreObjects:
            catalogService.registerResourceObject(
                featureCode=FEATURE_CODE,
                objectKey=aicoreObj["objectKey"],
                label=aicoreObj["label"],
                meta=aicoreObj.get("meta")
            )
        
        # Register feature definition
        catalogService.registerFeatureDefinition(
            featureCode=FEATURE_CODE,
            label=FEATURE_LABEL,
            icon=FEATURE_ICON
        )
        
        logger.info(f"Registered system RBAC objects: {len(UI_OBJECTS)} UI, {len(DATA_OBJECTS)} DATA, {len(RESOURCE_OBJECTS)} RESOURCE")
        return True
        
    except Exception as e:
        logger.error(f"Failed to register system RBAC objects: {e}")
        return False
