use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

/// Persistent state for an in-flight op tracked in SurrealDB.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InFlightOp {
    pub jti: String,
    pub op_type: String,
    pub target: String,
    pub state: OpState,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub error: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum OpState {
    Pending,
    Applied,
    Rejected,
}

impl OpState {
    pub fn as_str(&self) -> &'static str {
        match self {
            OpState::Pending => "pending",
            OpState::Applied => "applied",
            OpState::Rejected => "rejected",
        }
    }
}

/// Payload emitted to ops.ack.* after each op completes or fails.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AckPayload {
    pub jti: String,
    pub workspace: String,
    pub op_type: String,
    pub target: String,
    pub result: AckResult,
    pub error: Option<String>,
    pub timestamp: DateTime<Utc>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AckResult {
    Applied,
    Rejected,
    Skipped,
}
