Skip to content
use actix_web::{HttpRequest, Result as AwResult, get, web};

use super::render_layout;
use super::session_auth::get_username_from_request;
use crate::auth::{Exercise, ExerciseLog, Goal, HodisContext};

#[allow(clippy::too_many_arguments)]
pub fn render_dashboard_content(
    _user_id: &str,
    exercises: &[Exercise],
    goal: &Option<Goal>,
    total_points: f64,
    user_points: f64,
    recent_logs: &[ExerciseLog],
    favorite_ids: &[String],
    success_msg: Option<&str>,
) -> maud::Markup {
    maud::html! {
        @if let Some(msg) = success_msg {
            div class="ba b--green br2 pa3 bg-washed-green mb3" {
                p class="f6 dark-green ma0" { (msg) }
            }
        }

        @if let Some(g) = goal {
            div class="ba b--black-20 br2 pa3 mb4" {
                h2 class="f4 fw6 mb2" style="color: #e3001a;" { (g.name) }
                div class="w-100 bg-light-gray br2 mb2" style="height: 16px;" {
                    @let pct = if g.target_points > 0.0 { (total_points / g.target_points * 100.0).min(100.0) } else { 0.0 };
                    div class="bg-brand br2" style=(format!("width: {:.1}%; height: 16px; transition: width 0.3s ease;", pct)) {}
                }
                div class="flex justify-between" {
                    span class="f6 black-60" { (format!("{:.1} / {:.0} Punkte", total_points, g.target_points)) }
                    span class="f6 fw6" { (format!("{:.1}%", pct)) }
                }
            }
        }

        div class="mb4" {
            div class="flex justify-between items-center mb2" {
                h2 class="f4 fw6 black-70 ma0" { "Dein Beitrag" }
                span class="f6 fw6 brand" { (format!("{:.1} Pkt", user_points)) }
            }
        }

        div class="mb4" {
            h2 class="f4 fw6 mb2 black-70" { "Log" }

            @if exercises.is_empty() {
                div class="ba b--black-20 br2 pa3 tc" {
                    p class="f6 black-50" { "Noch keine Übungen verfügbar. Bitte einen Admin, welche hinzuzufügen!" }
                }
            } @else {
                form hx-post="/log-exercise" hx-target="#dashboard-content" hx-swap="outerHTML" class="ba b--black-20 br2 pa3" {
                    div class="mb3" {
                        label class="db f6 black-70 mb1" for="exercise" { "Übung" }
                        select name="exercise_id" id="exercise" required class="db w-100 pa2 ba b--black-30 br1" {
                            @for ex in exercises {
                                option value=(ex.id) { (ex.name) " (" (format!("{:.1} Pkt/{}", ex.points_per_unit, ex.unit)) ")" }
                            }
                        }
                    }
                    div class="flex mb3" {
                        div class="flex-auto mr2" {
                            label class="db f6 black-70 mb1" for="amount" { "Menge" }
                            input type="number" name="amount" id="amount" required step="0.1" min="0.1" class="db w-100 pa2 ba b--black-30 br1" placeholder="z.B. 5";
                        }
                    }
                    button type="submit" class="w-100 pa2 btn-brand br1 f5 fw6" { "Log" }
                }
            }
        }

        @if !exercises.is_empty() {
            div class="mb4" {
                h2 class="f4 fw6 mb2 black-70" { "Schnelleingabe" }
                div class="flex flex-wrap" style="gap: 0.5rem;" {
                    @for ex in exercises {
                        @let is_fav = favorite_ids.contains(&ex.id);
                        form hx-post="/toggle-favorite" hx-target="#dashboard-content" hx-swap="outerHTML" class="dib ma0" style="display:inline;" {
                            input type="hidden" name="exercise_id" value=(ex.id);
                            button
                                type="submit"
                                class={"pa2 br1 f6 pointer " @if is_fav { "btn-brand" } @else { "btn-outline" }}
                                style={"display: inline-block; margin-right: 0.25rem; margin-bottom: 0.25rem;"}
                            {
                                @if is_fav { "★ " } @else { "☆ " }
                                (ex.name)
                            }
                        }
                    }
                }
            }
        }

        @if !recent_logs.is_empty() {
            div class="mb4" {
                h2 class="f4 fw6 mb2 black-70" { "Letzte Aktivitäten" }
                div class="ba b--black-20 br2 overflow-hidden" {
                    @for log in recent_logs.iter().take(10) {
                        div class="flex pa2 bb b--black-10 items-center" {
                            div class="flex-auto" {
                                span class="f6 fw5" { (log.amount) }
                                @if let Some(ex) = exercises.iter().find(|e| e.id == log.exercise_id) {
                                    span class="f6 black-60 ml1" { (ex.unit) " " (ex.name) }
                                }
                            }
                            span class="f6 brand fw5 mr2" { (format!("+{:.1} Pkt", log.points_earned)) }
                            span class="f7 black-30" { (log.created_at.split('T').next().unwrap_or("")) }
                            form hx-post="/delete-log" hx-target="#dashboard-content" hx-swap="outerHTML" class="dib ma0" style="display:inline;" {
                                input type="hidden" name="id" value=(log.id);
                                button type="submit" class="f7 red bn bg-transparent pointer underline dim ml1" { "entfernen" }
                            }
                        }
                    }
                }
            }
        }
    }
}

