use std::time::{Duration, Instant};

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RunMode {
    Local,
    Browser,
}

impl RunMode {
    pub fn detect() -> Self {
        if let Ok(mode) = std::env::var("RUN_MODE") {
            match mode.to_lowercase().as_str() {
                "browser" | "web" => return RunMode::Browser,
                "local" => return RunMode::Local,
                _ => {}
            }
        }

        // Auto-detect
        if std::env::var("AWS_EXECUTION_ENV").is_ok()
            || std::env::var("CLOUDSHELL").is_ok()
            || std::env::var("TUI_WEB").map(|v| v == "1").unwrap_or(false)
        {
            RunMode::Browser
        } else {
            RunMode::Local
        }
    }
}

pub struct RenderScheduler {
    run_mode: RunMode,
    last_render: Instant,
    render_scheduled: bool,
    immediate_render: bool, // Flag for immediate renders (bypass throttling)
    render_scheduled_count: u64,
    min_render_interval: Duration,
}

impl RenderScheduler {
    pub fn new() -> Self {
        let run_mode = RunMode::detect();
        let min_render_interval = match run_mode {
            RunMode::Browser => Duration::from_millis(50), // Max 20 FPS (browser limitation)
            RunMode::Local => Duration::from_millis(8), // Max 120 FPS (ultra-responsive, throttled for non-input)
        };

        Self {
            run_mode,
            last_render: Instant::now(),
            render_scheduled: false,
            immediate_render: false,
            render_scheduled_count: 0,
            min_render_interval,
        }
    }

    pub fn run_mode(&self) -> RunMode {
        self.run_mode
    }

    pub fn request_render(&mut self, _reason: &str) -> bool {
        self.render_scheduled_count += 1;
        self.render_scheduled = true; // Always schedule so the next should_render() can draw
        let now = Instant::now();
        let elapsed = now.duration_since(self.last_render);
        if elapsed >= self.min_render_interval {
            // Throttle allows: next frame should draw without waiting another interval
            self.immediate_render = true;
            true
        } else {
            false
        }
    }

    /// Request immediate render (bypass throttling) - for critical input events
    pub fn request_immediate_render(&mut self, _reason: &str) -> bool {
        self.render_scheduled_count += 1;
        self.render_scheduled = true;
        self.immediate_render = true; // Mark as immediate to bypass throttling
        true
    }

    pub fn should_render(&mut self) -> bool {
        if !self.render_scheduled {
            return false;
        }

        let now = Instant::now();
        let elapsed = now.duration_since(self.last_render);

        // If immediate render was requested, bypass throttling
        // Otherwise, respect the throttle interval
        if self.immediate_render || elapsed >= self.min_render_interval {
            self.last_render = now;
            self.render_scheduled = false;
            self.immediate_render = false; // Clear immediate flag
            true
        } else {
            false
        }
    }

    pub fn render_scheduled_count(&self) -> u64 {
        self.render_scheduled_count
    }

    pub fn min_render_interval_ms(&self) -> u64 {
        self.min_render_interval.as_millis() as u64
    }
}
