use crate::AppService;
use crate::error::AppError;
use models::WorkspaceRole;
use models::workspaces::workspace;
use models::workspaces::workspace_membership;

use sea_orm::*;
use session::Session;
use uuid::Uuid;

impl AppService {
    pub async fn utils_find_workspace_by_slug(
        &self,
        slug: String,
    ) -> Result<workspace::Model, AppError> {
        workspace::Entity::find()
            .filter(workspace::Column::Slug.eq(slug))
            .filter(workspace::Column::DeletedAt.is_null())
            .one(&self.db)
            .await?
            .ok_or(AppError::WorkspaceNotFound)
    }

    pub async fn utils_find_workspace_by_id(&self, id: Uuid) -> Result<workspace::Model, AppError> {
        workspace::Entity::find_by_id(id)
            .filter(workspace::Column::DeletedAt.is_null())
            .one(&self.db)
            .await?
            .ok_or(AppError::WorkspaceNotFound)
    }

    pub async fn utils_workspace_context_role(
        &self,
        ctx: &Session,
        workspace_slug: String,
    ) -> Result<WorkspaceRole, AppError> {
        let user_uid = ctx.user().ok_or(AppError::Unauthorized)?;
        let ws = self.utils_find_workspace_by_slug(workspace_slug).await?;
        let membership = workspace_membership::Entity::find()
            .filter(workspace_membership::Column::WorkspaceId.eq(ws.id))
            .filter(workspace_membership::Column::UserId.eq(user_uid))
            .filter(workspace_membership::Column::Status.eq("active"))
            .one(&self.db)
            .await?;
        match membership {
            Some(m) => m.role.parse().map_err(|_| AppError::RoleParseError),
            None => Err(AppError::NotWorkspaceMember),
        }
    }

    pub async fn utils_check_workspace_permission(
        &self,
        workspace_id: Uuid,
        user_id: Uuid,
        required_roles: &[WorkspaceRole],
    ) -> Result<(), AppError> {
        let membership = workspace_membership::Entity::find()
            .filter(workspace_membership::Column::WorkspaceId.eq(workspace_id))
            .filter(workspace_membership::Column::UserId.eq(user_id))
            .filter(workspace_membership::Column::Status.eq("active"))
            .one(&self.db)
            .await?;

        if let Some(member) = membership {
            for role in required_roles {
                if member.role.parse::<WorkspaceRole>() == Ok(role.clone()) {
                    return Ok(());
                }
            }
        }

        Err(AppError::PermissionDenied)
    }
}
