use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use tui::{layout::{Alignment, Constraint, Direction, Layout}, style::{Color, Style}, widgets::{Block, BorderType, Borders, Paragraph}, Terminal};

use crate::state::AppState;

pub struct Canvas<T: tui::backend::Backend> {
    top_row: usize,
    terminal: Terminal<T>,
}

impl<T: tui::backend::Backend> Canvas<T> {
    pub fn new(terminal: Terminal<T>) -> Self {
        enable_raw_mode().unwrap();
        Self {
            top_row: 0,
            terminal
        }
    }

    pub fn render(&mut self, app_state: &AppState) -> Result<(), anyhow::Error>
    {
        self.terminal.draw(|rect| {
            let size = rect.size();
            let chunks = Layout::default()
                .direction(Direction::Vertical)
                .margin(2)
                .constraints(
                    [
                        Constraint::Min(2),
                        Constraint::Length(3),
                        // Constraint::Length(3),
                    ]
                    .as_ref(),
                )
                .split(size);

            let title = Paragraph::new(
                app_state
                    .path
                    .clone()
                    .map(|path| path.to_string_lossy().into_owned())
                    .unwrap_or("No file opened".to_owned()),
            )
            .style(Style::default().fg(Color::LightCyan))
            .alignment(Alignment::Center)
            .block(
                Block::default()
                    .borders(Borders::ALL)
                    .style(Style::default().fg(Color::White))
                    .border_type(BorderType::Plain),
            );
            rect.render_widget(title, chunks[1]);

            /*
            let cp = Paragraph::new(COPYRIGHT)
                .style(Style::default().fg(Color::LightCyan))
                .alignment(Alignment::Center)
                .block(
                    Block::default()
                        .borders(Borders::ALL)
                        .style(Style::default().fg(Color::White))
                        .title("Copyright")
                        .border_type(BorderType::Plain),
                );
            rect.render_widget(cp, chunks[2]);
            */

            let (row, column) = app_state.cursor.addr();
            if row == self.top_row && row >= 1 {
                self.top_row -= 1;
            } else if row - self.top_row == (chunks[0].height - 1).into() {
                self.top_row += 1;
            }

            let contents = Paragraph::new(app_state.contents.contents()).scroll((self.top_row as u16, 0));
            rect.render_widget(contents, chunks[0]);

            rect.set_cursor(chunks[0].x + column as u16, chunks[0].y + (row - self.top_row) as u16);
        })?;
        Ok(())
    }
}

impl<T: tui::backend::Backend> Drop for Canvas<T> {
    fn drop(&mut self) {
        let _ = disable_raw_mode();
        let _ = self.terminal.show_cursor();
    }
}