//! Create new prop page component.

use leptos::prelude::*;
#[cfg(feature = "hydrate")]
use leptos::task::spawn_local;

use crate::components::{Card, PageHeader};
use crate::utils::name_to_slug;

/// Prop new page component with file upload.
#[component]
pub fn PropsNewPage() -> impl IntoView {
    // Form state
    let (name, set_name) = signal(String::new());
    let (slug, set_slug) = signal(String::new());
    let (description, set_description) = signal(String::new());
    let (tags, set_tags) = signal(String::new());
    let (default_layer, set_default_layer) = signal("clothes".to_string());
    let (default_position, set_default_position) = signal(4i16); // Center position

    // UI state
    let (message, set_message) = signal(Option::<(String, bool)>::None);
    let (pending, set_pending) = signal(false);
    let (created_id, _set_created_id) = signal(Option::<String>::None);
    #[cfg(feature = "hydrate")]
    let set_created_id = _set_created_id;
    let (slug_auto, set_slug_auto) = signal(true);
    let (file_name, _set_file_name) = signal(Option::<String>::None);
    #[cfg(feature = "hydrate")]
    let set_file_name = _set_file_name;

    let update_name = move |ev: leptos::ev::Event| {
        let new_name = event_target_value(&ev);
        set_name.set(new_name.clone());
        if slug_auto.get() {
            set_slug.set(name_to_slug(&new_name));
        }
    };

    let on_file_change = move |ev: leptos::ev::Event| {
        #[cfg(feature = "hydrate")]
        {
            use wasm_bindgen::JsCast;
            let target = ev.target().unwrap();
            let input: web_sys::HtmlInputElement = target.dyn_into().unwrap();
            if let Some(files) = input.files() {
                if files.length() > 0 {
                    if let Some(file) = files.get(0) {
                        set_file_name.set(Some(file.name()));
                    }
                }
            }
        }
        #[cfg(not(feature = "hydrate"))]
        {
            let _ = ev;
        }
    };

    let on_submit = move |ev: leptos::ev::SubmitEvent| {
        ev.prevent_default();
        set_pending.set(true);
        set_message.set(None);

        #[cfg(feature = "hydrate")]
        {
            use wasm_bindgen::JsCast;

            // Get the form element
            let target = ev.target().unwrap();
            let form: web_sys::HtmlFormElement = target.dyn_into().unwrap();

            // Get the file input
            let file_input = form
                .query_selector("input[type='file']")
                .unwrap()
                .unwrap()
                .dyn_into::<web_sys::HtmlInputElement>()
                .unwrap();

            let files = file_input.files();
            if files.is_none() || files.as_ref().unwrap().length() == 0 {
                set_message.set(Some(("Please select a file".to_string(), false)));
                set_pending.set(false);
                return;
            }

            let file = files.unwrap().get(0).unwrap();

            // Build tags array from comma-separated string
            let tags_vec: Vec<String> = tags
                .get()
                .split(',')
                .map(|s| s.trim().to_string())
                .filter(|s| !s.is_empty())
                .collect();

            // Create metadata JSON
            let metadata = serde_json::json!({
                "name": name.get(),
                "slug": if slug.get().is_empty() { None::<String> } else { Some(slug.get()) },
                "description": if description.get().is_empty() { None::<String> } else { Some(description.get()) },
                "tags": tags_vec,
                "default_layer": default_layer.get(),
                "default_position": default_position.get()
            });

            // Create FormData
            let form_data = web_sys::FormData::new().unwrap();
            form_data
                .append_with_str("metadata", &metadata.to_string())
                .unwrap();
            form_data.append_with_blob("file", &file).unwrap();

            spawn_local(async move {
                use gloo_net::http::Request;

                let response = Request::post("/api/admin/props")
                    .body(form_data)
                    .unwrap()
                    .send()
                    .await;

                set_pending.set(false);

                match response {
                    Ok(resp) if resp.ok() => {
                        #[derive(serde::Deserialize)]
                        struct CreateResponse {
                            id: String,
                            #[allow(dead_code)]
                            name: String,
                            #[allow(dead_code)]
                            slug: String,
                        }
                        if let Ok(result) = resp.json::<CreateResponse>().await {
                            set_created_id.set(Some(result.id));
                            set_message.set(Some(("Prop created successfully!".to_string(), true)));
                        }
                    }
                    Ok(resp) => {
                        #[derive(serde::Deserialize)]
                        struct ErrorResp {
                            error: String,
                        }
                        if let Ok(err) = resp.json::<ErrorResp>().await {
                            set_message.set(Some((err.error, false)));
                        } else {
                            set_message.set(Some(("Failed to create prop".to_string(), false)));
                        }
                    }
                    Err(_) => {
                        set_message.set(Some(("Network error".to_string(), false)));
                    }
                }
            });
        }
    };

    view! {
        <PageHeader title="Create New Prop" subtitle="Upload a new server prop image">
            <a href="/admin/props" class="btn btn-secondary">"Back to Props"</a>
        </PageHeader>

        <Card>
            <form on:submit=on_submit>
                <h3 class="section-title">"Prop Details"</h3>

                <div class="form-row">
                    <div class="form-group">
                        <label for="name" class="form-label">
                            "Name" <span class="required">"*"</span>
                        </label>
                        <input
                            type="text"
                            id="name"
                            required=true
                            class="form-input"
                            placeholder="Smile Expression"
                            prop:value=move || name.get()
                            on:input=update_name
                        />
                    </div>
                    <div class="form-group">
                        <label for="slug" class="form-label">"Slug (URL)"</label>
                        <input
                            type="text"
                            id="slug"
                            pattern="[a-z0-9][a-z0-9\\-]*[a-z0-9]|[a-z0-9]"
                            class="form-input"
                            placeholder="smile-expression"
                            prop:value=move || slug.get()
                            on:input=move |ev| {
                                set_slug_auto.set(false);
                                set_slug.set(event_target_value(&ev));
                            }
                        />
                        <small class="form-help">"Optional. Auto-generated from name if not provided."</small>
                    </div>
                </div>

                <div class="form-group">
                    <label for="description" class="form-label">"Description"</label>
                    <textarea
                        id="description"
                        class="form-textarea"
                        placeholder="A happy smile expression for avatars"
                        prop:value=move || description.get()
                        on:input=move |ev| set_description.set(event_target_value(&ev))
                    ></textarea>
                </div>

                <div class="form-group">
                    <label for="tags" class="form-label">"Tags"</label>
                    <input
                        type="text"
                        id="tags"
                        class="form-input"
                        placeholder="expression, face, happy"
                        prop:value=move || tags.get()
                        on:input=move |ev| set_tags.set(event_target_value(&ev))
                    />
                    <small class="form-help">"Comma-separated list of tags"</small>
                </div>

                <h3 class="section-title">"Image File"</h3>

                <div class="form-group">
                    <label for="file" class="form-label">
                        "Image File" <span class="required">"*"</span>
                    </label>
                    <input
                        type="file"
                        id="file"
                        required=true
                        accept=".svg,.png,image/svg+xml,image/png"
                        class="form-input"
                        on:change=on_file_change
                    />
                    <small class="form-help">"SVG or PNG image file (64x64 recommended)"</small>
                    <Show when=move || file_name.get().is_some()>
                        <p class="text-muted">"Selected: " {move || file_name.get().unwrap_or_default()}</p>
                    </Show>
                </div>

                <h3 class="section-title">"Default Positioning"</h3>

                <div class="form-row">
                    <div class="form-group">
                        <label for="default_layer" class="form-label">"Layer"</label>
                        <select
                            id="default_layer"
                            class="form-select"
                            on:change=move |ev| set_default_layer.set(event_target_value(&ev))
                        >
                            <option value="skin" selected=move || default_layer.get() == "skin">"Skin (behind)"</option>
                            <option value="clothes" selected=move || default_layer.get() == "clothes">"Clothes (with)"</option>
                            <option value="accessories" selected=move || default_layer.get() == "accessories">"Accessories (front)"</option>
                        </select>
                        <small class="form-help">"Z-depth layer for prop placement"</small>
                    </div>
                    <div class="form-group">
                        <label for="default_position" class="form-label">"Position"</label>
                        <select
                            id="default_position"
                            class="form-select"
                            on:change=move |ev| {
                                if let Ok(v) = event_target_value(&ev).parse() {
                                    set_default_position.set(v);
                                }
                            }
                        >
                            <option value="0" selected=move || default_position.get() == 0>"Top-Left (0)"</option>
                            <option value="1" selected=move || default_position.get() == 1>"Top-Center (1)"</option>
                            <option value="2" selected=move || default_position.get() == 2>"Top-Right (2)"</option>
                            <option value="3" selected=move || default_position.get() == 3>"Middle-Left (3)"</option>
                            <option value="4" selected=move || default_position.get() == 4>"Center (4)"</option>
                            <option value="5" selected=move || default_position.get() == 5>"Middle-Right (5)"</option>
                            <option value="6" selected=move || default_position.get() == 6>"Bottom-Left (6)"</option>
                            <option value="7" selected=move || default_position.get() == 7>"Bottom-Center (7)"</option>
                            <option value="8" selected=move || default_position.get() == 8>"Bottom-Right (8)"</option>
                        </select>
                        <small class="form-help">"Grid position (3x3 grid)"</small>
                    </div>
                </div>

                <Show when=move || message.get().is_some()>
                    {move || {
                        let (msg, is_success) = message.get().unwrap_or_default();
                        let class = if is_success { "alert alert-success" } else { "alert alert-error" };
                        view! {
                            <div class=class role="alert">
                                <p>{msg}</p>
                            </div>
                        }
                    }}
                </Show>

                <Show when=move || created_id.get().is_some()>
                    {move || {
                        let id = created_id.get().unwrap_or_default();
                        view! {
                            <div class="alert alert-info">
                                <p>
                                    <a href=format!("/admin/props/{}", id)>
                                        "View prop"
                                    </a>
                                </p>
                            </div>
                        }
                    }}
                </Show>

                <div class="form-actions">
                    <button
                        type="submit"
                        class="btn btn-primary"
                        disabled=move || pending.get()
                    >
                        {move || if pending.get() { "Uploading..." } else { "Create Prop" }}
                    </button>
                </div>
            </form>
        </Card>
    }
}
