use std::sync::Arc;

use async_trait::async_trait;
use serde::Serialize;

use crate::{
    interpret::{InterpretError, Outcome},
    inventory::Inventory,
    modules::{helm::chart::HelmChartInterpret, monitoring::kube_prometheus::{
        config::KubePrometheusConfig,
        kube_prometheus_helm_chart_score::kube_prometheus_helm_chart_score,
    }},
    topology::{K8sAnywhereTopology, Topology},
};

use super::{
    K8sMonitorConfig,
    monitoring::{AlertChannel, AlertChannelConfig, Monitor},
};

#[derive(Debug, Clone, Serialize)]
pub struct K8sMonitor {
    pub config: K8sMonitorConfig,
}

#[async_trait]
impl Monitor for K8sMonitor {
    async fn provision_monitor(
        &self,
        alert_receivers: Option<Vec<Box<dyn AlertChannelConfig>>>,
    ) -> Result<Outcome, InterpretError> {
        if let Some(receivers) = alert_receivers {
            let alert_channels = self.build_alert_channels(receivers).await?;
            for channel in alert_channels {
                channel.register_alert_channel().await?;
            }
        }
        let chart = self.config.chart.clone();
        //
        chart.create_interpret();
        Ok(Outcome::success("installed monitor".to_string()))
    }

    fn delete_monitor(&self) -> Result<Outcome, InterpretError> {
        todo!()
    }
}

#[async_trait]
impl AlertChannelConfig for K8sMonitor {
    async fn build_alert_channel(&self) -> Result<Box<dyn AlertChannel>, InterpretError> {
        todo!()
    }
}

impl K8sMonitor {
    pub async fn build_alert_channels(
        &self,
        alert_channel_configs: Vec<Box<dyn AlertChannelConfig>>,
    ) -> Result<Vec<Box<dyn AlertChannel>>, InterpretError> {
        let mut alert_channels = Vec::new();
        for config in alert_channel_configs {
            let channel = config.build_alert_channel().await?;
            alert_channels.push(channel)
        }
        Ok(alert_channels)
    }
}
