mod app;
mod config;
mod ui;
mod zfs;

use anyhow::Result;
use app::{App, InputMode};
use crossterm::{
    event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyModifiers, MouseEventKind, MouseButton},
    execute,
    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use std::time::Duration;
use ratatui::{backend::CrosstermBackend, Terminal};
use std::io;
use std::env;

const VERSION: &str = env!("CARGO_PKG_VERSION");

fn main() -> Result<()> {
    // Handle command line arguments
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 {
        match args[1].as_str() {
            "-v" | "--version" => {
                println!("zfsdu {}", VERSION);
                return Ok(());
            }
            "-h" | "--help" => {
                print_help();
                return Ok(());
            }
            _ => {
                eprintln!("Unknown option: {}", args[1]);
                eprintln!("Use --help for usage information");
                std::process::exit(1);
            }
        }
    }
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;

    let mut app = App::new()?;
    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 {
        eprintln!("Error: {err:?}");
    }

    Ok(())
}

fn print_help() {
    println!("zfsdu {} - ZFS Disk Usage Viewer", VERSION);
    println!();
    println!("USAGE:");
    println!("    zfsdu [OPTIONS]");
    println!();
    println!("OPTIONS:");
    println!("    -h, --help       Print help information");
    println!("    -v, --version    Print version information");
    println!();
    println!("KEYBINDINGS:");
    println!("    ↑/k, ↓/j         Navigate up/down");
    println!("    Enter/l          Expand/collapse dataset");
    println!("    Space            Mark/unmark snapshot");
    println!("    +/-/*            Select/unselect/invert (in scope)");
    println!("    s                Toggle sort (Size/Date/Name)");
    println!("    /                Search");
    println!("    f                Filter");
    println!("    d                Delete marked snapshots");
    println!("    D                Toggle dry-run mode");
    println!("    a                Toggle auto-refresh");
    println!("    r                Refresh");
    println!("    ?                Help");
    println!("    q                Quit");
    println!();
    println!("CONFIG:");
    println!("    ~/.config/zfsdu/config.toml");
    println!();
    println!("(c) Florian Schermer - DATAZONE GmbH");
    println!("https://datazone.de");
}

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

        // Check auto-refresh
        app.check_auto_refresh()?;

        // Poll with timeout for auto-refresh
        if !event::poll(Duration::from_millis(100))? {
            continue;
        }

        match event::read()? {
            Event::Key(key) => {
                // Handle input mode
                if app.input_mode != InputMode::Normal {
                    match key.code {
                        KeyCode::Esc => app.cancel_input(),
                        KeyCode::Enter => app.confirm_input(),
                        KeyCode::Backspace => app.input_backspace(),
                        KeyCode::Char(c) => app.input_char(c),
                        _ => {}
                    }
                    continue;
                }

                // Close help on any key
                if app.show_help {
                    app.show_help = false;
                    continue;
                }

                // Quit on q or Ctrl+C
                if key.code == KeyCode::Char('q') || key.code == KeyCode::F(10) {
                    return Ok(());
                }
                if key.code == KeyCode::Char('c') && key.modifiers.contains(KeyModifiers::CONTROL) {
                    return Ok(());
                }

                match key.code {
                    // Navigation
                    KeyCode::Up | KeyCode::Char('k') => app.previous(),
                    KeyCode::Down | KeyCode::Char('j') => app.next(),
                    KeyCode::Enter | KeyCode::Right | KeyCode::Char('l') => app.toggle_expand(),
                    KeyCode::Backspace | KeyCode::Left | KeyCode::Char('h') => app.toggle_expand(),
                    KeyCode::Home => app.first(),
                    KeyCode::End => app.last(),
                    KeyCode::PageUp => app.page_up(),
                    KeyCode::PageDown => app.page_down(),

                    // Expand/Collapse all
                    KeyCode::Char('e') => app.expand_all(),
                    KeyCode::Char('c') => app.collapse_all(),

                    // Selection
                    KeyCode::Char(' ') => app.toggle_mark(),
                    KeyCode::Char('+') => app.select_group(),
                    KeyCode::Char('-') => app.unselect_group(),
                    KeyCode::Char('*') => app.invert_selection(),

                    // Search & Filter
                    KeyCode::Char('/') => app.start_search(),
                    KeyCode::Char('f') => app.start_filter(),
                    KeyCode::Char('n') => app.next_match(),
                    KeyCode::Char('N') => app.prev_match(),
                    KeyCode::Esc => app.clear_filter(),

                    // Sort
                    KeyCode::Char('s') => app.toggle_sort(),

                    // Dry-run mode
                    KeyCode::Char('D') => app.toggle_dry_run(),

                    // Auto-refresh
                    KeyCode::Char('a') => app.toggle_auto_refresh(),

                    // Actions
                    KeyCode::Char('d') | KeyCode::F(8) => app.delete_marked()?,
                    KeyCode::Char('r') | KeyCode::F(5) => app.refresh()?,

                    // Help
                    KeyCode::F(1) | KeyCode::Char('?') => app.toggle_help(),

                    _ => {}
                }
            }
            Event::Mouse(mouse) => {
                match mouse.kind {
                    MouseEventKind::Down(MouseButton::Left) => {
                        // Calculate which item was clicked (accounting for header and borders)
                        let row = mouse.row as usize;
                        if row >= 4 { // Header area is 4 rows (title + border + header + separator)
                            let clicked_index = row - 4 + app.scroll_offset;
                            let visible_count = app.visible_count();
                            if clicked_index < visible_count {
                                app.selected = clicked_index;
                            }
                        }
                    }
                    MouseEventKind::Down(MouseButton::Right) => {
                        // Right-click toggles mark (like spacebar)
                        let row = mouse.row as usize;
                        if row >= 4 {
                            let clicked_index = row - 4 + app.scroll_offset;
                            let visible_count = app.visible_count();
                            if clicked_index < visible_count {
                                app.selected = clicked_index;
                                app.toggle_mark();
                            }
                        }
                    }
                    MouseEventKind::ScrollUp => {
                        for _ in 0..3 {
                            app.previous();
                        }
                    }
                    MouseEventKind::ScrollDown => {
                        for _ in 0..3 {
                            app.next();
                        }
                    }
                    MouseEventKind::Down(MouseButton::Middle) => {
                        // Middle-click toggles expand
                        app.toggle_expand();
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }
}
