//! SurrealDB storage backend implementation
//!
//! This module provides a comprehensive SurrealDB-based storage backend that
//! supports both embedded (RocksDB) and server (WebSocket) modes. It leverages
//! SurrealDB's multi-model capabilities including document, graph, and
//! relational features.
//!
//! Note: This implementation is designed for SurrealDB 2.0+ API

use std::collections::HashMap;
use std::sync::Arc;

use async_trait::async_trait;
use chrono::{DateTime, Utc};
use futures::stream::BoxStream;
use serde::{Deserialize, Serialize};
use surrealdb::engine::any::Any;
use surrealdb::opt::auth::Root;
use surrealdb::types::{RecordId, RecordIdKey, SurrealValue};
use surrealdb::Surreal;
use tokio::sync::RwLock;
use tracing::{debug, error, info, warn};
use uuid::Uuid;

use super::traits::{
    AuditEntry, AuthToken, Metric, StorageError, StorageResult, StorageStatistics, TaskEvent,
    TaskEventType, TaskStorage, TimeRange,
};
use crate::{TaskStatus, WorkflowTask};

/// Storage mode configuration for SurrealDB
#[derive(Debug, Clone)]
pub enum StorageMode {
    /// Embedded mode using RocksDB for local storage
    Embedded {
        path: String,
        namespace: String,
        database: String,
    },
    /// Server mode connecting to remote SurrealDB instance
    Server {
        url: String,
        username: String,
        password: String,
        namespace: String,
        database: String,
    },
}

impl StorageMode {
    /// Create embedded mode configuration
    pub fn embedded(path: &str) -> Self {
        Self::Embedded {
            path: path.to_string(),
            namespace: "orchestrator".to_string(),
            database: "tasks".to_string(),
        }
    }

    /// Create server mode configuration
    pub fn server(url: &str, username: &str, password: &str) -> Self {
        Self::Server {
            url: url.to_string(),
            username: username.to_string(),
            password: password.to_string(),
            namespace: "orchestrator".to_string(),
            database: "tasks".to_string(),
        }
    }

    /// Set custom namespace and database
    pub fn with_namespace_db(mut self, namespace: &str, database: &str) -> Self {
        match &mut self {
            StorageMode::Embedded {
                namespace: ns,
                database: db,
                ..
            } => {
                *ns = namespace.to_string();
                *db = database.to_string();
            }
            StorageMode::Server {
                namespace: ns,
                database: db,
                ..
            } => {
                *ns = namespace.to_string();
                *db = database.to_string();
            }
        }
        self
    }
}

/// Configuration for SurrealDB storage
#[derive(Debug, Clone)]
pub struct SurrealConfig {
    pub mode: StorageMode,
    pub connection_timeout: std::time::Duration,
    pub query_timeout: std::time::Duration,
    pub max_connections: usize,
    pub enable_real_time: bool,
    pub enable_audit_logging: bool,
    pub enable_metrics: bool,
}

impl Default for SurrealConfig {
    fn default() -> Self {
        Self {
            mode: StorageMode::embedded("./data/surrealdb"),
            connection_timeout: std::time::Duration::from_secs(30),
            query_timeout: std::time::Duration::from_secs(60),
            max_connections: 10,
            enable_real_time: true,
            enable_audit_logging: true,
            enable_metrics: true,
        }
    }
}

/// Internal task representation for SurrealDB
#[derive(Debug, Clone, Serialize, Deserialize, SurrealValue)]
#[surreal(crate = "surrealdb::types")]
struct SurrealTask {
    #[serde(skip_serializing_if = "Option::is_none")]
    id: Option<RecordId>,
    name: String,
    command: String,
    args: Vec<String>,
    dependencies: Vec<String>,
    status: String,
    priority: i32,
    created_at: DateTime<Utc>,
    updated_at: DateTime<Utc>,
    #[serde(skip_serializing_if = "Option::is_none")]
    started_at: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    completed_at: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    output: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    error: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    created_by: Option<String>,
    retry_count: i32,
    max_retries: i32,
}

