use erp_core::error::AppError;

/// 消息中心模块错误类型。
#[derive(Debug, thiserror::Error)]
pub enum MessageError {
    #[error("验证失败: {0}")]
    Validation(String),

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

    #[error("模板编码已存在: {0}")]
    DuplicateTemplateCode(String),

    #[error("渲染失败: {0}")]
    TemplateRenderError(String),

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

impl From<MessageError> for AppError {
    fn from(err: MessageError) -> Self {
        match err {
            MessageError::Validation(msg) => AppError::Validation(msg),
            MessageError::NotFound(msg) => AppError::NotFound(msg),
            MessageError::DuplicateTemplateCode(msg) => AppError::Conflict(msg),
            MessageError::TemplateRenderError(msg) => AppError::Internal(msg),
            MessageError::VersionMismatch => AppError::VersionMismatch,
        }
    }
}

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

pub type MessageResult<T> = Result<T, MessageError>;

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

    #[test]
    fn validation_maps_to_app_validation() {
        let app: AppError = MessageError::Validation("标题不能为空".to_string()).into();
        match app {
            AppError::Validation(msg) => assert_eq!(msg, "标题不能为空"),
            other => panic!("Expected AppError::Validation, got {:?}", other),
        }
    }

    #[test]
    fn not_found_maps_to_app_not_found() {
        let app: AppError = MessageError::NotFound("消息不存在".to_string()).into();
        match app {
            AppError::NotFound(msg) => assert_eq!(msg, "消息不存在"),
            other => panic!("Expected AppError::NotFound, got {:?}", other),
        }
    }

    #[test]
    fn duplicate_template_code_maps_to_app_conflict() {
        let app: AppError = MessageError::DuplicateTemplateCode("WELCOME".to_string()).into();
        match app {
            AppError::Conflict(msg) => assert_eq!(msg, "WELCOME"),
            other => panic!("Expected AppError::Conflict, got {:?}", other),
        }
    }

    #[test]
    fn template_render_error_maps_to_app_internal() {
        let app: AppError = MessageError::TemplateRenderError("变量缺失".to_string()).into();
        match app {
            AppError::Internal(msg) => assert_eq!(msg, "变量缺失"),
            other => panic!("Expected AppError::Internal, got {:?}", other),
        }
    }

    #[test]
    fn version_mismatch_maps_to_app_version_mismatch() {
        let app: AppError = MessageError::VersionMismatch.into();
        match app {
            AppError::VersionMismatch => {}
            other => panic!("Expected AppError::VersionMismatch, got {:?}", other),
        }
    }

    #[test]
    fn error_display_format() {
        assert_eq!(
            MessageError::Validation("字段为空".to_string()).to_string(),
            "验证失败: 字段为空"
        );
        assert_eq!(
            MessageError::NotFound("id=123".to_string()).to_string(),
            "未找到: id=123"
        );
        assert_eq!(
            MessageError::DuplicateTemplateCode("CODE".to_string()).to_string(),
            "模板编码已存在: CODE"
        );
        assert_eq!(
            MessageError::TemplateRenderError("解析失败".to_string()).to_string(),
            "渲染失败: 解析失败"
        );
        assert_eq!(
            MessageError::VersionMismatch.to_string(),
            "版本冲突: 数据已被其他操作修改，请刷新后重试"
        );
    }

    #[test]
    fn transaction_connection_error_maps_to_validation() {
        let db_err = sea_orm::DbErr::Conn(sea_orm::RuntimeErr::Internal("连接超时".to_string()));
        let tx_err: sea_orm::TransactionError<MessageError> =
            sea_orm::TransactionError::Connection(db_err);
        let msg_err: MessageError = tx_err.into();
        match msg_err {
            MessageError::Validation(msg) => assert!(msg.contains("连接超时")),
            other => panic!("期望 Validation，得到 {:?}", other),
        }
    }

    #[test]
    fn transaction_inner_error_passthrough() {
        let inner = MessageError::NotFound("模板不存在".to_string());
        let tx_err: sea_orm::TransactionError<MessageError> =
            sea_orm::TransactionError::Transaction(inner);
        let msg_err: MessageError = tx_err.into();
        match msg_err {
            MessageError::NotFound(msg) => assert_eq!(msg, "模板不存在"),
            other => panic!("期望 NotFound，得到 {:?}", other),
        }
    }
}
