use harmony_cli::progress::{IndicatifProgressTracker, ProgressTracker};
use indicatif::MultiProgress;
use std::sync::Arc;

use crate::instrumentation::{self, HarmonyComposerEvent};

pub fn init() -> tokio::task::JoinHandle<()> {
    configure_logger();
    let handle = tokio::spawn(handle_events());

    loop {
        if instrumentation::instrument(HarmonyComposerEvent::HarmonyComposerStarted).is_ok() {
            break;
        }
    }

    handle
}

fn configure_logger() {
    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).build();
}

pub async fn handle_events() {
    let progress_tracker = Arc::new(IndicatifProgressTracker::new(MultiProgress::new()));

    const SETUP_SECTION: &str = "project-initialization";
    const COMPILTATION_TASK: &str = "compilation";
    const PROGRESS_DEPLOYMENT: &str = "deployment";

    instrumentation::subscribe("Harmony Composer Logger", {
        move |event| {
            let progress_tracker = Arc::clone(&progress_tracker);

            async move {
                match event {
                    HarmonyComposerEvent::HarmonyComposerStarted => {}
                    HarmonyComposerEvent::ProjectInitializationStarted => {
                        progress_tracker.add_section(
                            SETUP_SECTION,
                            &format!(
                                "{} Initializing Harmony project...",
                                harmony_cli::theme::EMOJI_HARMONY,
                            ),
                        );
                    }
                    HarmonyComposerEvent::ProjectInitialized => {}
                    HarmonyComposerEvent::ProjectCompilationStarted { details } => {
                        progress_tracker.add_task(SETUP_SECTION, COMPILTATION_TASK, &details);
                    }
                    HarmonyComposerEvent::ProjectCompiled => {
                        progress_tracker.finish_task(COMPILTATION_TASK, "project compiled");
                    }
                    HarmonyComposerEvent::ProjectCompilationFailed { details } => {
                        progress_tracker.fail_task(COMPILTATION_TASK, &format!("failed to compile project:\n{details}"));
                    }
                    HarmonyComposerEvent::DeploymentStarted { target, profile } => {
                        progress_tracker.add_section(
                            PROGRESS_DEPLOYMENT,
                            &format!(
                                "\n{} Deploying project on target '{target}' with profile '{profile}'...\n",
                                harmony_cli::theme::EMOJI_DEPLOY,
                            ),
                        );
                    }
                    HarmonyComposerEvent::DeploymentCompleted => {
                        progress_tracker.clear();
                    }
                    HarmonyComposerEvent::DeploymentFailed { details } => {
                        progress_tracker.add_task(PROGRESS_DEPLOYMENT, "deployment-failed", "");
                        progress_tracker.fail_task("deployment-failed", &details);
                    },
                    HarmonyComposerEvent::Shutdown => {
                        return false;
                    }
                }
                true
            }
        }
    })
    .await
}
