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

use crate::api::iac::{fetch_detections as api_fetch_detections, DetectedTechnology};
use crate::components::LoadingSpinner;

/// Detection result from Infrastructure-from-Code analysis
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DetectionResult {
    pub id: String,
    pub project: String,
    pub timestamp: String,
    pub detections: Vec<DetectedTech>,
    pub completeness: f32,
    pub confidence: f32,
}

/// Individual detected technology
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DetectedTech {
    pub technology: String,
    pub confidence: f32,
    pub evidence: Vec<String>,
    pub version: Option<String>,
}

/// Detection Dashboard Page
#[component]
pub fn DetectionDashboardPage() -> impl IntoView {
    let (detections, set_detections) = signal::<Vec<DetectionResult>>(vec![]);
    let (loading, set_loading) = signal(true);
    let (error, set_error) = signal::<Option<String>>(None);
    let (selected_detection, set_selected_detection) = signal::<Option<String>>(None);

    // Load detections on mount
    Effect::new(move |_| {
        spawn_local(async move {
            set_loading.set(true);
            set_error.set(None);

            // TODO: Call API endpoint GET /api/detections
            match fetch_detections().await {
                Ok(results) => {
                    set_detections.set(results);
                }
                Err(e) => {
                    set_error.set(Some(format!("Failed to load detections: {}", e)));
                }
            }
            set_loading.set(false);
        });
    });

    view! {
        <div class="min-h-screen bg-base-200 p-6">
            <div class="container mx-auto">
                // Header
                <div class="mb-8">
                    <h1 class="text-4xl font-bold text-base-content mb-2">
                        "Technology Detection Dashboard"
                    </h1>
                    <p class="text-base-content/70">
                        "Infrastructure-from-Code analysis results and detected technologies"
                    </p>
                </div>

                <div class="space-y-6">
                    // Error display
                    <Show when=move || error.get().is_some()>
                        <div class="alert alert-error shadow-lg">
                            <div>
                                <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l-2-2m0 0l-2-2m2 2l2-2m-2 2l-2 2m8-8l-2 2m0 0l-2-2m2 2l2-2m-2 2l-2 2" />
                                </svg>
                                <span>{error.get().unwrap_or_default()}</span>
                            </div>
                        </div>
                    </Show>

                    // Loading state
                    <Show when=move || loading.get()>
                        <div class="flex justify-center items-center py-12">
                            <LoadingSpinner size="loading-lg" />
                        </div>
                    </Show>

                    // Detection results grid
                    <Show when=move || !detections.get().is_empty()>
                        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
                            {detections.get().into_iter().map(|detection| {
                                view! {
                                    <DetectionCard
                                        detection=detection.clone()
                                        on_select=Callback::new(move |_| {
                                            set_selected_detection.set(Some(detection.id.clone()));
                                        })
                                    />
                                }
                            }).collect_view()}
                        </div>
                    </Show>

                    <Show when=move || detections.get().is_empty() && !loading.get()>
                        <div class="alert">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current flex-shrink-0 w-6 h-6">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                            </svg>
                            <span>"No detections found. Run infrastructure analysis to detect technologies."</span>
                        </div>
                    </Show>

                    // Detail view for selected detection
                    <Show when=move || selected_detection.get().is_some()>
                        {selected_detection.get().and_then(|id| {
                            detections.get().into_iter().find(|d| d.id == id).map(|detection| {
                                view! {
                                    <DetectionDetail
                                        detection=detection
                                        on_close=Callback::new(move |_| {
                                            set_selected_detection.set(None);
                                        })
                                    />
                                }
                            })
                        })}
                    </Show>
                </div>
            </div>
        </div>
    }
}

/// Detection result card
#[component]
pub fn DetectionCard(detection: DetectionResult, on_select: Callback<()>) -> impl IntoView {
    view! {
        <div class="card bg-base-100 shadow-md hover:shadow-lg transition-shadow cursor-pointer">
            <div class="card-body">
                <div class="flex justify-between items-start mb-4">
                    <div>
                        <h2 class="card-title text-2xl">{detection.project.clone()}</h2>
                        <p class="text-sm text-base-content/60">{detection.timestamp}</p>
                    </div>
                    <div class="text-right badge badge-lg badge-primary">
                        {(detection.confidence * 100.0) as i32}"%"
                    </div>
                </div>

                // Completeness bar
                <div class="mb-4">
                    <div class="flex justify-between items-center mb-2">
                        <p class="text-sm font-semibold">"Infrastructure Completeness"</p>
                        <span class="text-sm badge badge-ghost">
                            {(detection.completeness * 100.0) as i32}"%"
                        </span>
                    </div>
                    <progress
                        class="progress progress-success w-full"
                        value={(detection.completeness * 100.0) as i32}
                        max="100"
                    ></progress>
                </div>

                // Detected technologies
                <div class="mb-4">
                    <p class="text-sm font-semibold mb-2">
                        "Detected Technologies ("
                        {detection.detections.len()}
                        ")"
                    </p>
                    <div class="flex flex-wrap gap-2">
                        {detection.detections.iter().take(5).map(|tech| {
                            view! {
                                <span class="badge badge-info">
                                    {tech.technology.clone()}
                                </span>
                            }
                        }).collect_view()}
                        {if detection.detections.len() > 5 {
                            view! {
                                <span class="badge badge-ghost">
                                    "+"
                                    {detection.detections.len() - 5}
                                    " more"
                                </span>
                            }.into_any()
                        } else {
                            ().into_any()
                        }}
                    </div>
                </div>

                // Action button
                <div class="card-actions justify-end">
                    <button
                        on:click=move |_| on_select.run(())
                        class="btn btn-primary btn-sm"
                    >
                        "View Details"
                    </button>
                </div>
            </div>
        </div>
    }
}

