use crate::models::HoldRole;
use crate::models::{self};
use leptos::prelude::*;

/// Displays a grid of the problem
#[component]
#[tracing::instrument(skip_all)]
pub fn Problem(
    /// Wall dimensions
    #[prop(into)]
    dim: Signal<models::WallDimensions>,

    /// Problem (route)
    #[prop(into)]
    problem: Signal<models::Problem>,
) -> impl IntoView {
    let holds = move || {
        let mut holds = vec![];
        for row in 0..dim.get().rows {
            for col in 0..dim.get().cols {
                let hold_position = models::HoldPosition { row, col };
                let role = move || problem.read().pattern.pattern.get(&hold_position).copied();
                let role = Signal::derive(role);
                let hold = view! { <Hold role /> };
                holds.push(hold);
            }
        }
        holds.into_iter().collect_view()
    };

    let style = move || {
        let grid_rows = crate::css::grid_rows_n(dim.get().rows);
        let grid_cols = crate::css::grid_cols_n(dim.get().cols);
        [grid_rows, grid_cols].join(" ")
    };

    view! {
        <div class="grid gap-8 grid-cols-[auto_1fr]">
            <div style=style class="grid gap-3">
                {holds}
            </div>
        </div>
    }
}

#[component]
#[tracing::instrument(skip_all)]
fn Hold(#[prop(into)] role: Signal<Option<HoldRole>>) -> impl IntoView {
    let class = move || {
        let role_classes = match role.get() {
            Some(HoldRole::Start) => Some("outline outline-offset-2 outline-green-500"),
            Some(HoldRole::Normal) => Some("outline outline-offset-2 outline-blue-500"),
            Some(HoldRole::Zone) => Some("outline outline-offset-2 outline-amber-500"),
            Some(HoldRole::End) => Some("outline outline-offset-2 outline-red-500"),
            None => Some("brightness-50"),
        };
        let mut s = "min-w-2 bg-sky-100 aspect-square rounded-sm".to_string();
        if let Some(c) = role_classes {
            s.push(' ');
            s.push_str(c);
        }
        s
    };

    view! { <div class=class /> }
}
