/*
 * Copyright (c) 2025, LJason. All Rights Reserved.
 */

use serde::{Deserialize, Serialize};

use crate::BiCoreError;

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Response<T> {
    /// 返回值
    /// - 0: 成功
    /// - -400：请求错误
    /// - -403：访问权限不足
    #[serde(default)]
    pub code: i32,

    /// 错误信息
    /// 默认为0
    #[serde(default)]
    pub message: String,

    /// 信息本体
    /// 出错时为 None
    pub data: Option<T>,
}

impl<T> Response<T> {
    /// 业务状态码常量
    pub const CODE_SUCCESS: i32 = 0;
    pub const CODE_BAD_REQUEST: i32 = -400;
    pub const CODE_FORBIDDEN: i32 = -403;

    /// 将 Response 转换为 Result 类型
    ///
    /// # Errors
    /// - `BiCoreError::MissingData` - 当 code 为 0 但 data 为空时
    /// - `BiCoreError::RequestError` - 当 code 为 -400 时
    /// - `BiCoreError::AccessDenied` - 当 code 为 -403 时
    /// - `BiCoreError::Unknown` - 当 code 为其他值时
    pub fn into_result(self) -> Result<T, BiCoreError> {
        match self.code {
            Self::CODE_SUCCESS => self.data.ok_or(BiCoreError::MissingData),
            Self::CODE_BAD_REQUEST => Err(BiCoreError::RequestError(self.message)),
            Self::CODE_FORBIDDEN => Err(BiCoreError::AccessDenied),
            _ => Err(BiCoreError::Unknown),
        }
    }
}
