//! Blink state using Arc<AtomicBool> — zero entity overhead.
//!
//! The pulsing dot reads from a shared atomic. A background thread toggles it
//! every 500ms and calls window.request_animation_frame() via a stored callback.
//! No Entity, no cx.notify(), no dispatch tree involvement.

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

use crate::state::AgentStatus;
use crate::theme;

/// Shared blink state — just an atomic bool. No Entity, no GPUI overhead.
pub struct SharedBlink {
    pub visible: Arc<AtomicBool>,
}

impl SharedBlink {
    pub fn new() -> Self {
        Self { visible: Arc::new(AtomicBool::new(true)) }
    }

    /// Start blinking on a background thread. Calls `cx.notify()` on the
    /// parent view entity to trigger repaint.
    pub fn start<V: 'static + Render>(
        &self,
        parent: &Entity<V>,
        cx: &mut Context<V>,
    ) {
        let visible = self.visible.clone();
        let weak = parent.downgrade();
        cx.spawn(async move |_weak_parent: WeakEntity<V>, cx: &mut AsyncApp| {
            loop {
                cx.background_executor().timer(Duration::from_millis(500)).await;
                visible.fetch_xor(true, Ordering::Relaxed);
                // Notify the PARENT view directly — no intermediate entity
                let ok = weak.update(cx, |_, cx| cx.notify());
                if ok.is_err() { break; }
            }
        }).detach();
    }
}

/// Render a status dot as an inline div. Reads from SharedBlink atomically.
/// No Entity, no dispatch tree node, no dirty propagation.
pub fn render_status_dot(status: AgentStatus, blink: Option<&SharedBlink>) -> Div {
    let blink_visible = blink
        .map(|b| b.visible.load(Ordering::Relaxed))
        .unwrap_or(true);

    let color = match status {
        AgentStatus::Running if !blink_visible => theme::SURFACE1,
        AgentStatus::Running => theme::GREEN,
        AgentStatus::Idle => theme::OVERLAY0,
        AgentStatus::Done => theme::BLUE,
        AgentStatus::Error => theme::RED,
    };

    div()
        .w(px(8.0))
        .h(px(8.0))
        .rounded(px(4.0))
        .bg(color)
        .flex_shrink_0()
}