impl From<WorkflowTask> for SurrealTask {
    fn from(task: WorkflowTask) -> Self {
        Self {
            id: if task.id.is_empty() {
                None
            } else {
                Some(RecordId::new("tasks", task.id.as_str()))
            },
            name: task.name,
            command: task.command,
            args: task.args,
            dependencies: task.dependencies,
            status: task.status.to_string(),
            priority: 0,
            created_at: task.created_at,
            updated_at: Utc::now(),
            started_at: task.started_at,
            completed_at: task.completed_at,
            output: task.output,
            error: task.error,
            created_by: None,
            retry_count: 0,
            max_retries: 3,
        }
    }
}

impl From<SurrealTask> for WorkflowTask {
    fn from(task: SurrealTask) -> Self {
        Self {
            id: task
                .id
                .map(|r| match r.key {
                    RecordIdKey::String(s) => s,
                    RecordIdKey::Number(n) => n.to_string(),
                    RecordIdKey::Uuid(u) => u.to_string(),
                    _ => Uuid::new_v4().to_string(),
                })
                .unwrap_or_else(|| Uuid::new_v4().to_string()),
            name: task.name,
            command: task.command,
            args: task.args,
            dependencies: task.dependencies,
            status: task.status.parse().unwrap_or(TaskStatus::Pending),
            created_at: task.created_at,
            started_at: task.started_at,
            completed_at: task.completed_at,
            output: task.output,
            error: task.error,
            tags: Default::default(),
        }
    }
}

impl std::fmt::Display for TaskStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            TaskStatus::Pending => write!(f, "Pending"),
            TaskStatus::Running => write!(f, "Running"),
            TaskStatus::Completed => write!(f, "Completed"),
            TaskStatus::Failed => write!(f, "Failed"),
            TaskStatus::Cancelled => write!(f, "Cancelled"),
        }
    }
}

impl std::str::FromStr for TaskStatus {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "Pending" => Ok(TaskStatus::Pending),
            "Running" => Ok(TaskStatus::Running),
            "Completed" => Ok(TaskStatus::Completed),
            "Failed" => Ok(TaskStatus::Failed),
            "Cancelled" => Ok(TaskStatus::Cancelled),
            _ => Err(()),
        }
    }
}

/// SurrealDB storage implementation
pub struct SurrealStorage {
    db: Surreal<Any>,
    config: SurrealConfig,
    start_time: DateTime<Utc>,
    current_user: Arc<RwLock<Option<String>>>,
}

impl SurrealStorage {
    /// Create a new SurrealDB storage instance
    pub fn new(config: SurrealConfig) -> Self {
        Self {
            db: Surreal::init(),
            config,
            start_time: Utc::now(),
            current_user: Arc::new(RwLock::new(None)),
        }
    }

    /// Create storage with embedded mode
    pub fn embedded(path: &str) -> Self {
        Self::new(SurrealConfig {
            mode: StorageMode::embedded(path),
            ..Default::default()
        })
    }

    /// Create storage with server mode
    pub fn server(url: &str, username: &str, password: &str) -> Self {
        Self::new(SurrealConfig {
            mode: StorageMode::server(url, username, password),
            ..Default::default()
        })
    }

    /// Connect to SurrealDB based on configuration
    async fn connect(&self) -> StorageResult<()> {
        match &self.config.mode {
            StorageMode::Embedded {
                path,
                namespace,
                database,
            } => {
                info!("Connecting to embedded SurrealDB at {}", path);
                let connection_string = format!("rocksdb://{}", path);
                self.db.connect(&connection_string).await.map_err(|e| {
                    StorageError::ConnectionFailed {
                        reason: format!("Failed to connect to embedded database: {}", e),
                    }
                })?;

                self.db
                    .use_ns(namespace)
                    .use_db(database)
                    .await
                    .map_err(|e| StorageError::ConnectionFailed {
                        reason: format!("Failed to set namespace/database: {}", e),
                    })?;
            }
            StorageMode::Server {
                url,
                username,
                password,
                namespace,
                database,
            } => {
                info!("Connecting to SurrealDB server at {}", url);
                self.db
                    .connect(url)
                    .await
                    .map_err(|e| StorageError::ConnectionFailed {
                        reason: format!("Failed to connect to server: {}", e),
                    })?;

                self.db
                    .signin(Root {
                        username: username.clone(),
                        password: password.clone(),
                    })
                    .await
                    .map_err(|e| StorageError::AuthenticationFailed {
                        reason: format!("Authentication failed: {}", e),
                    })?;

                self.db
                    .use_ns(namespace)
                    .use_db(database)
                    .await
                    .map_err(|e| StorageError::ConnectionFailed {
                        reason: format!("Failed to set namespace/database: {}", e),
                    })?;
            }
        }

        info!("Successfully connected to SurrealDB");
        Ok(())
    }

