// SPDX-License-Identifier: Apache-2.0
//! Create Album — make a new album with a name and default visibility.

use leptos::ev::Event;
use leptos::prelude::*;
use leptos_router::hooks::use_navigate;
use wasm_bindgen::JsCast;

use crate::components::icons::{
    IconChevronLeft, IconKey, IconLink, IconLock, IconShield, IconUsers,
};
use crate::mock::{Album, Visibility};
use crate::state::{AppState, ToastKind};

#[derive(Clone, Copy, PartialEq, Eq)]
enum DefaultVisibility {
    OwnerOnly,
    FamilyKey,
    PrivateLink,
    Invitation,
}

impl DefaultVisibility {
    fn code(self) -> &'static str {
        match self {
            Self::OwnerOnly => "owner",
            Self::FamilyKey => "family",
            Self::PrivateLink => "link",
            Self::Invitation => "invite",
        }
    }
    fn title(self) -> &'static str {
        match self {
            Self::OwnerOnly => "Only you (recommended)",
            Self::FamilyKey => "Family key members",
            Self::PrivateLink => "By private link",
            Self::Invitation => "By personal invitation",
        }
    }
    fn description(self) -> &'static str {
        match self {
            Self::OwnerOnly => {
                "Nobody else can see this album. You can share it later, photo by photo or all at once."
            }
            Self::FamilyKey => "Everyone in your Family key can see this album automatically.",
            Self::PrivateLink => {
                "A revocable link, optionally password protected. You decide who receives it."
            }
            Self::Invitation => "Invite specific people one by one. No general link.",
        }
    }
    fn to_visibility(self) -> Visibility {
        match self {
            Self::OwnerOnly => Visibility::OwnerOnly,
            Self::FamilyKey => Visibility::SharedByFamilyKey,
            Self::PrivateLink => Visibility::SharedByLink,
            Self::Invitation => Visibility::SharedByInvitation,
        }
    }
}

#[component]
pub fn CreateAlbumPage() -> impl IntoView {
    let st = AppState::get();
    let navigate = use_navigate();

    let title = RwSignal::new(String::new());
    let description = RwSignal::new(String::new());
    let default_vis = RwSignal::new(DefaultVisibility::OwnerOnly);

    let on_title = move |ev: Event| {
        if let Some(target) = ev.target() {
            if let Ok(input) = target.dyn_into::<web_sys::HtmlInputElement>() {
                title.set(input.value());
            }
        }
    };
    let on_desc = move |ev: Event| {
        if let Some(target) = ev.target() {
            if let Ok(input) = target.dyn_into::<web_sys::HtmlTextAreaElement>() {
                description.set(input.value());
            }
        }
    };

    let can_save = Memo::new(move |_| !title.with(|t| t.trim().is_empty()));

    let make_nav_back = || {
        let nav = navigate.clone();
        move |_| nav("/albums", Default::default())
    };
    let nav_back = make_nav_back();
    let nav_back_cancel = make_nav_back();
    let do_save = {
        let nav = navigate.clone();
        move |_| {
            if !can_save.get() {
                return;
            }
            let id = format!(
                "alb_new_{}",
                title.with(|t| t
                    .chars()
                    .filter(|c| c.is_alphanumeric())
                    .take(8)
                    .collect::<String>()
                    .to_lowercase())
            );
            let new_album = Album {
                id: id.clone(),
                title: title.get().trim().to_string(),
                photo_count: 0,
                visibility: default_vis.get().to_visibility(),
                updated_at: "Just now".into(),
                cover_palette: ("#bfb2a0".into(), "#7a6a52".into()),
                is_received: false,
                received_from: None,
            };
            st.albums.update(|v| v.insert(0, new_album));
            st.toast(
                "Album created. Add photos when you are ready.",
                ToastKind::Success,
            );
            nav(&format!("/albums/{}", id), Default::default());
        }
    };

    view! {
        <div class="row" style="margin-bottom: 1.25rem; gap: 0.5rem;">
            <button class="btn btn--ghost btn--sm" on:click=nav_back>
                <IconChevronLeft size=16 />
                "Back to albums"
            </button>
        </div>

        <header class="screen-head">
            <div class="screen-head__eyebrow">"New album"</div>
            <h1 class="screen-head__title">"Start a new album."</h1>
            <p class="screen-head__lead">
                "Albums are private until you choose otherwise. You can change
                the default later, photo by photo or all at once."
            </p>
        </header>

        // Title
        <div class="form-block">
            <label class="form-block__label" for="album-title">"Album name"</label>
            <input
                id="album-title"
                class="form-block__input"
                type="text"
                value=move || title.get()
                on:input=on_title
                placeholder="e.g. Hana's first year"
                autocomplete="off"
            />
        </div>

        // Description
        <div class="form-block">
            <label class="form-block__label" for="album-desc">"Short description"</label>
            <p class="form-block__hint">"Optional. Just for yourself."</p>
            <textarea
                id="album-desc"
                class="form-block__input"
                rows="3"
                on:input=on_desc
                placeholder="What this album is about, who it's for..."
            >{move || description.get()}</textarea>
        </div>

        // Default visibility
        <div class="section-head">
            <h2 class="section-head__title">"Who should see this album by default?"</h2>
            <span class="section-head__rule"></span>
        </div>

        <div class="radio-cards">
            {[
                DefaultVisibility::OwnerOnly,
                DefaultVisibility::FamilyKey,
                DefaultVisibility::PrivateLink,
                DefaultVisibility::Invitation,
            ]
            .iter()
            .map(|&opt| {
                let is_selected = Memo::new(move |_| default_vis.get() == opt);
                let icon = match opt {
                    DefaultVisibility::OwnerOnly => view! { <IconLock size=14 /> }.into_any(),
                    DefaultVisibility::FamilyKey => view! { <IconKey size=14 /> }.into_any(),
                    DefaultVisibility::PrivateLink => view! { <IconLink size=14 /> }.into_any(),
                    DefaultVisibility::Invitation => view! { <IconUsers size=14 /> }.into_any(),
                };
                view! {
                    <label class="radio-card">
                        <input
                            type="radio"
                            name="default-vis"
                            value=opt.code()
                            prop:checked=move || is_selected.get()
                            on:change=move |_| default_vis.set(opt)
                        />
                        <div class="radio-card__body">
                            <div class="radio-card__title">
                                {icon}
                                " "
                                {opt.title()}
                            </div>
                            <div class="radio-card__desc">{opt.description()}</div>
                        </div>
                    </label>
                }
            })
            .collect_view()}
        </div>

        <div class="action-bar">
            <button class="btn btn--ghost" on:click=nav_back_cancel>"Cancel"</button>
            <button
                class="btn btn--sage"
                on:click=do_save
                prop:disabled=move || !can_save.get()
            >
                "Create album"
            </button>
        </div>

        <div class="trust-panel" style="margin-top: 2rem;">
            <div class="trust-panel__badges">
                <span class="badge badge--sage">
                    <IconShield size=12 />
                    "Private until you choose otherwise"
                </span>
                <span class="badge badge--sage">
                    <IconShield size=12 />
                    "Change visibility any time"
                </span>
            </div>
        </div>
    }
}
