use gloo_net::http::Request;
use leptos::prelude::*;
use leptos::task::spawn_local;
use serde::{Deserialize, Serialize};

use crate::config::use_config;

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SystemStatusData {
    pub nushell_installed: bool,
    pub workspace_configured: bool,
    pub servers_deployed: bool,
    pub taskservs_installed: bool,
    pub orchestrator_running: bool,
}

#[derive(Debug, Clone)]
pub struct StatusItem {
    pub name: &'static str,
    pub description: &'static str,
    pub icon: &'static str,
    pub status: bool,
    pub details: String,
    pub fix_instructions: Vec<&'static str>,
}

#[component]
pub fn SystemStatus(#[prop(optional)] auto_refresh: Option<bool>) -> impl IntoView {
    let (status_data, set_status_data) = signal(SystemStatusData::default());
    let (loading, set_loading) = signal(true);
    let (error, set_error) = signal(None::<String>);
    let (selected_item, set_selected_item) = signal(None::<usize>);

    let fetch_status = move || {
        spawn_local(async move {
            set_loading.set(true);
            set_error.set(None);

            match fetch_system_status().await {
                Ok(status) => {
                    set_status_data.set(status);
                    set_loading.set(false);
                }
                Err(e) => {
                    set_error.set(Some(format!("Failed to fetch status: {}", e)));
                    set_loading.set(false);
                }
            }
        });
    };

    // Initial fetch
    Effect::new(move |_| {
        fetch_status();
    });

    // Auto-refresh if enabled
    if auto_refresh.unwrap_or(true) {
        Effect::new(move |_| {
            spawn_local(async move {
                use wasm_bindgen_futures::JsFuture;
                use web_sys::window;

                loop {
                    if let Some(window) = window() {
                        let promise = js_sys::Promise::new(&mut |resolve, _reject| {
                            window
                                .set_timeout_with_callback_and_timeout_and_arguments_0(
                                    &resolve, 30_000,
                                )
                                .ok();
                        });
                        let _ = JsFuture::from(promise).await;
                    }
                    fetch_status();
                }
            });
        });
    }

    let status_items = move || {
        let data = status_data.get();
        vec![
            StatusItem {
                name: "Nushell",
                description: "Primary shell and scripting language",
                icon: "🐚",
                status: data.nushell_installed,
                details: if data.nushell_installed {
                    "Nushell 0.107.1+ is installed".to_string()
                } else {
                    "Nushell is not installed or version is too old".to_string()
                },
                fix_instructions: vec![
                    "Install Nushell:",
                    "  macOS: brew install nushell",
                    "  Linux: cargo install nu",
                    "Verify: nu --version",
                ],
            },
            StatusItem {
                name: "Workspace",
                description: "Infrastructure workspace configured",
                icon: "📁",
                status: data.workspace_configured,
                details: if data.workspace_configured {
                    "Workspace is properly configured".to_string()
                } else {
                    "No workspace configured".to_string()
                },
                fix_instructions: vec![
                    "Initialize workspace:",
                    "  provisioning workspace init",
                    "Or use the wizard to create one",
                ],
            },
            StatusItem {
                name: "Servers",
                description: "Cloud servers deployed",
                icon: "🖥️",
                status: data.servers_deployed,
                details: if data.servers_deployed {
                    "Servers are deployed and running".to_string()
                } else {
                    "No servers deployed yet".to_string()
                },
                fix_instructions: vec![
                    "Deploy servers:",
                    "  provisioning server create",
                    "Check Servers page for details",
                ],
            },
            StatusItem {
                name: "Task Services",
                description: "Infrastructure services installed",
                icon: "⚙️",
                status: data.taskservs_installed,
                details: if data.taskservs_installed {
                    "Task services are installed".to_string()
                } else {
                    "No task services installed".to_string()
                },
                fix_instructions: vec![
                    "Install task services:",
                    "  provisioning taskserv create kubernetes",
                    "See Taskservs page for available services",
                ],
            },
            StatusItem {
                name: "Orchestrator",
                description: "Orchestrator service running",
                icon: "🎯",
                status: data.orchestrator_running,
                details: if data.orchestrator_running {
                    "Orchestrator is running".to_string()
                } else {
                    "Orchestrator is not running".to_string()
                },
                fix_instructions: vec![
                    "Start orchestrator:",
                    "  cd provisioning/platform/orchestrator",
                    "  ./scripts/start-orchestrator.nu --background",
                    "Check logs if issues persist",
                ],
            },
        ]
    };

    let overall_status = move || {
        let items = status_items();
        let total = items.len();
        let complete = items.iter().filter(|item| item.status).count();
        (complete, total)
    };

    let overall_color = move || {
        let (complete, total) = overall_status();
        if complete == total {
            "#10b981" // green
        } else if complete >= total / 2 {
            "#f59e0b" // yellow
        } else {
            "#ef4444" // red
        }
    };

    view! {
        <div class="system-status" style="padding: 20px;">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
                <h2 style="margin: 0; font-size: 1.5rem; color: #1f2937;">
                    "System Status"
                </h2>
                <button
                    on:click=move |_| fetch_status()
                    style="padding: 8px 16px; background: #f3f4f6; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; color: #374151;"
                    disabled=move || loading.get()
                >
                    {move || if loading.get() { "🔄 Refreshing..." } else { "🔄 Refresh" }}
                </button>
            </div>

            // Overall progress
            <div style="background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                    <h3 style="margin: 0; font-size: 1.1rem; color: #1f2937;">
                        "Overall Progress"
                    </h3>
                    <span style=move || format!("font-size: 1.5rem; font-weight: 600; color: {};", overall_color())>
                        {move || {
                            let (complete, total) = overall_status();
                            format!("{}/{}", complete, total)
                        }}
                    </span>
                </div>
                <div style="background: #e5e7eb; height: 8px; border-radius: 4px; overflow: hidden;">
                    <div
                        style=move || {
                            let (complete, total) = overall_status();
                            let percent = (complete as f64 / total as f64 * 100.0) as usize;
                            format!(
                                "background: {}; height: 100%; width: {}%; transition: width 0.3s ease;",
                                overall_color(),
                                percent
                            )
                        }
                    />
                </div>
            </div>

            // Error message
            <Show when=move || error.get().is_some()>
                <div style="background: #fef2f2; border: 1px solid #fecaca; border-left: 4px solid #ef4444; padding: 15px; border-radius: 6px; margin-bottom: 20px;">
                    <p style="margin: 0; color: #991b1b;">
                        {move || error.get().unwrap_or_default()}
                    </p>
                </div>
            </Show>

            // Status cards
            <div style="display: grid; gap: 15px;">
                {move || status_items().into_iter().enumerate().map(|(idx, item)| {
                    let is_selected = move || selected_item.get() == Some(idx);
                    let item_for_show = item.clone();
                    let item_for_instructions = item.clone();
                    let fix_instructions = StoredValue::new(item.fix_instructions.clone());
                    view! {
                        <div
                            on:click=move |_| {
                                if selected_item.get() == Some(idx) {
                                    set_selected_item.set(None);
                                } else {
                                    set_selected_item.set(Some(idx));
                                }
                            }
                            style=move || format!(
                                "background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); cursor: pointer; transition: all 0.2s; border-left: 4px solid {};",
                                if item.status { "#10b981" } else { "#ef4444" }
                            )
                        >
                            <div style="padding: 20px;">
                                <div style="display: flex; align-items: start; gap: 15px;">
                                    <div style="font-size: 2rem;">
                                        {item.icon}
                                    </div>
                                    <div style="flex: 1;">
                                        <div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 5px;">
                                            <h4 style="margin: 0; font-size: 1.1rem; color: #1f2937;">
                                                {item.name}
                                            </h4>
                                            <span style=format!(
                                                "font-size: 1.2rem; color: {};",
                                                if item.status { "#10b981" } else { "#ef4444" }
                                            )>
                                                {if item.status { "✅" } else { "❌" }}
                                            </span>
                                        </div>
                                        <p style="margin: 0 0 8px 0; color: #6b7280; font-size: 0.9rem;">
                                            {item.description}
                                        </p>
                                        <p style="margin: 0; color: #374151; font-size: 0.85rem;">
                                            {item.details.clone()}
                                        </p>
                                    </div>
                                </div>
                            </div>

                            // Expanded details
                            <Show when=move || is_selected()>
                                <div style="padding: 0 20px 20px 20px; border-top: 1px solid #e5e7eb;">
                                    <Show when=move || !item_for_show.status>
                                        <div style="background: #fef3c7; padding: 15px; border-radius: 6px; margin-top: 15px; border-left: 4px solid #f59e0b;">
                                            <h5 style="margin: 0 0 10px 0; color: #92400e; font-size: 0.95rem; font-weight: 600;">
                                                "How to fix:"
                                            </h5>
                                            <div style="font-family: monospace; font-size: 0.85rem; color: #78350f; line-height: 1.8;">
                                                {fix_instructions.get_value().into_iter().map(|line| {
                                                    view! {
                                                        <div>{line}</div>
                                                    }
                                                }).collect_view()}
                                            </div>
                                        </div>
                                    </Show>
                                </div>
                            </Show>
                        </div>
                    }
                }).collect_view()}
            </div>

            <div style="margin-top: 20px; padding: 15px; background: #f0f9ff; border-radius: 8px; border-left: 4px solid #3b82f6;">
                <p style="margin: 0; color: #1e40af; font-size: 0.9rem;">
                    <strong>"💡 Tip:"</strong>" Click on any status card to see detailed fix instructions. Status refreshes automatically every 30 seconds."
                </p>
            </div>
        </div>
    }
}

/// Fetch system status from orchestrator API
async fn fetch_system_status() -> Result<SystemStatusData, String> {
    let config = use_config();

    // Check orchestrator
    let orchestrator_running =
        match Request::get(&format!("{}/health", config.api.orchestrator_url))
            .send()
            .await
        {
            Ok(response) => response.ok(),
            Err(_) => false,
        };

    // For now, simulate other checks
    // TODO: Add real API endpoints to check these
    let status = SystemStatusData {
        nushell_installed: true, // Assume true if UI is running
        workspace_configured: orchestrator_running,
        servers_deployed: false,    // TODO: Check via API
        taskservs_installed: false, // TODO: Check via API
        orchestrator_running,
    };

    Ok(status)
}