    /// Initialize database schema
    async fn init_schema(&self) -> StorageResult<()> {
        info!("Initializing database schema");

        // Create tables
        let schema_queries = vec![
            // Tasks table
            r#"
                DEFINE TABLE tasks SCHEMAFULL;
                DEFINE FIELD name ON TABLE tasks TYPE string;
                DEFINE FIELD command ON TABLE tasks TYPE string;
                DEFINE FIELD args ON TABLE tasks TYPE array<string> DEFAULT [];
                DEFINE FIELD dependencies ON TABLE tasks TYPE array<string> DEFAULT [];
                DEFINE FIELD status ON TABLE tasks TYPE string DEFAULT "Pending";
                DEFINE FIELD priority ON TABLE tasks TYPE int DEFAULT 0;
                DEFINE FIELD created_at ON TABLE tasks TYPE datetime DEFAULT time::now();
                DEFINE FIELD updated_at ON TABLE tasks TYPE datetime DEFAULT time::now();
                DEFINE FIELD started_at ON TABLE tasks TYPE datetime;
                DEFINE FIELD completed_at ON TABLE tasks TYPE datetime;
                DEFINE FIELD output ON TABLE tasks TYPE string;
                DEFINE FIELD error ON TABLE tasks TYPE string;
                DEFINE FIELD created_by ON TABLE tasks TYPE string;
                DEFINE FIELD retry_count ON TABLE tasks TYPE int DEFAULT 0;
                DEFINE FIELD max_retries ON TABLE tasks TYPE int DEFAULT 3;
                DEFINE INDEX tasks_status_idx ON TABLE tasks COLUMNS status;
                DEFINE INDEX tasks_priority_idx ON TABLE tasks COLUMNS priority;
            "#,
            // Task queue table
            r#"
                DEFINE TABLE task_queue SCHEMAFULL;
                DEFINE FIELD task_id ON TABLE task_queue TYPE string;
                DEFINE FIELD priority ON TABLE task_queue TYPE int DEFAULT 0;
                DEFINE FIELD enqueued_at ON TABLE task_queue TYPE datetime DEFAULT time::now();
                DEFINE INDEX queue_priority_idx ON TABLE task_queue COLUMNS priority DESC, enqueued_at ASC;
            "#,
            // Audit log table
            r#"
                DEFINE TABLE audit_log SCHEMAFULL;
                DEFINE FIELD task_id ON TABLE audit_log TYPE string;
                DEFINE FIELD operation ON TABLE audit_log TYPE string;
                DEFINE FIELD old_status ON TABLE audit_log TYPE string;
                DEFINE FIELD new_status ON TABLE audit_log TYPE string;
                DEFINE FIELD user_id ON TABLE audit_log TYPE string;
                DEFINE FIELD timestamp ON TABLE audit_log TYPE datetime DEFAULT time::now();
                DEFINE FIELD metadata ON TABLE audit_log TYPE object DEFAULT {};
                DEFINE INDEX audit_timestamp_idx ON TABLE audit_log COLUMNS timestamp;
            "#,
            // Metrics table
            r#"
                DEFINE TABLE metrics SCHEMAFULL;
                DEFINE FIELD name ON TABLE metrics TYPE string;
                DEFINE FIELD value ON TABLE metrics TYPE float;
                DEFINE FIELD tags ON TABLE metrics TYPE object DEFAULT {};
                DEFINE FIELD timestamp ON TABLE metrics TYPE datetime DEFAULT time::now();
                DEFINE INDEX metrics_timestamp_idx ON TABLE metrics COLUMNS timestamp;
            "#,
        ];

        for schema in schema_queries {
            if let Err(e) = self.db.query(schema).await {
                warn!("Schema creation warning (may be expected): {}", e);
            }
        }

        info!("Database schema initialization completed");
        Ok(())
    }

    /// Record an audit entry if audit logging is enabled
    async fn record_audit_if_enabled(&self, entry: AuditEntry) -> StorageResult<()> {
        if !self.config.enable_audit_logging {
            return Ok(());
        }

        self.record_audit_entry(entry).await
    }

