use ratatui::layout::{Alignment, Constraint, Layout, Rect};
use ratatui::style::Style;
use ratatui::text::{Line, Span};
use ratatui::widgets::{Cell, Paragraph, Row, Table};
use ratatui::Frame;
use tui_big_text::{BigText, PixelSize};

use crate::state::ui::UiState;
use crate::theme;

pub fn render(frame: &mut Frame, area: Rect, ui: &UiState, plugin_mode: bool) {
    let theme = theme::get();
    frame.render_widget(&ui.sparkles, area);

    let author_style = Style::new().fg(theme.title.author);
    let link_style = Style::new().fg(theme.title.link);
    let license_style = Style::new().fg(theme.title.license);

    let big_title = BigText::builder()
        .pixel_size(PixelSize::Full)
        .style(Style::new().fg(theme.title.big_title).bold())
        .lines(vec!["CAGIRE".into()])
        .centered()
        .build();

    let info_lines = vec![
        Line::from(""),
        Line::from(vec![
            Span::styled("A Forth Music Sequencer by ", Style::new().fg(theme.title.subtitle)),
            Span::styled("BuboBubo", author_style),
        ]),
        Line::from(Span::styled(
            format!("v{}", env!("CARGO_PKG_VERSION")),
            Style::new().fg(theme.title.subtitle),
        )),
        Line::from(""),
        Line::from(Span::styled("https://raphaelforment.fr", link_style)),
        Line::from(""),
        Line::from(Span::styled("AGPL-3.0", license_style)),
    ];

    let mut keybindings = vec![
        ("Ctrl+Arrows", "Navigate Views"),
        ("Enter", "Edit Step"),
        ("Space", "Play/Stop"),
        ("s", "Save"),
        ("l", "Load"),
    ];
    if !plugin_mode {
        keybindings.push(("q", "Quit"));
    }
    keybindings.push(("?", "Keybindings"));

    let key_style = Style::new().fg(theme.modal.confirm);
    let desc_style = Style::new().fg(theme.ui.text_primary);
    let rows: Vec<Row> = keybindings
        .iter()
        .enumerate()
        .map(|(i, (key, desc))| {
            let bg = if i % 2 == 0 {
                theme.table.row_even
            } else {
                theme.table.row_odd
            };
            Row::new(vec![
                Cell::from(*key).style(key_style),
                Cell::from(*desc).style(desc_style),
            ])
            .style(Style::new().bg(bg))
        })
        .collect();

    let table = Table::new(
        rows,
        [Constraint::Length(14), Constraint::Fill(1)],
    )
    .column_spacing(2);

    let press_line = Line::from(Span::styled(
        "Press any key to continue",
        Style::new().fg(theme.title.subtitle),
    ));

    let info_height = info_lines.len() as u16;
    let table_height = keybindings.len() as u16;
    let table_width: u16 = 42;

    let big_text_height: u16 = 8;

    let content_height = info_height + table_height + 3; // +3 for gap + empty line + press line
    let show_big_title =
        area.height >= (big_text_height + content_height) && area.width >= 30;

    let total_height = if show_big_title {
        big_text_height + content_height
    } else {
        content_height
    };
    let v_pad = area.height.saturating_sub(total_height) / 2;

    let mut constraints = Vec::new();
    constraints.push(Constraint::Length(v_pad));
    if show_big_title {
        constraints.push(Constraint::Length(big_text_height));
    }
    constraints.push(Constraint::Length(info_height));
    constraints.push(Constraint::Length(1)); // gap
    constraints.push(Constraint::Length(table_height));
    constraints.push(Constraint::Length(1)); // empty line
    constraints.push(Constraint::Length(1)); // press any key
    constraints.push(Constraint::Fill(1));

    let areas = Layout::vertical(constraints).split(area);
    let mut idx = 1; // skip padding

    if show_big_title {
        frame.render_widget(big_title, areas[idx]);
        idx += 1;
    }

    let info = Paragraph::new(info_lines).alignment(Alignment::Center);
    frame.render_widget(info, areas[idx]);
    idx += 1;

    idx += 1; // skip gap

    let tw = table_width.min(areas[idx].width);
    let tx = areas[idx].x + (areas[idx].width.saturating_sub(tw)) / 2;
    let table_area = Rect::new(tx, areas[idx].y, tw, areas[idx].height);
    frame.render_widget(table, table_area);
    idx += 2; // skip empty line

    let press = Paragraph::new(press_line).alignment(Alignment::Center);
    frame.render_widget(press, areas[idx]);
}
