use erp_core::error::AppError;

/// Workflow module error types.
#[derive(Debug, thiserror::Error)]
pub enum WorkflowError {
    #[error("验证失败: {0}")]
    Validation(String),

    #[error("资源未找到: {0}")]
    NotFound(String),

    #[error("流程定义已存在: {0}")]
    DuplicateDefinition(String),

    #[error("流程图无效: {0}")]
    InvalidDiagram(String),

    #[error("流程状态错误: {0}")]
    InvalidState(String),

    #[error("表达式求值失败: {0}")]
    ExpressionError(String),

    #[error("版本冲突: 数据已被其他操作修改，请刷新后重试")]
    VersionMismatch,
}

impl From<sea_orm::TransactionError<WorkflowError>> for WorkflowError {
    fn from(err: sea_orm::TransactionError<WorkflowError>) -> Self {
        match err {
            sea_orm::TransactionError::Connection(err) => {
                WorkflowError::Validation(err.to_string())
            }
            sea_orm::TransactionError::Transaction(inner) => inner,
        }
    }
}

impl From<WorkflowError> for AppError {
    fn from(err: WorkflowError) -> Self {
        match err {
            WorkflowError::Validation(s) => AppError::Validation(s),
            WorkflowError::NotFound(s) => AppError::NotFound(s),
            WorkflowError::DuplicateDefinition(s) => AppError::Conflict(s),
            WorkflowError::InvalidDiagram(s) => AppError::Validation(s),
            WorkflowError::InvalidState(s) => AppError::Validation(s),
            WorkflowError::ExpressionError(s) => AppError::Validation(s),
            WorkflowError::VersionMismatch => AppError::VersionMismatch,
        }
    }
}

pub type WorkflowResult<T> = Result<T, WorkflowError>;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn validation_maps_to_app_error_validation() {
        let err = WorkflowError::Validation("字段缺失".to_string());
        let app: AppError = err.into();
        match app {
            AppError::Validation(msg) => assert!(msg.contains("字段缺失")),
            other => panic!("期望 AppError::Validation，得到 {:?}", other),
        }
    }

    #[test]
    fn not_found_maps_to_app_error_not_found() {
        let err = WorkflowError::NotFound("流程不存在".to_string());
        let app: AppError = err.into();
        match app {
            AppError::NotFound(msg) => assert!(msg.contains("流程不存在")),
            other => panic!("期望 AppError::NotFound，得到 {:?}", other),
        }
    }

    #[test]
    fn duplicate_definition_maps_to_app_error_conflict() {
        let err = WorkflowError::DuplicateDefinition("key 已存在".to_string());
        let app: AppError = err.into();
        match app {
            AppError::Conflict(msg) => assert!(msg.contains("key 已存在")),
            other => panic!("期望 AppError::Conflict，得到 {:?}", other),
        }
    }

    #[test]
    fn invalid_diagram_maps_to_validation() {
        let err = WorkflowError::InvalidDiagram("缺少 StartEvent".to_string());
        let app: AppError = err.into();
        match app {
            AppError::Validation(msg) => assert!(msg.contains("缺少 StartEvent")),
            other => panic!("期望 AppError::Validation，得到 {:?}", other),
        }
    }

    #[test]
    fn invalid_state_maps_to_validation() {
        let err = WorkflowError::InvalidState("流程已结束".to_string());
        let app: AppError = err.into();
        match app {
            AppError::Validation(msg) => assert!(msg.contains("流程已结束")),
            other => panic!("期望 AppError::Validation，得到 {:?}", other),
        }
    }

    #[test]
    fn expression_error_maps_to_validation() {
        let err = WorkflowError::ExpressionError("语法错误".to_string());
        let app: AppError = err.into();
        match app {
            AppError::Validation(msg) => assert!(msg.contains("语法错误")),
            other => panic!("期望 AppError::Validation，得到 {:?}", other),
        }
    }

    #[test]
    fn version_mismatch_maps_directly() {
        let err = WorkflowError::VersionMismatch;
        let app: AppError = err.into();
        match app {
            AppError::VersionMismatch => {}
            other => panic!("期望 AppError::VersionMismatch，得到 {:?}", other),
        }
    }
}
