use leptos::prelude::*;
use orbital_style::inject_style;
use super::styles::progress_circle_styles;
use super::types::ProgressCircleColor;
#[component]
pub fn ProgressCircle(
#[prop(optional, into)]
class: MaybeProp<String>,
#[prop(into, optional)]
value: Signal<f64>,
#[prop(into, optional)]
color: Signal<ProgressCircleColor>,
#[prop(into, default = "120px".into())]
size: Signal<String>,
#[prop(optional)]
children: Option<Children>,
) -> impl IntoView {
inject_style("orbital-progress-circle", progress_circle_styles());
let stroke_width = 7;
let view_box_width = 100;
let radius = 50;
let begin_position_x = 0;
let begin_position_y = radius;
let end_position_x = 0;
let end_position_y = 2 * radius;
let center_x = 50 + stroke_width / 2;
let rail_path = format!(
"M {center_x},{center_x} m {begin_position_x},{begin_position_y} a {radius},{radius} 0 1 1 {end_position_x},{} a {radius},{radius} 0 1 1 {},{end_position_y}",
-end_position_y, -end_position_x
);
let len = std::f64::consts::PI * 2.0 * f64::from(radius);
let rail_stroke_dasharray = format!("{len}px {}px", view_box_width * 8);
let fill_path = rail_path.clone();
let fill_stroke_dasharray = Memo::new(move |_| {
let percentage = value.get().clamp(0.0, 100.0);
format!("{}px {}px", percentage / 100.0 * len, view_box_width * 8)
});
let class = MaybeProp::derive(move || {
let mut parts = vec!["orbital-progress-circle".to_string()];
if let Some(extra) = class.get() {
if !extra.is_empty() {
parts.push(extra);
}
}
Some(parts.join(" "))
});
view! {
<div
class=class
role="progressbar"
aria-valuemax="100"
aria-valuemin="0"
aria-valuenow=move || value.get()
style=("--orbital-progress-circle-size", move || size.get())
>
<svg viewBox="0 0 107 107" preserveAspectRatio="xMidYMid meet">
<g>
<path
d=rail_path
stroke-width=stroke_width
stroke-linecap="round"
fill="none"
style:stroke="var(--orb-color-surface-sunken)"
style:stroke-dasharray=rail_stroke_dasharray
/>
</g>
<g>
<path
class="orbital-progress-circle__fill"
class:orbital-progress-circle__fill--empty=move || value.get() <= 0.0
d=fill_path
stroke-width=stroke_width
stroke-linecap="round"
fill="none"
style:stroke=move || color.get().stroke_color()
style:stroke-dasharray=move || fill_stroke_dasharray.get()
/>
</g>
</svg>
{if let Some(children) = children {
view! { <div class="orbital-progress-circle__content">{children()}</div> }.into_any()
} else {
view! {
<div class="orbital-progress-circle__content orbital-progress-circle__content--text">
{move || format!("{} %", value.get().round() as i64)}
</div>
}
.into_any()
}}
</div>
}
}