use crate::{Exception, Object, SqlCrud};
use mysql::prelude::*;
use mysql::*;
use std::collections::HashMap;

/// mysl客户端封装（失败品，弃用，直接使用mysql crate更佳）
///
/// 使用的是mysql crate，具体使用见其文档：https://docs.rs/mysql/26.0.1/mysql/
#[deprecated]
pub struct MySqlClient {
    pub pool: Pool,
}

impl MySqlClient {
    pub fn new(host: String, port: i32, user: String, password: String, db: String) -> Result<Self, Exception> {
        let url = format!("mysql://{user}:{password}@{host}:{port}/{db}");
        let opts = Opts::from_url(&url)?;
        let pool = Pool::new(opts)?;
        Ok(MySqlClient { pool })
    }
}

impl SqlCrud for MySqlClient {
    fn insert(&self, sql: &str) -> std::result::Result<bool, Exception> {
        todo!()
    }

    fn update(&self, sql: &str) -> std::result::Result<bool, Exception> {
        todo!()
    }

    fn delete(&self, sql: &str) -> std::result::Result<bool, Exception> {
        todo!()
    }

    fn select_one(&self, sql: &str) -> std::result::Result<HashMap<String, Object>, Exception> {

        todo!()
    }

    fn select(&self, sql: &str) -> std::result::Result<Vec<HashMap<String, Object>>, Exception> {
        let mut conn = self.pool.get_conn()?;
        let rows = conn.query_iter(sql)?;
        let mut results = vec![];
        for row in rows.into_iter().map(|row| row.unwrap()) {
            let mut item: HashMap<String, Object> = HashMap::new();
            let columns = row.columns().clone();
            let values = row.unwrap();
            for (i, column) in columns.iter().enumerate() {
                // TODO 此处有问题，通过这种方式返回的值，全部是Bytes类型，没有根据数据库实际情况返回对应的类型，如int，string，float等
                item.insert(column.name_str().to_string(), values.get(i).unwrap().clone().try_into().unwrap());
            }
            results.push(item);
        }
        Ok(results)
    }
}

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

    #[test]
    fn it_works() -> Result<(), Exception> {
        let client = MySqlClient::new("127.0.0.1".into(), 3306, "root".into(), "123456".into(), "test".into())?;
        let results = client.select("select * from sys_region where region_id = 2")?;
        println!("{:?}", results);
        Ok(())
    }
}
