from sqlalchemy.orm import Session

from app.core.exceptions import AppException
from app.core.permissions import add_permission_for_role
from app.models.role import Role
from app.models.role_permission import RolePermission
from common_logging import get_logger, log_execution

logger = get_logger(__name__)


class PermissionTemplateService:
    VALID_RESOURCES = [
        "users",
        "roles",
        "knowledge_bases",
        "knowledge_categories",
        "knowledge_tags",
        "agents",
        "workflows",
        "documents",
        "audit_logs",
        "menus",
        "providers",
        "models",
    ]
    VALID_ACTIONS = ["read", "create", "update", "delete", "execute", "view"]

    @staticmethod
    def export_role_permissions(db: Session, role_id: int, tenant_id: int) -> dict:
        role = db.query(Role).filter(Role.id == role_id).first()
        if not role:
            raise AppException("角色不存在", "Role not found")
        permissions = (
            db.query(RolePermission)
            .filter(RolePermission.role_id == role_id, not RolePermission.is_deleted)
            .all()
        )
        return {
            "role_name": role.name,
            "role_code": role.code,
            "tenant_id": tenant_id,
            "permissions": [
                {"resource": perm.resource, "action": perm.action} for perm in permissions
            ],
        }

    @staticmethod
    @log_execution
    def import_role_permissions(
        db: Session, role_id: int, tenant_id: int, config: dict, replace: bool = False
    ) -> bool:
        role = db.query(Role).filter(Role.id == role_id).first()
        if not role:
            raise AppException("角色不存在", "Role not found")
        if role.is_system:
            raise AppException("系统角色权限不可修改", "System role permissions cannot be modified")
        for perm in config.get("permissions", []):
            resource = perm.get("resource")
            action = perm.get("action")
            if not resource or not action:
                raise AppException("权限配置格式错误", "Invalid permission format")
            if not resource.startswith("menu:"):
                if resource not in PermissionTemplateService.VALID_RESOURCES:
                    raise AppException(f"无效的资源: {resource}", f"Invalid resource: {resource}")
                if action not in PermissionTemplateService.VALID_ACTIONS:
                    raise AppException(f"无效的操作: {action}", f"Invalid action: {action}")
        if replace:
            db.query(RolePermission).filter(RolePermission.role_id == role_id).delete()
        for perm in config.get("permissions", []):
            resource = perm.get("resource")
            action = perm.get("action")
            existing = (
                db.query(RolePermission)
                .filter(
                    RolePermission.role_id == role_id,
                    RolePermission.resource == resource,
                    RolePermission.action == action,
                    not RolePermission.is_deleted,
                )
                .first()
            )
            if existing:
                continue
            role_perm = RolePermission(
                role_id=role_id, resource=resource, action=action, tenant_id=tenant_id
            )
            db.add(role_perm)
            add_permission_for_role(f"role:{role.code}", tenant_id, resource, action)
        db.commit()
        logger.info(f"Imported {len(config.get('permissions', []))} permissions for role {role_id}")
        return True

    @staticmethod
    def copy_permissions(db: Session, from_role_id: int, to_role_id: int, tenant_id: int) -> bool:
        config = PermissionTemplateService.export_role_permissions(db, from_role_id, tenant_id)
        return PermissionTemplateService.import_role_permissions(
            db, to_role_id, tenant_id, config, replace=False
        )
