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 app_id: 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: "03a79f1f36d85712f21e983957de3f891629d3bb731df4010c85794cc4da35a57a".to_string(),
            private_key: "f2b033fc68664a00fab1b0eda28c35e70c358bc82027293bbf7f91195b43af28".to_string(),
            sin_key: "ZctLTt2tugU2ntZdVgMXssrGuENPH6V7b7ROYN88Msw=".to_string(),
            app_id: "3230cdff981546dc8fe71b9c2d597ba11678695776032".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 date_source: String,
    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(),
            date_source: "".to_string()
        }
    }
}

#[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:?}")
    }

    #[test]
    fn test_sk() {
        let cf = SdConfig{
            private_key: "caaba4e6910b1b510e9347e004bc115cb5fb90a16ddde3cc0566522e946d0368".to_string(),
            ..Default::default()
        };
        let key = cf.get_sk().unwrap();
        let data = hex::decode("0485bae5445c8d2896bf09b84a69db998daad510489dc86ae1b14e2dff0bb5c0ab0cbe66517eefa55e8009a09679f9ceebf705b1f4796e52daa1fad1b3cb6f56e3cf7ef35ac7ebda3a4e6e5e8108fc228981323205bcfbf49b7337fc317d7b2f4213d36744e27dd27406ed66a86648ebdf9cfa9051742d78addb638f6a3ec0e0847702d1d1e1cc611a94e3acbfb43ec8b87f8e0cc2668e319f617750e1ea392a43cf5e4087a8eb833f5091d5f544301c134b93afcbf905c5e080a793450b391a1ad61d9226603e1c68cf1235ba64721574f1c08ff84b37").unwrap();
        let r = key.decrypt(data, crate::gmssl::sm2::PassOrder::C1C3C2);
        println!("{:?}", r)
    }
}
