use crate::gmssl::sm2::{SM2_KEY, SM2_POINT};

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct SdConfig {
    pub public_key: String,
    pub private_key: String,
    pub sin_key: String,
    pub supplier_code: String,
    pub callback_url: reqwest::Url,
}

impl SdConfig {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn get_pk(&self) -> anyhow::Result<SM2_KEY> {
        unsafe {
            let mut key: SM2_KEY = std::mem::zeroed();
            let public_key = <SM2_POINT as TryFrom<&str>>::try_from(&self.public_key)?;
            key.set_pk(public_key);
            Ok(key)
        }
    }
    pub fn get_sk(&self) -> anyhow::Result<SM2_KEY> {
        unsafe {
            let mut key: SM2_KEY = std::mem::zeroed();

            key.set_sk(&self.private_key);
            Ok(key)
        }
    }
}

impl Default for SdConfig {
    fn default() -> Self {
        let key = SM2_KEY::key_generate();

        Self {
            public_key: key.get_pk(false),
            private_key: key.get_sk(),
            sin_key: "ZctLTt2tugU2ntZdVgMXssrGuENPH6V7b7ROYN88Msw=".to_string(),
            supplier_code: "CESHI".to_string(),
            callback_url: reqwest::Url::parse("https://api-test.schengle.com/gateway").unwrap(),
        }
    }
}

#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct FscgConfig {
    pub pay_url: reqwest::Url,
    pub search_url: reqwest::Url,
    pub balance_url: reqwest::Url,
    pub app_id: String,
    pub app_secret: String,
}

impl Default for FscgConfig {
    fn default() -> Self {
        Self {
            app_id: "som app_id".to_string(),
            app_secret: "som app_secret".to_string(),
            balance_url: reqwest::Url::parse(
                "http://192.144.212.211:36000/gateway/flowservice/queryAccount.ws",
            )
            .unwrap(),
            search_url: reqwest::Url::parse(
                "http://192.144.212.211:36000/gateway/flowservice/queryorder.ws",
            )
            .unwrap(),
            pay_url: reqwest::Url::parse(
                "http://192.144.212.211:36000/gateway/flowservice/makeorder.ws",
            )
            .unwrap(),
        }
    }
}

#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Config {
    pub sd_config: SdConfig,
    pub addr: std::net::SocketAddr,
    pub timeout: u64,
    pub fscg_config: FscgConfig,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            sd_config: Default::default(),
            addr: "0.0.0.0:8848".parse().unwrap(),
            timeout: Default::default(),
            fscg_config: Default::default(),
        }
    }
}

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

    #[test]
    fn test_name() {
        let config = SdConfig::default();
        let r = config.get_pk().unwrap();
        // let r = r.encrypt("sdgasfawerashfrgLLLLLLLLLLLLLLLLLLLLLLLJFB;ljebfffffffffffffffffffffffffffffffffffffffffffsdqwdadfwefdf");
        println!("{r:?}")
    }
}
