use crate::app::App;
use crate::models::AppState;
use ratatui::layout::Rect;
use ratatui::style::Stylize;
use ratatui::text::{Line, Span};
use ratatui::widgets::{Clear, List};
use ratatui::{
    Frame,
    layout::{Constraint, Direction, Layout},
    style::{Color, Modifier, Style},
    widgets::{Block, Borders, Paragraph, Row, Table},
};

pub fn render(f: &mut Frame, app: &mut App) {
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(3),
            Constraint::Min(1),
            Constraint::Length(3),
        ])
        .split(f.area());

    render_title(f, app, chunks[0]);
    render_table(f, app, chunks[1]);
    render_pagination_info(f, app, chunks[2]);
    render_popup_form(f, app, chunks[1]);
    render_edit_help(f, app, chunks[2]);
    render_popup_status_list(f, app, chunks[1]);
}

fn render_title(f: &mut Frame, app: &App, area: ratatui::layout::Rect) {
    match app.app_state {
        AppState::Normal => {
            let title = Paragraph::new("iSeq2 tasks list")
                .style(
                    Style::default()
                        .fg(Color::Cyan)
                        .add_modifier(Modifier::BOLD),
                )
                .block(Block::default().borders(Borders::ALL));
            f.render_widget(title, area);
        }
        AppState::Editing => {
            let title = Paragraph::new("Store new task")
                .style(
                    Style::default()
                        .fg(Color::Cyan)
                        .add_modifier(Modifier::BOLD),
                )
                .block(Block::default().borders(Borders::ALL));
            f.render_widget(title, area);
        }
        AppState::SelectStatus => {
            let title = Paragraph::new("Update task status")
                .style(
                    Style::default()
                        .fg(Color::LightBlue)
                        .add_modifier(Modifier::BOLD),
                )
                .block(Block::default().borders(Borders::ALL));
            f.render_widget(title, area);
        }
    }
}

fn render_table(f: &mut Frame, app: &mut App, area: ratatui::layout::Rect) {
    let header = Row::new(["Id", "Name", "Status", "Story Points"])
        .style(Style::new().bold())
        .bottom_margin(1);

    let rows: Vec<Row> = app
        .tasks
        .iter()
        .map(|task| {
            Row::new([
                task.id.to_string(),
                task.name.clone(),
                task.status.clone(),
                task.story_points.to_string(),
            ])
        })
        .collect();

    let widths = [
        Constraint::Percentage(25),
        Constraint::Percentage(25),
        Constraint::Percentage(25),
        Constraint::Percentage(25),
    ];

    let table = Table::new(rows, widths)
        .header(header)
        .column_spacing(1)
        .style(Color::Cyan)
        .block(Block::default().borders(Borders::ALL))
        .row_highlight_style(Style::new().on_black().bold())
        .column_highlight_style(Color::Gray)
        .cell_highlight_style(Style::new().reversed().yellow())
        .highlight_symbol("> ");

    f.render_stateful_widget(table, area, &mut app.table_state);
}

fn render_pagination_info(f: &mut Frame, app: &mut App, area: ratatui::layout::Rect) {
    let pagination_info = app.pagination_info();
    let pagination = Paragraph::new(pagination_info)
        .style(Style::default().fg(Color::Cyan))
        .block(Block::default().borders(Borders::ALL).title("Paginaiton"));
    f.render_widget(pagination, area);
}

fn render_popup_form(f: &mut Frame, app: &mut App, area: ratatui::layout::Rect) {
    if app.app_state == AppState::Editing {
        f.render_widget(Clear, area);
        let c_area = centered_rect(60, 25, area);
        let input = Paragraph::new(app.name_input.to_string())
            .style(Style::default().fg(Color::Yellow))
            .block(Block::default().borders(Borders::ALL).title("Task name"));

        f.render_widget(input, c_area);
    }
}

fn render_popup_status_list(f: &mut Frame, app: &mut App, area: Rect) {
    if app.app_state == AppState::SelectStatus {
        f.render_widget(Clear, area);
        let list = List::new(app.status_list)
            .style(Style::default().fg(Color::Yellow))
            .block(Block::default().borders(Borders::ALL).title("Task status"))
            .highlight_symbol("> ");
        let ceter_area = centered_rect(60, 25, area);
        f.render_stateful_widget(list, ceter_area, &mut app.list_status_state);
    }
}

fn render_edit_help(f: &mut Frame, app: &App, area: ratatui::layout::Rect) {
    if app.app_state == AppState::Editing || app.app_state == AppState::SelectStatus {
        f.render_widget(Clear, area);
        let msg = vec![
            Span::styled("Enter", Style::default().fg(Color::Green)),
            Span::raw(" save | "),
            Span::styled("Esc", Style::default().fg(Color::Red)),
            Span::raw(" cancel"),
        ];

        let help = Paragraph::new(Line::from(msg))
            .style(Style::default())
            .block(Block::default().borders(Borders::ALL).title("Controls"));
        f.render_widget(help, area);
    }
}

fn centered_rect(
    percent_x: u16,
    percent_y: u16,
    area: ratatui::layout::Rect,
) -> ratatui::layout::Rect {
    let popup_layout = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Percentage((100 - percent_y) / 2),
            Constraint::Percentage(percent_y),
            Constraint::Percentage((100 - percent_y) / 2),
        ])
        .split(area);

    Layout::default()
        .direction(Direction::Horizontal)
        .constraints([
            Constraint::Percentage((100 - percent_x) / 2),
            Constraint::Percentage(percent_x),
            Constraint::Percentage((100 - percent_x) / 2),
        ])
        .split(popup_layout[1])[1]
}
