//! Terminal management for the TUI

use anyhow::Result;
use crossterm::{
    execute,
    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::prelude::*;
use std::io::{self, Stdout};

/// Terminal wrapper
pub(crate) struct Terminal {
    inner: ratatui::Terminal<CrosstermBackend<Stdout>>,
}

#[allow(dead_code)]
impl Terminal {
    /// Create and initialize a new terminal
    pub(crate) fn new() -> Result<Self> {
        enable_raw_mode()?;
        let mut stdout = io::stdout();
        execute!(stdout, EnterAlternateScreen)?;

        let backend = CrosstermBackend::new(stdout);
        let inner = ratatui::Terminal::new(backend)?;

        Ok(Self { inner })
    }

    /// Get mutable reference to the inner terminal
    pub(crate) fn inner_mut(&mut self) -> &mut ratatui::Terminal<CrosstermBackend<Stdout>> {
        &mut self.inner
    }

    /// Get immutable reference to the inner terminal
    pub(crate) fn inner(&self) -> &ratatui::Terminal<CrosstermBackend<Stdout>> {
        &self.inner
    }

    /// Clear the screen
    pub(crate) fn clear(&mut self) -> Result<()> {
        self.inner.clear()?;
        Ok(())
    }

    /// Draw on the terminal
    pub(crate) fn draw<F>(&mut self, f: F) -> Result<()>
    where
        F: FnOnce(&mut Frame<'_>),
    {
        self.inner.draw(f)?;
        Ok(())
    }
}

impl Drop for Terminal {
    fn drop(&mut self) {
        let _ = disable_raw_mode();
        let _ = execute!(io::stdout(), LeaveAlternateScreen);
    }
}

impl Default for Terminal {
    fn default() -> Self {
        Self::new().expect("Failed to initialize terminal")
    }
}
