use crate::database_control::*;
use sqlx::{Error, FromRow};

#[derive(Debug, FromRow)]
pub struct SignalDecisionInfo {
    pub decision: String,
}

#[derive(Debug, FromRow)]
pub struct SignalAssociaionOpinion {
    pub id: i64,
    pub name: String,
    pub is_working: bool,
    pub opinion: String,
    pub weight: f64,
}

pub async fn monitoring_signal_decision() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let signal_association_opinions = select_signal_association_opinion().await;
    let mut up_cnt = 0;
    let mut down_cnt = 0;
    let mut keep_cnt = 0;

    for element in signal_association_opinions {
        if element.is_working == true {
            match element.opinion.as_str() {
                "UP" => {
                    up_cnt += 1;
                }
                "DOWN" => {
                    down_cnt += 1;
                }
                "KEEP" => {
                    keep_cnt += 1;
                }
                _ => {}
            }
        }
    }

    let update_table_name = String::from("signal_decision");
    let mut association_update_values: Vec<(String, String)> = Vec::new();
    let association_update_condition = vec![(String::from("id"), String::from("1"))];
    if up_cnt > down_cnt && up_cnt >= keep_cnt {
        association_update_values = vec![(String::from("decision"), String::from("UP"))];
    } else if down_cnt > up_cnt && down_cnt >= keep_cnt {
        association_update_values = vec![(String::from("decision"), String::from("DOWN"))];
    } else {
        association_update_values = vec![(String::from("decision"), String::from("KEEP"))];
    }
    update_record2(
        &update_table_name,
        &association_update_values,
        &association_update_condition,
    )
    .await;

    Ok(())
}

pub async fn select_signal_association_opinion() -> Vec<SignalAssociaionOpinion> {
    let select_table_name = String::from("signal_association_opinion");
    let select_columns = String::from("*");
    let select_condition = None;
    let select_struct = SignalAssociaionOpinion {
        id: 0,
        name: String::new(),
        is_working: false,
        opinion: String::new(),
        weight: 0.0,
    };

    let select_result = select_record(
        &select_table_name,
        &select_columns,
        &select_condition,
        &select_struct,
    )
    .await
    .unwrap();

    select_result
}

pub async fn select_signal_decision() -> Vec<SignalDecisionInfo> {
    let select_table_name = String::from("signal_decision");
    let select_columns = String::from("*");
    let select_condition = None;
    let select_struct = SignalDecisionInfo {
        decision: String::new(),
    };

    let select_result = select_record(
        &select_table_name,
        &select_columns,
        &select_condition,
        &select_struct,
    )
    .await
    .unwrap();

    select_result
}
