use crate::app::App;
use crate::models::AppState;
use crate::ui;
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
use ratatui::Terminal;
use std::error::Error;

pub fn run<B: ratatui::backend::Backend>(
    terminal: &mut Terminal<B>,
    app: &mut App,
) -> Result<(), Box<dyn Error>> {
    loop {
        terminal.draw(|f| ui::render(f, app))?;

        if let Event::Key(key) = event::read()?
            && key.kind == KeyEventKind::Press
        {
            match app.app_state {
                AppState::Normal => match key.code {
                    KeyCode::Char('q') => return Ok(()),
                    KeyCode::Char('i') | KeyCode::Char('a') => {
                        app.enter_edit_mode();
                    }
                    KeyCode::Char('j') | KeyCode::Down => {
                        app.next();
                    }
                    KeyCode::Char('k') | KeyCode::Up => {
                        app.previous();
                    }
                    KeyCode::Char('u') => {
                        app.enter_status_mode();
                    }
                    KeyCode::Char('+') => {
                        app.increase_story_points()?;
                        app.refresh_task()?;
                    }
                    KeyCode::Char('-') => {
                        app.decrease_story_points()?;
                        app.refresh_task()?;
                    }
                    _ => {}
                },
                AppState::Editing => match key.code {
                    KeyCode::Esc => {
                        app.exit_edit_mode();
                    }
                    KeyCode::Char(c) => {
                        app.input_char(c);
                    }
                    KeyCode::Backspace => {
                        app.input_backspace();
                    }
                    KeyCode::Enter => {
                        app.add_task()?;
                        app.exit_edit_mode();
                        app.refresh_task()?;
                    }
                    _ => {}
                },
                AppState::SelectStatus => match key.code {
                    KeyCode::Esc => {
                        app.exit_status_mode();
                    }
                    KeyCode::Char('j') | KeyCode::Down => app.next_status(),
                    KeyCode::Char('k') | KeyCode::Up => app.previous_status(),
                    KeyCode::Enter => {
                        app.change_status()?;
                        app.exit_status_mode();
                        app.refresh_task()?;
                    }
                    _ => {}
                },
            }
        }
    }
}
