mod app;
mod data_layer;
mod entities;
mod enums;
mod ui;
use crate::{app::App, enums::*, ui::ui};
use chrono::Local;
use entities::{Account, Transaction};
use ratatui::{
    Terminal,
    crossterm::{
        event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
        execute,
        terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
    },
    prelude::Backend,
};
use std::{
    env::{self},
    error::Error,
    io,
};

fn main() -> Result<(), Box<dyn Error>> {
    enable_raw_mode()?;
    let mut stderr = io::stderr();
    execute!(stderr, EnterAlternateScreen, EnableMouseCapture)?;

    let mut path: &str = "ft_rs.db";
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 {
        path = &args[1];
    }

    let mut terminal = ratatui::init();
    let mut app = App::new(path);
    let res = run_app(&mut terminal, &mut app);

    disable_raw_mode()?;
    execute!(
        terminal.backend_mut(),
        LeaveAlternateScreen,
        DisableMouseCapture
    )?;
    terminal.show_cursor()?;

    if let Err(err) = res {
        println!("{err:?}");
    }
    return Ok(());
}

fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) -> io::Result<bool>
where
    std::io::Error: From<<B as Backend>::Error>,
{
    loop {
        terminal.draw(|f| ui(f, app))?;

        // S'occupe des keyevents
        if let Event::Key(key) = event::read()? {
            if key.kind == event::KeyEventKind::Release {
                continue;
            }

            if let KeyCode::Enter = key.code
                && app.error_showing
            {
                app.error = String::new();
                app.error_showing = false;
                continue;
            }

            match app.current_screen {
                CurrentScreen::Main => match key.code {
                    KeyCode::Char('q') => {
                        app.current_screen = CurrentScreen::Exiting;
                    }
                    KeyCode::Right => {
                        app.current_widget = CurrentWidget::TrxList;
                    }
                    KeyCode::Left => {
                        app.current_widget = CurrentWidget::AccountList;
                    }
                    KeyCode::Char('j') => match app.current_widget {
                        CurrentWidget::AccountList => {
                            app.next_ac();
                        }
                        CurrentWidget::TrxList => {
                            app.next_tr();
                        }
                    },
                    KeyCode::Char('k') => match app.current_widget {
                        CurrentWidget::AccountList => {
                            app.previous_ac();
                        }
                        CurrentWidget::TrxList => {
                            app.previous_tr();
                        }
                    },
                    KeyCode::Char('l') => match app.current_widget {
                        CurrentWidget::AccountList => {}
                        CurrentWidget::TrxList => {
                            app.next_tab();
                        }
                    },
                    KeyCode::Char('h') => match app.current_widget {
                        CurrentWidget::AccountList => {}
                        CurrentWidget::TrxList => {
                            app.previous_tab();
                        }
                    },
                    KeyCode::Char('n') => match app.current_widget {
                        CurrentWidget::AccountList => {
                            app.current_screen = CurrentScreen::NewAccount;
                        }
                        CurrentWidget::TrxList => {
                            app.current_screen = CurrentScreen::NewTransaction;
                            app.new_transaction
                                .set_account_id(app.acc_list.get_selected_id());
                            app.new_transaction.set_date(Local::now());
                        }
                    },
                    KeyCode::Char('m') => match app.current_widget {
                        CurrentWidget::AccountList => {
                            app.current_screen = CurrentScreen::NewAccount;
                            app.new_account = app.acc_list.selected_ac();
                            app.set_current_input_ac();
                        }
                        CurrentWidget::TrxList => {
                            app.current_screen = CurrentScreen::NewTransaction;
                            app.new_transaction = app.trx_table.selected_tr();
                            app.set_current_input_tr();
                        }
                    },
                    _ => {
                        if let CurrentWidget::TrxList = app.current_widget
                            && app.selected_tab == 1
                        {
                            if let Ok(c) = key.code.to_string().parse::<i64>() {
                                app.select_tr_type_chart(c);
                            }
                        }
                    }
                },
                CurrentScreen::NewAccount => match key.code {
                    KeyCode::Down => {
                        app.next_ac_input();
                    }
                    KeyCode::Up => {
                        app.previous_ac_input();
                    }
                    KeyCode::Backspace => {
                        app.current_input.pop();
                    }
                    KeyCode::Char(value) => {
                        app.current_input.push(value);
                    }
                    KeyCode::Enter => {
                        app.save_new_account();
                        app.current_screen = CurrentScreen::Main;
                    }
                    KeyCode::Esc => {
                        app.current_screen = CurrentScreen::Main;
                        app.new_account = Account::new_empty();
                    }
                    _ => {}
                },
                CurrentScreen::NewTransaction => match key.code {
                    KeyCode::Down => {
                        app.next_tr_input();
                    }
                    KeyCode::Up => {
                        app.previous_tr_input();
                    }
                    KeyCode::Enter => {
                        app.save_new_tr();
                        app.current_screen = CurrentScreen::Main;
                    }
                    KeyCode::Backspace => {
                        app.current_input.pop();
                    }
                    KeyCode::Char(value) => {
                        app.current_input.push(value);
                    }
                    KeyCode::Esc => {
                        app.current_screen = CurrentScreen::Main;
                        app.new_transaction = Transaction::new_empty();
                    }
                    _ => {}
                },
                CurrentScreen::Exiting => match key.code {
                    KeyCode::Char('y') => {
                        return Ok(true);
                    }
                    _ => {
                        app.current_screen = CurrentScreen::Main;
                    }
                },
            }
        }
    }
}