mod error;
mod login;
mod orthography;
mod phonemes;
mod phonotactics;

use leptos::*;
use leptos_mview::*;
use leptos_router::{Route, Router, Routes, A};
use leptos_use::{use_color_mode_with_options, ColorMode, UseColorModeOptions, UseColorModeReturn};
use phosphor_leptos::{Cube, Heart, Horse, IconWeight, List as Menu, Moon, Sun};

/// Toggle to switch between dark mode and light mode
#[component]
fn DarkModeToggle() -> impl IntoView {
    let UseColorModeReturn { mode, set_mode, .. } = use_color_mode_with_options(
        UseColorModeOptions::default()
            .custom_modes(vec!["fantasy".to_string()])
            .attribute("data-theme"),
    );

    let light_mode = ColorMode::Custom("fantasy".to_string());

    view! {
        <label class="flex cursor-pointer items-center gap-2">
            <Sun class="size-8"/>
            <input
                class="toggle theme-controller"
                type="checkbox"
                prop:checked=move || mode.get() == ColorMode::Dark
                on:input=move |_| {
                    set_mode
                        .update(|mode| {
                            *mode = match mode {
                                ColorMode::Auto => ColorMode::Dark,
                                ref mode if mode == &&light_mode => ColorMode::Dark,
                                ColorMode::Dark => light_mode.clone(),
                                _ => ColorMode::Dark,
                            };
                        })
                }
            />

            <Moon class="size-8"/>
        </label>
    }
}

/// Application navigation bar
#[component]
fn AppNavbar() -> impl IntoView {
    use crate::app::login::LoginAvatar;

    let nav_contents = move || {
        mview! {
            li {
                A href="demo" active_class="active" {
                    "Demo"
                }
            }
            li {
                details {
                    summary { "Phonology" }
                    ul class="bg-base-200 rounded-t-none" {
                        li {
                            details class="min-w-40" {
                                summary { "Phonetics" }
                                ul {
                                    li {
                                        A href="phonemes" active_class="active" {
                                            "Phonemes"
                                        }
                                    }
                                    li {
                                        A href="phonotactics" active_class="active" {
                                            "Phonotactics"
                                        }
                                    }
                                }
                            }
                        }
                        li {
                            A href="orthography" active_class="active" {
                                "Orthography"
                            }
                        }
                    }
                }
            }
        }
    };

    mview! {
        nav class="navbar bg-base-200" {
            div class="navbar-start" {
                div class="dropdown dropdown-hover" {
                    div role="button" tabindex=0 class="btn btn-ghost lg:hidden" {
                        Menu class="size-8";
                    }
                    ul tabindex=0 class="menu menu-sm dropdown-content z-[1] p-2 shadow bg-base-200 rounded-box w-52" {
                        {nav_contents()}
                    }
                }
                A href="" class="btn btn-ghost text-xl" { "Noteboek" }
            }
            div class="navbar-center hidden lg:flex" {
                ul class="menu menu-horizontal px-1 space-x-2" {
                    {nav_contents()}
                }
            }
            div class="navbar-end space-x-4" {
                LoginAvatar;
                DarkModeToggle;
            }
        }
    }
}

/// Test view for test stuff
#[component]
fn DemoView() -> impl IntoView {
    tracing::info!("woop");
    tracing::warn!("woop");
    tracing::error!("woop");
    let (count, set_count) = create_signal(0);
    mview! {
        div.prose.prose-zinc {
            h1 { "Hello, world! 🐢" }
            p { "Hello, world! 🐢" }
        }
        div {
            h1 { "Hello, world! 🐢" }
            p { "Hello, world! 🐢" }
        }
        button.btn.btn-primary on:click={move |_| set_count.update(|n| *n += 1)} {"Click me: " {move || count.get()}}
        Horse;
        Heart color="#AE2983" weight={IconWeight::Fill} size="32px";
        Cube color="teal" weight={IconWeight::Bold};
        Cube.text-slate-200 mirrored={true} weight={IconWeight::Duotone};
        Cube color="teal" weight={IconWeight::Fill};
        Cube color="teal" weight={IconWeight::Light};
        Cube color="teal" weight={IconWeight::Regular};
        Cube color="teal" weight={IconWeight::Thin};
    }
}

/// A container for the current user's status
#[derive(Clone, Copy, Debug)]
struct UserStatusResource(pub(crate) Resource<(), Result<login::UserStatus, gloo_net::Error>>);

/// Application main component
#[component]
pub fn App() -> impl IntoView {
    let user_status = UserStatusResource(create_local_resource(
        || (),
        |_| async move { login::fetch_user_status().await },
    ));
    provide_context(user_status);

    mview! {
        Router {
            AppNavbar;
            main {
                Routes {
                    Route path="demo" view=[DemoView];
                    Route path="login" view=[login::LoginView];
                    Route path="phonotactics" view=[phonotactics::PhonotacticsView];
                    Route path="phonemes" view=[phonemes::PhonemesView];
                    Route path="orthography" view=[orthography::OrthographyView];
                }
            }
        }
    }
}