# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Interface for Workspace feature — manages WorkspaceUserSettings.
Uses a dedicated poweron_workspace database.
"""

import logging
from typing import Dict, Any, Optional

from modules.connectors.connectorDbPostgre import DatabaseConnector
from modules.datamodels.datamodelUam import User
from modules.features.workspace.datamodelFeatureWorkspace import WorkspaceUserSettings
from modules.interfaces.interfaceRbac import getRecordsetWithRBAC
from modules.security.rbac import RbacClass
from modules.shared.configuration import APP_CONFIG

logger = logging.getLogger(__name__)

_workspaceInterfaces: Dict[str, "WorkspaceObjects"] = {}


class WorkspaceObjects:
    """Interface for Workspace-specific database operations (voice + general settings)."""

    def __init__(self, currentUser: User, mandateId: Optional[str] = None, featureInstanceId: Optional[str] = None):
        self.currentUser = currentUser
        self.mandateId = mandateId
        self.featureInstanceId = featureInstanceId
        self.userId = currentUser.id if currentUser else None

        self._initializeDatabase()

        from modules.security.rootAccess import getRootDbAppConnector
        dbApp = getRootDbAppConnector()
        self.rbac = RbacClass(self.db, dbApp=dbApp)

        self.db.updateContext(self.userId)

    def _initializeDatabase(self):
        dbHost = APP_CONFIG.get("DB_HOST", "_no_config_default_data")
        dbDatabase = "poweron_workspace"
        dbUser = APP_CONFIG.get("DB_USER")
        dbPassword = APP_CONFIG.get("DB_PASSWORD_SECRET")
        dbPort = int(APP_CONFIG.get("DB_PORT", 5432))

        self.db = DatabaseConnector(
            dbHost=dbHost,
            dbDatabase=dbDatabase,
            dbUser=dbUser,
            dbPassword=dbPassword,
            dbPort=dbPort,
            userId=self.userId,
        )
        logger.debug(f"Workspace database initialized for user {self.userId}")

    def setUserContext(self, currentUser: User, mandateId: Optional[str] = None, featureInstanceId: Optional[str] = None):
        self.currentUser = currentUser
        self.userId = currentUser.id if currentUser else None
        self.mandateId = mandateId
        self.featureInstanceId = featureInstanceId
        self.db.updateContext(self.userId)

    # =========================================================================
    # WorkspaceUserSettings CRUD
    # =========================================================================

    def getWorkspaceUserSettings(self, userId: Optional[str] = None) -> Optional[WorkspaceUserSettings]:
        targetUserId = userId or self.userId
        if not targetUserId:
            return None

        try:
            recordFilter: Dict[str, Any] = {"userId": targetUserId}
            if self.featureInstanceId:
                recordFilter["featureInstanceId"] = self.featureInstanceId

            records = getRecordsetWithRBAC(
                self.db, WorkspaceUserSettings, self.currentUser,
                recordFilter=recordFilter, mandateId=self.mandateId,
            )
            if not records:
                return None
            return WorkspaceUserSettings(**records[0])

        except Exception as e:
            logger.error(f"Error getting workspace user settings: {e}")
            return None

    def saveWorkspaceUserSettings(self, data: Dict[str, Any]) -> WorkspaceUserSettings:
        """Upsert: create or update workspace user settings for the current user."""
        targetUserId = data.get("userId", self.userId)
        if not targetUserId:
            raise ValueError("No user ID provided")

        existing = self.getWorkspaceUserSettings(targetUserId)
        if existing:
            updateData = {k: v for k, v in data.items() if k not in ("id", "userId", "mandateId", "featureInstanceId")}
            self.db.recordModify(WorkspaceUserSettings, existing.id, updateData)
            updated = self.getWorkspaceUserSettings(targetUserId)
            if not updated:
                raise ValueError("Failed to retrieve updated workspace user settings")
            return updated

        createData = {
            "userId": targetUserId,
            "mandateId": data.get("mandateId", self.mandateId),
            "featureInstanceId": data.get("featureInstanceId", self.featureInstanceId),
        }
        createData.update({k: v for k, v in data.items() if k not in ("id", "userId", "mandateId", "featureInstanceId")})
        createdRecord = self.db.recordCreate(WorkspaceUserSettings, createData)
        if not createdRecord or not createdRecord.get("id"):
            raise ValueError("Failed to create workspace user settings")
        return WorkspaceUserSettings(**createdRecord)


def getInterface(currentUser: Optional[User] = None, mandateId: Optional[str] = None, featureInstanceId: Optional[str] = None) -> WorkspaceObjects:
    if not currentUser:
        raise ValueError("Invalid user context: user is required")

    effectiveMandateId = str(mandateId) if mandateId else None
    effectiveFeatureInstanceId = str(featureInstanceId) if featureInstanceId else None

    contextKey = f"workspace_{effectiveMandateId}_{effectiveFeatureInstanceId}_{currentUser.id}"

    if contextKey not in _workspaceInterfaces:
        _workspaceInterfaces[contextKey] = WorkspaceObjects(currentUser, mandateId=effectiveMandateId, featureInstanceId=effectiveFeatureInstanceId)
    else:
        _workspaceInterfaces[contextKey].setUserContext(currentUser, mandateId=effectiveMandateId, featureInstanceId=effectiveFeatureInstanceId)

    return _workspaceInterfaces[contextKey]
