//! Example: Using Arc Package Manager with Progress Callbacks
//!
//! This example demonstrates how to use the progress tracking system
//! to monitor package installations with custom progress handling.

use std::sync::{Arc, Mutex};
use libarc::{PackageManager, Package, ProgressCallback, ProgressState};

/// Custom progress callback that prints progress updates
struct SimpleProgressCallback {
    package_name: String,
}

impl ProgressCallback for SimpleProgressCallback {
    fn update(&self, state: ProgressState) {
        match state {
            ProgressState::Preparing => {
                println!("📦 Preparing to install {}...", self.package_name);
            }
            ProgressState::Downloading { current, total } => {
                let percent = if total > 0 {
                    (current as f64 / total as f64) * 100.0
                } else {
                    0.0
                };
                println!(
                    "⬇️  Downloading: {}/{} ({:.0}%)",
                    current, total, percent
                );
            }
            ProgressState::Installing { current, total } => {
                let percent = if total > 0 {
                    (current as f64 / total as f64) * 100.0
                } else {
                    0.0
                };
                println!(
                    "⚙️  Installing: {}/{} ({:.0}%)",
                    current, total, percent
                );
            }
            ProgressState::Completed => {
                println!("✅ Successfully installed {}!", self.package_name);
            }
            ProgressState::Failed(err) => {
                println!("❌ Failed to install {}: {}", self.package_name, err);
            }
        }
    }
}

/// More advanced progress callback with a progress bar
struct ProgressBarCallback {
    package_name: String,
    bar_width: usize,
}

impl ProgressBarCallback {
    fn new(package_name: String) -> Self {
        Self {
            package_name,
            bar_width: 40,
        }
    }

    fn draw_bar(&self, percent: f64) {
        let filled = (percent / 100.0 * self.bar_width as f64) as usize;
        let empty = self.bar_width - filled;
        
        print!("\r[");
        print!("{}", "█".repeat(filled));
        print!("{}", "░".repeat(empty));
        print!("] {:.0}%", percent);
        std::io::Write::flush(&mut std::io::stdout()).ok();
    }
}

impl ProgressCallback for ProgressBarCallback {
    fn update(&self, state: ProgressState) {
        match state {
            ProgressState::Preparing => {
                println!("📦 Preparing {}...", self.package_name);
            }
            ProgressState::Downloading { current, total } => {
                let percent = if total > 0 {
                    (current as f64 / total as f64) * 100.0
                } else {
                    0.0
                };
                print!("⬇️  Downloading: ");
                self.draw_bar(percent);
            }
            ProgressState::Installing { current, total } => {
                let percent = if total > 0 {
                    (current as f64 / total as f64) * 100.0
                } else {
                    0.0
                };
                print!("⚙️  Installing: ");
                self.draw_bar(percent);
            }
            ProgressState::Completed => {
                println!("\n✅ Successfully installed {}!", self.package_name);
            }
            ProgressState::Failed(err) => {
                println!("\n❌ Failed to install {}: {}", self.package_name, err);
            }
        }
    }
}

/// Silent progress callback that doesn't print anything
struct SilentProgressCallback;

impl ProgressCallback for SilentProgressCallback {
    fn update(&self, _state: ProgressState) {
        // Do nothing - completely silent installation
    }
}

/// Example: Using with the Arc package manager
#[allow(dead_code)]
fn example_basic_progress(package_name: &str) -> Result<(), Box<dyn std::error::Error>> {
    // Create a package manager
    let pm = PackageManager::new()?;

    // Create a progress callback
    let callback = Arc::new(SimpleProgressCallback {
        package_name: package_name.to_string(),
    });

    // For pacman packages
    let pkg = Package::Pacman(package_name.to_string());

    // You would normally use the progress callback with:
    // arc::pacman::install_with_progress(package_name, callback.as_ref())?;
    
    // However, the PackageManager API doesn't yet expose progress callbacks
    // This is a future enhancement

    pm.install(&pkg)?;
    Ok(())
}

/// Example: Silent installation (no progress output)
#[allow(dead_code)]
fn example_silent_installation(package_name: &str) -> Result<(), Box<dyn std::error::Error>> {
    let pm = PackageManager::new()?;
    
    // Simply use the install method - no output is shown
    let pkg = Package::Pacman(package_name.to_string());
    pm.install(&pkg)?;
    
    println!("Package {} installed successfully", package_name);
    Ok(())
}

/// Example: Custom progress tracking
#[allow(dead_code)]
fn example_custom_progress() {
    // Create a shared progress state
    let progress = Arc::new(Mutex::new(ProgressState::Preparing));

    // Use it in multiple threads
    let progress_clone = Arc::clone(&progress);
    
    std::thread::spawn(move || {
        // Simulate progress updates
        std::thread::sleep(std::time::Duration::from_millis(100));
        {
            let mut p = progress_clone.lock().unwrap();
            *p = ProgressState::Installing { current: 1, total: 3 };
        }
    });

    // Main thread can read the progress
    std::thread::sleep(std::time::Duration::from_millis(200));
    let current_state = progress.lock().unwrap();
    println!("Current state: {:?}", *current_state);
}

fn main() {
    println!("Arc Package Manager - Progress Tracking Examples");
    println!("================================================\n");

    println!("Example 1: Silent Installation");
    println!("  When using the standard install command, pacman/flatpak");
    println!("  output is suppressed and only the result is shown.\n");

    println!("Example 2: Custom Progress Callbacks");
    println!("  Implement the ProgressCallback trait to handle progress events.\n");

    println!("Example 3: Progress Tracking");
    println!("  Use Arc<Mutex<ProgressState>> for thread-safe progress updates.\n");

    println!("See the source code for full implementation details.");
}