    /// Record a metric if metrics are enabled
    async fn record_metric_if_enabled(&self, metric: Metric) -> StorageResult<()> {
        if !self.config.enable_metrics {
            return Ok(());
        }

        self.record_metric(metric).await
    }

    /// Publish an event if real-time is enabled
    async fn publish_event_if_enabled(&self, event: TaskEvent) -> StorageResult<()> {
        if !self.config.enable_real_time {
            return Ok(());
        }

        self.publish_event(event).await
    }

    /// Get current authenticated user
    async fn get_current_user(&self) -> Option<String> {
        self.current_user.read().await.clone()
    }

    /// Set current authenticated user
    async fn set_current_user(&self, user: Option<String>) {
        *self.current_user.write().await = user;
    }
}

#[async_trait]
impl TaskStorage for SurrealStorage {
    async fn init(&self) -> StorageResult<()> {
        self.connect().await?;
        self.init_schema().await?;

        // Record initialization metric
        self.record_metric_if_enabled(Metric::counter("storage.initialized", 1.0))
            .await?;

        info!("SurrealDB storage initialized successfully");
        Ok(())
    }

    async fn health_check(&self) -> StorageResult<bool> {
        match self.db.health().await {
            Ok(_) => {
                debug!("Health check passed");
                Ok(true)
            }
            Err(e) => {
                error!("Health check failed: {}", e);
                Ok(false)
            }
        }
    }

    async fn enqueue(&self, task: WorkflowTask, priority: u8) -> StorageResult<()> {
        let task_id = if task.id.is_empty() {
            Uuid::new_v4().to_string()
        } else {
            task.id.clone()
        };

        let mut surreal_task = SurrealTask::from(task.clone());
        surreal_task.priority = priority as i32;
        surreal_task.id = Some(RecordId::new("tasks", task_id.as_str()));

        if let Some(user) = self.get_current_user().await {
            surreal_task.created_by = Some(user);
        }

        // Create task
        let _: Option<SurrealTask> = self
            .db
            .create("tasks")
            .content(surreal_task)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        // Add to queue
        let queue_entry = serde_json::json!({
            "task_id": task_id,
            "priority": priority as i32,
            "enqueued_at": Utc::now(),
        });

        let _: Option<serde_json::Value> = self
            .db
            .create("task_queue")
            .content(queue_entry)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        // Record audit entry
        let audit_entry = AuditEntry::task_created(task_id.clone(), self.get_current_user().await);
        self.record_audit_if_enabled(audit_entry).await?;

        // Publish event
        let event = TaskEvent {
            event_type: TaskEventType::Enqueued,
            task_id: task_id.clone(),
            task: Some(task),
            timestamp: Utc::now(),
            metadata: HashMap::new(),
        };
        self.publish_event_if_enabled(event).await?;

        // Record metric
        self.record_metric_if_enabled(
            Metric::counter("tasks.enqueued", 1.0).with_tag("priority", &priority.to_string()),
        )
        .await?;

        info!("Task enqueued: {} with priority {}", task_id, priority);
        Ok(())
    }

