use thiserror::Error;

#[derive(Error, Debug)]
pub enum WorkflowError {
    #[error("Workflow not found: {0}")]
    WorkflowNotFound(String),

    #[error("Configuration error: {0}")]
    ConfigError(#[from] ConfigError),

    #[error("Invalid state transition: {from:?} -> {to:?}")]
    InvalidTransition { from: String, to: String },

    #[error("No current stage available")]
    NoCurrentStage,

    #[error("No agents configured for stage")]
    NoAgentsInStage,

    #[error("Task not found: {0}")]
    TaskNotFound(String),

    #[error("Stage not waiting for approval")]
    NotWaitingApproval,

    #[error("Swarm coordination error: {0}")]
    SwarmError(String),

    #[error("NATS messaging error: {0}")]
    NatsError(Box<dyn std::error::Error + Send + Sync>),

    #[error("Knowledge graph error: {0}")]
    KnowledgeGraphError(String),

    #[error("Serialization error: {0}")]
    SerializationError(#[from] serde_json::Error),

    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error),

    #[error("Artifact persistence failed: {0}")]
    ArtifactError(String),

    #[error("Database error: {0}")]
    DatabaseError(String),

    #[error("Authorization denied: {0}")]
    Unauthorized(String),

    #[error("Internal error: {0}")]
    Internal(String),

    #[error("Schedule error: {0}")]
    Schedule(#[from] ScheduleError),
}

#[derive(Error, Debug)]
pub enum ScheduleError {
    #[error("Invalid cron expression '{expr}': {reason}")]
    InvalidCron { expr: String, reason: String },

    #[error("Schedule not found: {0}")]
    NotFound(String),
}

#[derive(Error, Debug)]
pub enum ConfigError {
    #[error("Failed to read config file: {0}")]
    IoError(#[from] std::io::Error),

    #[error("Failed to parse config: {0}")]
    ParseJson(#[from] serde_json::Error),

    #[error("Invalid configuration: {0}")]
    Invalid(String),
}

pub type Result<T> = std::result::Result<T, WorkflowError>;
