use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use surrealdb::types::{RecordId, SurrealValue};
use uuid::Uuid;
use validator::Validate;

/// Permission model for fine-grained access control
#[derive(Debug, Clone, Serialize, Deserialize, SurrealValue)]
#[surreal(crate = "surrealdb::types")]
pub struct Permission {
    pub id: Option<RecordId>,
    pub permission_id: Uuid,
    pub name: String,
    pub resource: String,
    pub action: String,
    pub description: Option<String>,
    pub created_at: DateTime<Utc>,
}

/// Permission response
#[derive(Debug, Serialize)]
pub struct PermissionResponse {
    pub id: Uuid,
    pub name: String,
    pub resource: String,
    pub action: String,
    pub description: Option<String>,
    pub created_at: DateTime<Utc>,
}

impl From<Permission> for PermissionResponse {
    fn from(permission: Permission) -> Self {
        Self {
            id: permission.permission_id,
            name: permission.name,
            resource: permission.resource,
            action: permission.action,
            description: permission.description,
            created_at: permission.created_at,
        }
    }
}

impl Permission {
    /// Create a new permission
    pub fn new(
        name: String,
        resource: String,
        action: String,
        description: Option<String>,
    ) -> Self {
        Self {
            id: None,
            permission_id: Uuid::new_v4(),
            name,
            resource,
            action,
            description,
            created_at: Utc::now(),
        }
    }

    /// Create system permissions (called during initialization)
    pub fn create_system_permissions() -> Vec<Self> {
        vec![
            // User permissions
            Self::new(
                "users:read".to_string(),
                "users".to_string(),
                "read".to_string(),
                Some("Read user information".to_string()),
            ),
            Self::new(
                "users:write".to_string(),
                "users".to_string(),
                "write".to_string(),
                Some("Create and update users".to_string()),
            ),
            Self::new(
                "users:delete".to_string(),
                "users".to_string(),
                "delete".to_string(),
                Some("Delete users".to_string()),
            ),
            // Role permissions
            Self::new(
                "roles:read".to_string(),
                "roles".to_string(),
                "read".to_string(),
                Some("Read role information".to_string()),
            ),
            Self::new(
                "roles:write".to_string(),
                "roles".to_string(),
                "write".to_string(),
                Some("Create and update roles".to_string()),
            ),
            Self::new(
                "roles:delete".to_string(),
                "roles".to_string(),
                "delete".to_string(),
                Some("Delete roles".to_string()),
            ),
            // Permission permissions
            Self::new(
                "permissions:read".to_string(),
                "permissions".to_string(),
                "read".to_string(),
                Some("Read permission information".to_string()),
            ),
            // Profile permissions
            Self::new(
                "profile:read".to_string(),
                "profile".to_string(),
                "read".to_string(),
                Some("Read own profile".to_string()),
            ),
            Self::new(
                "profile:write".to_string(),
                "profile".to_string(),
                "write".to_string(),
                Some("Update own profile".to_string()),
            ),
            // System permissions
            Self::new(
                "system:manage".to_string(),
                "system".to_string(),
                "manage".to_string(),
                Some("Full system management access".to_string()),
            ),
            Self::new(
                "system:read".to_string(),
                "system".to_string(),
                "read".to_string(),
                Some("Read system information".to_string()),
            ),
        ]
    }
}

/// Permission check request
#[derive(Debug, Validate, Deserialize)]
pub struct PermissionCheckRequest {
    #[validate(length(min = 1))]
    pub resource: String,
    #[validate(length(min = 1))]
    pub action: String,
}