    async fn dequeue(&self) -> StorageResult<Option<WorkflowTask>> {
        // Get highest priority task from queue
        let query = r#"
            SELECT * FROM task_queue
            ORDER BY priority DESC, enqueued_at ASC
            LIMIT 1
        "#;

        let mut result = self
            .db
            .query(query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let queue_items: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        if queue_items.is_empty() {
            return Ok(None);
        }

        // Extract task_id from queue item (simplified approach)
        let queue_item_json = queue_items[0].clone();
        let task_id = queue_item_json
            .get("task_id")
            .and_then(|v| v.as_str())
            .ok_or_else(|| StorageError::BackendError(anyhow::anyhow!("No task_id in queue")))?
            .to_string();

        let queue_id = queue_item_json
            .get("id")
            .and_then(|v| v.as_str())
            .ok_or_else(|| StorageError::BackendError(anyhow::anyhow!("No queue ID")))?
            .to_string();

        // Get the actual task
        let task: Option<SurrealTask> = self
            .db
            .select(("tasks", task_id.as_str()))
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let task = match task {
            Some(task) => task,
            None => {
                // Clean up orphaned queue entry
                let _: Option<serde_json::Value> = self
                    .db
                    .delete(("task_queue", queue_id.as_str()))
                    .await
                    .map_err(|e| StorageError::BackendError(e.into()))?;
                return Ok(None);
            }
        };

        // Remove from queue
        let _: Option<serde_json::Value> = self
            .db
            .delete(("task_queue", queue_id.as_str()))
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let workflow_task = WorkflowTask::from(task);

        // Record metric
        self.record_metric_if_enabled(Metric::counter("tasks.dequeued", 1.0))
            .await?;

        info!("Task dequeued: {}", workflow_task.id);
        Ok(Some(workflow_task))
    }

    async fn peek(&self) -> StorageResult<Option<WorkflowTask>> {
        let query = r#"
            SELECT task_id FROM task_queue
            ORDER BY priority DESC, enqueued_at ASC
            LIMIT 1
        "#;

        let mut result = self
            .db
            .query(query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let queue_items: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        if queue_items.is_empty() {
            return Ok(None);
        }

        let queue_item_json = queue_items[0].clone();
        let task_id = queue_item_json
            .get("task_id")
            .and_then(|v| v.as_str())
            .ok_or_else(|| StorageError::BackendError(anyhow::anyhow!("No task_id in queue")))?
            .to_string();

        let task: Option<SurrealTask> = self
            .db
            .select(("tasks", task_id.as_str()))
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        Ok(task.map(WorkflowTask::from))
    }

    async fn get_task(&self, id: &str) -> StorageResult<Option<WorkflowTask>> {
        let task: Option<SurrealTask> = self
            .db
            .select(("tasks", id))
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        Ok(task.map(WorkflowTask::from))
    }

    async fn update_task(&self, task: WorkflowTask) -> StorageResult<()> {
        let mut surreal_task = SurrealTask::from(task.clone());
        surreal_task.updated_at = Utc::now();

        let _: Option<SurrealTask> = self
            .db
            .update(("tasks", task.id.as_str()))
            .content(surreal_task)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        info!("Task updated: {}", task.id);
        Ok(())
    }

    async fn update_task_status(&self, id: &str, status: TaskStatus) -> StorageResult<()> {
        let update_data = serde_json::json!({
            "status": status.to_string(),
            "updated_at": Utc::now(),
        });

        let _: Option<serde_json::Value> = self
            .db
            .update(("tasks", id))
            .merge(update_data)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        info!("Task status updated: {} -> {}", id, status.to_string());
        Ok(())
    }

    async fn list_tasks(
        &self,
        status_filter: Option<TaskStatus>,
    ) -> StorageResult<Vec<WorkflowTask>> {
        let query = match status_filter {
            Some(status) => {
                format!(
                    "SELECT * FROM tasks WHERE status = '{}' ORDER BY created_at DESC",
                    status
                )
            }
            None => "SELECT * FROM tasks ORDER BY created_at DESC".to_string(),
        };

        let mut result = self
            .db
            .query(&query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let tasks: Vec<SurrealTask> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        Ok(tasks.into_iter().map(WorkflowTask::from).collect())
    }

    async fn requeue_failed_task(&self, id: &str) -> StorageResult<bool> {
        // Get the task
        let task: Option<SurrealTask> = self
            .db
            .select(("tasks", id))
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let mut task = match task {
            Some(task) if task.status == "Failed" => task,
            Some(_) => return Ok(false), // Task is not failed
            None => return Err(StorageError::TaskNotFound { id: id.to_string() }),
        };

        // Check retry limits
        if task.retry_count >= task.max_retries {
            return Ok(false);
        }

        // Update task status and retry count
        task.status = "Pending".to_string();
        task.retry_count += 1;
        task.updated_at = Utc::now();
        task.error = None;

        let _: Option<SurrealTask> = self
            .db
            .update(("tasks", id))
            .content(task.clone())
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        // Add back to queue with original priority
        let queue_entry = serde_json::json!({
            "task_id": id,
            "priority": task.priority,
            "enqueued_at": Utc::now(),
        });

        let _: Option<serde_json::Value> = self
            .db
            .create("task_queue")
            .content(queue_entry)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        info!("Failed task requeued: {} (retry {})", id, task.retry_count);
        Ok(true)
    }

    async fn queue_size(&self) -> StorageResult<usize> {
        let query = "SELECT count() FROM task_queue GROUP ALL";
        let mut result = self
            .db
            .query(query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let counts: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let count_json = counts
            .first()
            .cloned()
            .unwrap_or_default();

        let count = count_json
            .get("count")
            .and_then(|v| v.as_u64())
            .unwrap_or(0) as usize;

        Ok(count)
    }

    async fn total_tasks(&self) -> StorageResult<usize> {
        let query = "SELECT count() FROM tasks GROUP ALL";
        let mut result = self
            .db
            .query(query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let counts: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let count_json = counts
            .first()
            .cloned()
            .unwrap_or_default();

        let count = count_json
            .get("count")
            .and_then(|v| v.as_u64())
            .unwrap_or(0) as usize;

        Ok(count)
    }

    async fn cleanup_completed_tasks(&self, older_than: chrono::Duration) -> StorageResult<usize> {
        let cutoff_time = Utc::now() - older_than;

        let query = format!(
            "DELETE tasks WHERE status = 'Completed' AND completed_at < '{}'",
            cutoff_time.to_rfc3339()
        );

        let mut result = self
            .db
            .query(&query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let deleted: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let deleted_count = deleted.len();

        info!(
            "Cleaned up {} completed tasks older than {:?}",
            deleted_count, older_than
        );
        Ok(deleted_count)
    }

    async fn get_audit_log(&self, time_range: TimeRange) -> StorageResult<Vec<AuditEntry>> {
        let query = format!(
            "SELECT * FROM audit_log WHERE timestamp >= '{}' AND timestamp <= '{}' ORDER BY \
             timestamp DESC",
            time_range.start.to_rfc3339(),
            time_range.end.to_rfc3339()
        );

        let mut result = self
            .db
            .query(&query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let entries: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let mut audit_entries = Vec::new();
        for entry in entries {
            if let Ok(audit_entry) = serde_json::from_value::<AuditEntry>(entry) {
                audit_entries.push(audit_entry);
            }
        }

        Ok(audit_entries)
    }

    async fn record_audit_entry(&self, entry: AuditEntry) -> StorageResult<()> {
        let entry_data = serde_json::to_value(&entry).map_err(StorageError::SerializationError)?;

        let _: Option<serde_json::Value> = self
            .db
            .create("audit_log")
            .content(entry_data)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        debug!("Recorded audit entry: {}", entry.operation);
        Ok(())
    }

    async fn get_metrics(&self, time_range: TimeRange) -> StorageResult<Vec<Metric>> {
        let query = format!(
            "SELECT * FROM metrics WHERE timestamp >= '{}' AND timestamp <= '{}' ORDER BY \
             timestamp DESC",
            time_range.start.to_rfc3339(),
            time_range.end.to_rfc3339()
        );

        let mut result = self
            .db
            .query(&query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let entries: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let mut metrics = Vec::new();
        for entry in entries {
            if let Ok(metric) = serde_json::from_value::<Metric>(entry) {
                metrics.push(metric);
            }
        }

        Ok(metrics)
    }

    async fn record_metric(&self, metric: Metric) -> StorageResult<()> {
        let metric_data =
            serde_json::to_value(&metric).map_err(StorageError::SerializationError)?;

        let _: Option<serde_json::Value> = self
            .db
            .create("metrics")
            .content(metric_data)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        debug!("Recorded metric: {} = {}", metric.name, metric.value);
        Ok(())
    }

    async fn authenticate(&self, username: &str, password: &str) -> StorageResult<AuthToken> {
        // Simplified authentication for demonstration
        // In a real implementation, you would store users in the database
        if username == "admin" && password == "admin123" {
            let token = AuthToken {
                token: Uuid::new_v4().to_string(),
                user_id: "admin".to_string(),
                expires_at: Utc::now() + chrono::Duration::hours(24),
                permissions: vec!["task:*".to_string()],
            };

            self.set_current_user(Some("admin".to_string())).await;
            info!("User authenticated: {}", username);
            Ok(token)
        } else {
            Err(StorageError::AuthenticationFailed {
                reason: "Invalid credentials".to_string(),
            })
        }
    }

    async fn validate_token(&self, _token: &str) -> StorageResult<Option<AuthToken>> {
        // Simplified token validation
        // In a real implementation, you would store tokens in the database
        Ok(None)
    }

    async fn subscribe_to_events(
        &self,
        _filters: Option<Vec<TaskEventType>>,
    ) -> StorageResult<BoxStream<'_, TaskEvent>> {
        // Real-time subscriptions placeholder
        // SurrealDB 2.0 has different LIVE query API
        use futures::stream;

        warn!("Real-time subscriptions not fully implemented for SurrealDB 2.0");
        let empty_stream = stream::empty::<TaskEvent>();
        Ok(Box::pin(empty_stream))
    }

    async fn publish_event(&self, event: TaskEvent) -> StorageResult<()> {
        let event_data = serde_json::to_value(&event).map_err(StorageError::SerializationError)?;

        let _: Option<serde_json::Value> = self
            .db
            .create("task_events")
            .content(event_data)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        debug!(
            "Published event: {:?} for task {}",
            event.event_type, event.task_id
        );
        Ok(())
    }

    async fn search_tasks(
        &self,
        name_pattern: Option<String>,
        status_filter: Option<Vec<TaskStatus>>,
        created_after: Option<DateTime<Utc>>,
        created_before: Option<DateTime<Utc>>,
        limit: Option<usize>,
        offset: Option<usize>,
    ) -> StorageResult<Vec<WorkflowTask>> {
        let mut conditions = Vec::new();

        if let Some(pattern) = name_pattern {
            conditions.push(format!("string::contains(name, '{}')", pattern));
        }

        if let Some(statuses) = status_filter {
            let status_strings: Vec<String> = statuses.iter().map(|s| format!("'{}'", s)).collect();
            conditions.push(format!("status IN [{}]", status_strings.join(",")));
        }

        if let Some(after) = created_after {
            conditions.push(format!("created_at >= '{}'", after.to_rfc3339()));
        }

        if let Some(before) = created_before {
            conditions.push(format!("created_at <= '{}'", before.to_rfc3339()));
        }

        let mut query = "SELECT * FROM tasks".to_string();
        if !conditions.is_empty() {
            query.push_str(&format!(" WHERE {}", conditions.join(" AND ")));
        }
        query.push_str(" ORDER BY created_at DESC");

        if let Some(limit) = limit {
            query.push_str(&format!(" LIMIT {}", limit));
        }

        if let Some(offset) = offset {
            query.push_str(&format!(" START {}", offset));
        }

        let mut result = self
            .db
            .query(&query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let tasks: Vec<SurrealTask> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        Ok(tasks.into_iter().map(WorkflowTask::from).collect())
    }

    async fn get_task_dependencies(&self, task_id: &str) -> StorageResult<Vec<String>> {
        // Get dependencies from the task's dependencies field
        let task: Option<SurrealTask> = self
            .db
            .select(("tasks", task_id))
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        Ok(task.map(|t| t.dependencies).unwrap_or_default())
    }

    async fn get_dependent_tasks(&self, task_id: &str) -> StorageResult<Vec<String>> {
        // Find tasks that depend on this task
        let query = format!(
            "SELECT id FROM tasks WHERE string::contains(dependencies, '{}')",
            task_id
        );

        let mut result = self
            .db
            .query(&query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let tasks: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let deps: Vec<String> = tasks
            .into_iter()
            .filter_map(|v| {
                let json = v;
                json.get("id").and_then(|id| id.as_str()).map(String::from)
            })
            .collect();

        Ok(deps)
    }

    async fn create_backup(&self, backup_path: &str) -> StorageResult<()> {
        // Backup implementation would depend on the deployment mode
        warn!(
            "Backup functionality not yet implemented for path: {}",
            backup_path
        );
        Ok(())
    }

    async fn restore_from_backup(&self, backup_path: &str) -> StorageResult<()> {
        // Restore implementation
        warn!(
            "Restore functionality not yet implemented for path: {}",
            backup_path
        );
        Ok(())
    }

    async fn get_statistics(&self) -> StorageResult<StorageStatistics> {
        // Get task counts by status
        let queries = vec![
            ("total", "SELECT count() FROM tasks GROUP ALL"),
            (
                "pending",
                "SELECT count() FROM tasks WHERE status = 'Pending' GROUP ALL",
            ),
            (
                "running",
                "SELECT count() FROM tasks WHERE status = 'Running' GROUP ALL",
            ),
            (
                "completed",
                "SELECT count() FROM tasks WHERE status = 'Completed' GROUP ALL",
            ),
            (
                "failed",
                "SELECT count() FROM tasks WHERE status = 'Failed' GROUP ALL",
            ),
        ];

        let mut stats = StorageStatistics::new();
        stats.uptime = Utc::now() - self.start_time;

        for (stat_name, query) in queries {
            let mut result = self
                .db
                .query(query)
                .await
                .map_err(|e| StorageError::BackendError(e.into()))?;

            let counts: Vec<serde_json::Value> = result
                .take(0)
                .map_err(|e| StorageError::BackendError(e.into()))?;

            let count_json = counts
                .first()
                .cloned()
                .unwrap_or_default();

            let count = count_json
                .get("count")
                .and_then(|v| v.as_u64())
                .unwrap_or(0) as usize;

            match stat_name {
                "total" => stats.total_tasks = count,
                "pending" => stats.pending_tasks = count,
                "running" => stats.running_tasks = count,
                "completed" => stats.completed_tasks = count,
                "failed" => stats.failed_tasks = count,
                _ => {}
            }
        }

        Ok(stats)
    }
}

// Helper implementations for better ergonomics
impl SurrealStorage {
    /// Create a new task with dependencies
    pub async fn create_task_with_dependencies(
        &self,
        task: WorkflowTask,
        dependencies: Vec<String>,
    ) -> StorageResult<String> {
        let task_id = if task.id.is_empty() {
            Uuid::new_v4().to_string()
        } else {
            task.id.clone()
        };

        let mut surreal_task = SurrealTask::from(task);
        surreal_task.dependencies = dependencies;
        surreal_task.id = Some(RecordId::new("tasks", task_id.as_str()));

        if let Some(user) = self.get_current_user().await {
            surreal_task.created_by = Some(user);
        }

        let _: Option<SurrealTask> = self
            .db
            .create("tasks")
            .content(surreal_task)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        Ok(task_id)
    }

    /// Get tasks ready to run (no pending dependencies)
    pub async fn get_ready_tasks(&self) -> StorageResult<Vec<WorkflowTask>> {
        // Simplified implementation - check if dependencies are all completed
        let query =
            "SELECT * FROM tasks WHERE status = 'Pending' ORDER BY priority DESC, created_at ASC";

        let mut result = self
            .db
            .query(query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let tasks: Vec<SurrealTask> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        // Filter tasks with satisfied dependencies
        let mut ready_tasks = Vec::new();
        for task in tasks {
            let mut all_deps_complete = true;

            for dep_id in &task.dependencies {
                if let Ok(Some(dep_task)) = self.get_task(dep_id).await {
                    if dep_task.status != TaskStatus::Completed {
                        all_deps_complete = false;
                        break;
                    }
                }
            }

            if all_deps_complete {
                ready_tasks.push(WorkflowTask::from(task));
            }
        }

        Ok(ready_tasks)
    }

    /// Get task execution metrics
    pub async fn get_task_execution_metrics(&self) -> StorageResult<HashMap<String, f64>> {
        let mut result_map = HashMap::new();

        // Calculate average execution time
        let exec_time_query = r#"
            SELECT math::mean(completed_at - started_at) AS avg_time
            FROM tasks
            WHERE status = 'Completed' AND started_at IS NOT NONE AND completed_at IS NOT NONE
            GROUP ALL
        "#;

        let mut result = self
            .db
            .query(exec_time_query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let avg_times: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        if let Some(avg_time_json) = avg_times.first().cloned() {
            if let Some(avg_time) = avg_time_json.get("avg_time").and_then(|v| v.as_f64()) {
                result_map.insert("avg_execution_time_seconds".to_string(), avg_time);
            }
        }

        // Calculate success rate
        let success_rate_query = r#"
            SELECT
                (count(status = 'Completed') / count()) * 100 AS success_rate
            FROM tasks
            WHERE status IN ['Completed', 'Failed']
            GROUP ALL
        "#;

        let mut result = self
            .db
            .query(success_rate_query)
            .await
            .map_err(|e| StorageError::BackendError(e.into()))?;

        let success_rates: Vec<serde_json::Value> = result
            .take(0)
            .map_err(|e| StorageError::BackendError(e.into()))?;

        if let Some(success_rate_json) = success_rates.first().cloned() {
            if let Some(success_rate) = success_rate_json
                .get("success_rate")
                .and_then(|v| v.as_f64())
            {
                result_map.insert("success_rate_percent".to_string(), success_rate);
            }
        }

        Ok(result_map)
    }
}
