use super::common;
use crate::{Message, SoftwareApp};
use cosmic::iced::{Alignment, Length};
use cosmic::{theme, widget, Element};
use rakuos_home::HomeApp;
use std::cmp;

pub fn view(app: &SoftwareApp, width: usize) -> Element<'_, Message> {
    let spacing = theme::active().cosmic().spacing;
    let mut column = widget::column::with_capacity(app.home_sections.len() * 2 + 1)
        .padding([0, spacing.space_s, spacing.space_m, spacing.space_s])
        .spacing(spacing.space_xxs)
        .width(Length::Fill);

    if app.home_sections.is_empty() && app.loading {
        return common::loading_page("Loading home page...");
    }

    for (section, apps) in &app.home_sections {
        if apps.is_empty() {
            continue;
        }

        column = column.push(widget::text::title4(section.title()));
        let limit = cmp::min(apps.len(), 20);
        column = column.push(home_grid(&apps[..limit], width));
    }

    if app.home_sections.is_empty() && !app.loading {
        column = column
            .push(widget::text::body("Could not load home page data."))
            .push(widget::button::suggested("Retry").on_press(Message::SearchClear));
    }

    column.into()
}

fn home_grid(apps: &[HomeApp], width: usize) -> Element<'_, Message> {
    let spacing = theme::active().cosmic().spacing;
    let metrics = HomeGridMetrics::new(width, 120, spacing.space_s);

    let mut grid = widget::grid();
    let mut col = 0;
    for app in apps {
        if col >= metrics.cols {
            grid = grid.insert_row();
            col = 0;
        }
        let id = app.id.clone();
        grid = grid.push(widget::mouse_area(home_card(app, metrics.item_width)).on_press(Message::SelectApp(id)));
        col += 1;
    }

    grid.column_spacing(metrics.column_spacing)
        .row_spacing(metrics.column_spacing)
        .into()
}

fn home_card(app: &HomeApp, width: usize) -> Element<'_, Message> {
    let spacing = theme::active().cosmic().spacing;
    widget::container(
        widget::column::with_children(vec![
            common::app_icon(&app.icon_path, &app.icon_url, 56),
            widget::text::caption(&app.name)
                .height(Length::Fixed(30.0))
                .into(),
        ])
        .align_x(Alignment::Center)
        .spacing(spacing.space_xxs),
    )
    .align_x(Alignment::Center)
    .align_y(Alignment::Center)
    .width(Length::Fixed(width as f32))
    .height(Length::Fixed(120.0))
    .padding(spacing.space_xs)
    .class(theme::Container::Card)
    .into()
}

struct HomeGridMetrics {
    cols: usize,
    item_width: usize,
    column_spacing: u16,
}

impl HomeGridMetrics {
    fn new(width: usize, min_width: usize, column_spacing: u16) -> Self {
        let width_m1 = width.saturating_sub(min_width);
        let cols_m1 = width_m1 / (min_width + column_spacing as usize);
        let cols = cols_m1 + 1;
        let item_width = width
            .saturating_sub(cols_m1 * column_spacing as usize)
            .checked_div(cols)
            .unwrap_or(min_width);
        Self {
            cols,
            item_width,
            column_spacing,
        }
    }
}
