//! Shared application state managed by Tauri.

use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};

use tauri::{AppHandle, Wry};

use crate::agent::AgentService;
use crate::error::AppError;
use crate::terminal::TerminalCommandService;

/// Runtime services shared across Tauri commands.
pub struct AppState {
    /// Stateful chat service used for per-session conversation history and agent config.
    pub agent: Mutex<AgentService<Wry>>,
    /// Slash-command executor backed by shared mock data.
    pub command_service: TerminalCommandService,
    next_request_id: AtomicU64,
}

impl AppState {
    /// Create a new application state for the current Tauri app.
    pub fn new(app_handle: &AppHandle<Wry>) -> Result<Self, AppError> {
        Ok(Self {
            agent: Mutex::new(AgentService::new(app_handle)?),
            command_service: TerminalCommandService::new(Arc::new(
                crate::terminal::yahoo_finance::YahooFinanceLookup::default(),
            )),
            next_request_id: AtomicU64::new(1),
        })
    }

    /// Generates a unique request id for correlating stream events with frontend listeners.
    pub fn next_request_id(&self) -> String {
        let id = self.next_request_id.fetch_add(1, Ordering::Relaxed);
        format!("request-{id}")
    }
}
