//! Spinner utilities for showing progress during operations

use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::thread;
use std::time::Duration;

/// Simple spinner for showing activity
pub struct Spinner {
    active: Arc<AtomicBool>,
    thread: Option<thread::JoinHandle<()>>,
}

impl Spinner {
    /// Create and start a new spinner with a message
    pub fn new(message: &str) -> Self {
        let active = Arc::new(AtomicBool::new(true));
        let active_clone = Arc::clone(&active);
        let message = message.to_string();

        let thread = thread::spawn(move || {
            let frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
            let mut frame = 0;

            while active_clone.load(Ordering::Relaxed) {
                print!("\r{} {}", frames[frame], message);
                std::io::Write::flush(&mut std::io::stdout()).ok();
                
                frame = (frame + 1) % frames.len();
                thread::sleep(Duration::from_millis(80));
            }
            print!("\r{}\r", " ".repeat(message.len() + 3));
            std::io::Write::flush(&mut std::io::stdout()).ok();
        });

        Self {
            active,
            thread: Some(thread),
        }
    }

    /// Stop the spinner
    pub fn stop(mut self) {
        self.active.store(false, Ordering::Relaxed);
        if let Some(thread) = self.thread.take() {
            let _ = thread.join();
        }
    }
}

impl Drop for Spinner {
    fn drop(&mut self) {
        self.active.store(false, Ordering::Relaxed);
    }
}