/// Detailed view of a detection result
#[component]
pub fn DetectionDetail(detection: DetectionResult, on_close: Callback<()>) -> impl IntoView {
    view! {
        <div class="card bg-base-100 shadow-lg">
            <div class="card-body">
                <div class="flex justify-between items-center mb-6">
                    <h2 class="card-title text-3xl">"Detection Details"</h2>
                    <button
                        on:click=move |_| on_close.run(())
                        class="btn btn-ghost btn-circle btn-sm"
                    >
                        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                        </svg>
                    </button>
                </div>

                // Detection metadata
                <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
                    <div class="stat bg-base-200 rounded">
                        <div class="stat-title">"Project"</div>
                        <div class="stat-value text-lg">{detection.project.clone()}</div>
                    </div>
                    <div class="stat bg-base-200 rounded">
                        <div class="stat-title">"Analyzed"</div>
                        <div class="stat-value text-lg">{detection.timestamp}</div>
                    </div>
                    <div class="stat bg-base-200 rounded">
                        <div class="stat-title">"Confidence"</div>
                        <div class="stat-value text-lg text-primary">{(detection.confidence * 100.0) as i32}"%"</div>
                    </div>
                    <div class="stat bg-base-200 rounded">
                        <div class="stat-title">"Completeness"</div>
                        <div class="stat-value text-lg text-success">{(detection.completeness * 100.0) as i32}"%"</div>
                    </div>
                </div>

                // Detailed technology list
                <div>
                    <h3 class="text-xl font-bold mb-4">
                        "Technologies ("
                        {detection.detections.len()}
                        ")"
                    </h3>
                    <div class="space-y-3">
                        {detection.detections.iter().map(|tech| {
                            view! {
                                <div class="border border-base-300 rounded-lg p-4">
                                    <div class="flex justify-between items-start mb-3">
                                        <div>
                                            <h4 class="font-semibold text-lg">{tech.technology.clone()}</h4>
                                            {tech.version.as_ref().map(|v| {
                                                let v = v.clone();
                                                view! {
                                                    <p class="text-sm text-base-content/60">"Version: " {v}</p>
                                                }
                                            })}
                                        </div>
                                        <span class="badge badge-lg badge-success">
                                            {(tech.confidence * 100.0) as i32}"%"
                                        </span>
                                    </div>
                                    <div class="mt-3">
                                        <p class="text-sm font-semibold mb-2">"Evidence:"</p>
                                        <ul class="list-disc list-inside space-y-1">
                                            {tech.evidence.iter().take(3).map(|ev| {
                                                let ev = ev.clone();
                                                view! {
                                                    <li class="text-sm text-base-content/80">{ev}</li>
                                                }
                                            }).collect_view()}
                                        </ul>
                                        {if tech.evidence.len() > 3 {
                                            view! {
                                                <p class="text-sm text-base-content/60 mt-2">
                                                    "+"
                                                    {tech.evidence.len() - 3}
                                                    " more evidence items"
                                                </p>
                                            }.into_any()
                                        } else {
                                            ().into_any()
                                        }}
                                    </div>
                                </div>
                            }
                        }).collect_view()}
                    </div>
                </div>
            </div>
        </div>
    }
}

/// Fetch detections from backend API
async fn fetch_detections() -> Result<Vec<DetectionResult>, String> {
    match api_fetch_detections(Some(1), Some(100)).await {
        Ok(response) => {
            // Transform API response to page types
            let items = response
                .items
                .into_iter()
                .map(|detection| {
                    // Transform DetectedTechnology to DetectedTech
                    let detections = detection
                        .detections
                        .into_iter()
                        .map(|tech| DetectedTech {
                            technology: tech.technology,
                            confidence: tech.confidence,
                            evidence: tech.evidence,
                            version: tech.version,
                        })
                        .collect();

                    DetectionResult {
                        id: detection.id,
                        project: detection.project,
                        timestamp: detection.timestamp,
                        detections,
                        completeness: detection.completeness,
                        confidence: detection.confidence,
                    }
                })
                .collect();

            Ok(items)
        }
        Err(e) => Err(e),
    }
}
