//! Terminal setup and teardown for Ratatui TUI

use std::io::{stdout, Stdout};

use anyhow::Result;
use crossterm::{
    event::{DisableMouseCapture, EnableMouseCapture},
    execute,
    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::{backend::CrosstermBackend, Terminal};

pub type TuiTerminal = Terminal<CrosstermBackend<Stdout>>;

/// Setup terminal for TUI mode
pub fn setup_terminal() -> Result<TuiTerminal> {
    enable_raw_mode()?;
    let mut stdout = stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let terminal = Terminal::new(backend)?;
    Ok(terminal)
}

/// Restore terminal to normal mode
pub fn restore_terminal(mut terminal: TuiTerminal) -> Result<()> {
    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;
    Ok(())
}

/// Safe terminal wrapper that ensures cleanup on drop
pub struct SafeTerminal {
    pub terminal: TuiTerminal,
}

impl SafeTerminal {
    pub fn new() -> Result<Self> {
        let terminal = setup_terminal()?;
        Ok(Self { terminal })
    }
}

impl Drop for SafeTerminal {
    fn drop(&mut self) {
        // Extract terminal before restoration
        let terminal = std::mem::replace(
            &mut self.terminal,
            Terminal::new(CrosstermBackend::new(stdout())).unwrap(),
        );

        // Ignore errors during cleanup
        let _ = restore_terminal(terminal);
    }
}

impl std::ops::Deref for SafeTerminal {
    type Target = TuiTerminal;

    fn deref(&self) -> &Self::Target {
        &self.terminal
    }
}

impl std::ops::DerefMut for SafeTerminal {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.terminal
    }
}
