use super::data::*;
use sqlx::{query_as, PgPool, Postgres, QueryBuilder};

#[derive(Clone)]
pub struct DbDeployConfigMgr(PgPool);

impl DbDeployConfigMgr {
    pub fn new(pool: PgPool) -> Self {
        Self(pool)
    }

    pub async fn find_db_client_config(&self, version: String) -> Option<DbClientConfig> {
        query_as("SELECT * from t_client_config where version = ($1)")
            .bind(version)
            .fetch_one(&self.0)
            .await
            .ok()
    }

    pub async fn enable_login_pc(&self, channel_id: i32) -> Option<bool> {
        Some(
            query_as::<_, DbChannelIdConfig>(
                "SELECT * from t_channel_id_config where channel_id = ($1)",
            )
            .bind(channel_id)
            .fetch_one(&self.0)
            .await
            .ok()?
            .enable_login_pc,
        )
    }

    pub async fn find_bind_region_config_vec(&self, client_version: String) -> Vec<DbBindConfig> {
        query_as("SELECT * from t_bind_config where client_version = ($1)")
            .bind(client_version)
            .fetch_all(&self.0)
            .await
            .unwrap_or_default()
    }

    pub async fn find_db_client_region_config(
        &self,
        client_version: String,
        region_name: String,
    ) -> Option<DbClientRegionConfig> {
        query_as("SELECT * from t_client_region_config where client_version = ($1) and region_name = ($2)")
            .bind(client_version)
            .bind(region_name)
            .fetch_one(&self.0)
            .await
            .ok()
    }

    pub async fn find_db_region_config(&self, name: String) -> Option<DbRegionConfig> {
        query_as("SELECT * from t_region_config where name = ($1)")
            .bind(name)
            .fetch_one(&self.0)
            .await
            .ok()
    }

    pub async fn find_db_rsakey_config(&self, id: i64) -> Option<DbRsakeyConfig> {
        query_as("SELECT * from t_rsakey_config where id = ($1)")
            .bind(id)
            .fetch_one(&self.0)
            .await
            .ok()
    }

    pub async fn fetch_region_list(&self, binds: &[DbBindConfig]) -> Vec<DbRegionConfig> {
        let mut regions_query =
            QueryBuilder::<Postgres>::new("SELECT * from t_region_config where name in (");

        binds.iter().enumerate().for_each(|(i, b)| {
            regions_query.push_bind(b.region_name.clone());
            if binds.len() > i + 1 {
                regions_query.push(",");
            }
        });

        regions_query
            .push(")")
            .build_query_as()
            .fetch_all(&self.0)
            .await
            .unwrap_or_default()
    }
}
