use dioxus::prelude::*;
use freya_elements::{
    self as dioxus_elements,
    events::MouseEvent,
};
use freya_hooks::{
    use_applied_theme,
    FontTheme,
    TableTheme,
    TableThemeWith,
};
use crate::icons::ArrowIcon;
#[allow(non_snake_case)]
#[component]
fn TableArrow(order_direction: OrderDirection) -> Element {
    let TableTheme { arrow_fill, .. } = use_applied_theme!(None, table);
    let rotate = match order_direction {
        OrderDirection::Down => "0",
        OrderDirection::Up => "180",
    };
    rsx!(ArrowIcon {
        rotate: "{rotate}",
        fill: "{arrow_fill}"
    })
}
#[derive(Props, Clone, PartialEq)]
pub struct TableHeadProps {
    pub children: Element,
}
#[allow(non_snake_case)]
pub fn TableHead(TableHeadProps { children }: TableHeadProps) -> Element {
    rsx!(
        rect { width: "100%", {children} }
    )
}
#[derive(Props, Clone, PartialEq)]
pub struct TableBodyProps {
    pub children: Element,
}
#[allow(non_snake_case)]
pub fn TableBody(TableBodyProps { children }: TableBodyProps) -> Element {
    rsx!(
        rect { width: "100%", {children} }
    )
}
#[derive(PartialEq, Clone, Copy)]
enum TableRowState {
    Idle,
    Hovering,
}
#[derive(Props, Clone, PartialEq)]
pub struct TableRowProps {
    pub theme: Option<TableThemeWith>,
    children: Element,
}
#[allow(non_snake_case)]
pub fn TableRow(TableRowProps { theme, children }: TableRowProps) -> Element {
    let theme = use_applied_theme!(&theme, table);
    let mut state = use_signal(|| TableRowState::Idle);
    let TableTheme {
        divider_fill,
        hover_row_background,
        row_background,
        ..
    } = theme;
    let background = if state() == TableRowState::Hovering {
        hover_row_background
    } else {
        row_background
    };
    rsx!(
        rect {
            onmouseenter: move |_| state.set(TableRowState::Hovering),
            onmouseleave: move |_| state.set(TableRowState::Idle),
            direction: "horizontal",
            width: "fill",
            background: "{background}",
            {children}
        }
        rect {
            height: "1",
            width: "fill",
            background: "{divider_fill}"
        }
    )
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub enum OrderDirection {
    Up,
    #[default]
    Down,
}
#[derive(Props, Clone, PartialEq)]
pub struct TableCellProps {
    pub children: Element,
    pub onpress: Option<EventHandler<MouseEvent>>,
    #[props(into)]
    pub order_direction: Option<Option<OrderDirection>>,
    #[props(default = "5 25".to_string(), into)]
    pub padding: String,
    #[props(default = "35".to_string(), into)]
    pub height: String,
}
#[allow(non_snake_case)]
pub fn TableCell(props: TableCellProps) -> Element {
    let config = consume_context::<TableConfig>();
    let width = 100.0 / config.columns as f32;
    let TableCellProps {
        children,
        order_direction,
        padding,
        height,
        ..
    } = &props;
    rsx!(
        rect {
            overflow: "clip",
            padding: "{padding}",
            width: "{width}%",
            main_align: "end",
            cross_align: "center",
            height: "{height}",
            direction: "horizontal",
            onclick: move |e| {
                if let Some(onpress) = &props.onpress {
                    onpress.call(e);
                }
            },
            if let Some(order_direction) = &order_direction {
                rect {
                    margin: "10",
                    width: "10",
                    height: "10",
                    if let Some(order_direction) = &order_direction {
                        TableArrow {
                            order_direction: *order_direction
                        }
                    }
                }
            }
            {children}
        }
    )
}
#[derive(Props, Clone, PartialEq)]
pub struct TableProps {
    #[props(default = "fill".into())]
    pub height: String,
    pub theme: Option<TableThemeWith>,
    pub columns: usize,
    pub children: Element,
}
#[allow(non_snake_case)]
pub fn Table(
    TableProps {
        height,
        theme,
        columns,
        children,
    }: TableProps,
) -> Element {
    let TableTheme {
        background,
        corner_radius,
        divider_fill,
        font_theme: FontTheme { color },
        ..
    } = use_applied_theme!(&theme, table);
    provide_context(TableConfig { columns });
    rsx!(rect {
        overflow: "clip",
        color: "{color}",
        background: "{background}",
        corner_radius: "{corner_radius}",
        height: "{height}",
        border: "1 outer {divider_fill}",
        {children}
    })
}
#[doc(hidden)]
#[derive(Clone)]
pub struct TableConfig {
    columns: usize,
}