#[get("/")]
pub async fn index(
    req: HttpRequest,
    auth_state: web::Data<HodisContext>,
) -> AwResult<maud::Markup> {
    let username = get_username_from_request(&req, &auth_state).await;

    if username.is_none() {
        let content = maud::html! {
            div class="flex flex-column items-center justify-center" style="min-height: calc(100vh - 8rem); padding: 2rem 1rem;" {
                div class="w-100 mw6 tc" {
                    h1 class="f2 fw6 mb3" style="color: #e3001a;" { "Hodis" }
                    h2 class="f4 fw3 black-60 mb4" { "Preseason-Challenge" }
                    p class="f6 black-50 mb4" {
                        "Erfasse deine Fitness-Aktivitäten und trage zu einem gemeinsamen Teamziel bei."
                    }
                    div class="flex justify-center" style="gap: 1rem;" {
                        a href="/auth/login" class="pa2 btn-brand br1 f5 fw6 no-underline" style="display:inline-block; min-width: 100px;" { "Anmelden" }
                        a href="/auth/signup" class="pa2 btn-outline br1 f5 fw6 no-underline" style="display:inline-block; min-width: 100px;" { "Registrieren" }
                    }
                }
            }
        };
        return Ok(render_layout(&content, None, false));
    }

    let user = match auth_state
        .db()
        .get_user_by_username(username.as_ref().unwrap())
        .await
    {
        Ok(Some(u)) => u,
        _ => {
            let content = maud::html! {
                p class="black-50" { "Fehler beim Laden der Nutzerdaten" }
            };
            return Ok(render_layout(&content, username.as_deref(), false));
        }
    };

    let exercises = auth_state
        .db()
        .get_all_exercises()
        .await
        .unwrap_or_default();
    let goal = auth_state.db().get_active_goal().await.unwrap_or_default();
    let total_points = auth_state.db().get_total_points().await.unwrap_or(0.0);
    let user_points = auth_state
        .db()
        .get_points_for_user(&user.id)
        .await
        .unwrap_or(0.0);
    let recent_logs = auth_state
        .db()
        .get_exercise_logs_for_user(&user.id)
        .await
        .unwrap_or_default();
    let favorite_ids = auth_state
        .db()
        .get_favorite_exercise_ids(&user.id)
        .await
        .unwrap_or_default();
    let is_admin = user.is_admin;

    let dashboard = render_dashboard_content(
        &user.id,
        &exercises,
        &goal,
        total_points,
        user_points,
        &recent_logs,
        &favorite_ids,
        None,
    );

    if req.headers().get("HX-Request").is_some() {
        Ok(maud::html! {
            div id="dashboard-content" hx-target="this" hx-swap="outerHTML" {
                (dashboard)
            }
        })
    } else {
        let content = maud::html! {
            div id="dashboard-content" hx-target="this" hx-swap="outerHTML" {
                (dashboard)
            }
        };
        Ok(render_layout(&content, username.as_deref(), is_admin))
    }
}