use dioxus::prelude::*;
use dioxus_free_icons::icons::bs_icons::*;
use dioxus_free_icons::Icon;

use crate::app::Route;
use crate::components::attack_chain::AttackChainView;
use crate::components::severity_badge::SeverityBadge;
use crate::infrastructure::pentest::{
    export_pentest_report, fetch_attack_chain, fetch_pentest_findings, fetch_pentest_session,
    pause_pentest_session, resume_pentest_session,
};

#[component]
pub fn PentestSessionPage(session_id: String) -> Element {
    let sid_for_session = session_id.clone();
    let sid_for_findings = session_id.clone();
    let sid_for_chain = session_id.clone();

    let mut session = use_resource(move || {
        let id = sid_for_session.clone();
        async move { fetch_pentest_session(id).await.ok() }
    });
    let mut findings = use_resource(move || {
        let id = sid_for_findings.clone();
        async move { fetch_pentest_findings(id).await.ok() }
    });
    let mut attack_chain = use_resource(move || {
        let id = sid_for_chain.clone();
        async move { fetch_attack_chain(id).await.ok() }
    });

    let mut active_tab = use_signal(|| "findings".to_string());
    let mut show_export_modal = use_signal(|| false);
    let mut export_password = use_signal(String::new);
    let mut exporting = use_signal(|| false);
    let mut export_sha256 = use_signal(|| Option::<String>::None);
    let mut export_error = use_signal(|| Option::<String>::None);
    let mut poll_gen = use_signal(|| 0u32);

    // Extract session data
    let session_data = session.read().clone();
    let sess = session_data.as_ref().and_then(|s| s.as_ref());

    let session_status = sess
        .and_then(|s| s.data.get("status"))
        .and_then(|v| v.as_str())
        .unwrap_or("unknown")
        .to_string();
    let target_name = sess
        .and_then(|s| s.data.get("target_name"))
        .and_then(|v| v.as_str())
        .unwrap_or("Pentest Session")
        .to_string();
    let strategy = sess
        .and_then(|s| s.data.get("strategy"))
        .and_then(|v| v.as_str())
        .unwrap_or("-")
        .to_string();
    let tool_invocations = sess
        .and_then(|s| s.data.get("tool_invocations"))
        .and_then(|v| v.as_u64())
        .unwrap_or(0);
    let tool_successes = sess
        .and_then(|s| s.data.get("tool_successes"))
        .and_then(|v| v.as_u64())
        .unwrap_or(0);
    let findings_count = {
        let f = findings.read();
        match &*f {
            Some(Some(data)) => data.total.unwrap_or(0),
            _ => 0,
        }
    };
    let started_at = sess
        .and_then(|s| s.data.get("started_at"))
        .and_then(|v| v.as_str())
        .unwrap_or("-")
        .to_string();
    let completed_at = sess
        .and_then(|s| s.data.get("completed_at"))
        .and_then(|v| v.as_str())
        .unwrap_or("")
        .to_string();
    let success_rate = if tool_invocations == 0 {
        100.0
    } else {
        (tool_successes as f64 / tool_invocations as f64) * 100.0
    };

    let is_running = session_status == "running";
    let is_paused = session_status == "paused";
    let is_active = is_running || is_paused;

    // Poll while running or paused
    use_effect(move || {
        let _gen = *poll_gen.read();
        if is_active {
            spawn(async move {
                #[cfg(feature = "web")]
                gloo_timers::future::TimeoutFuture::new(3_000).await;
                #[cfg(not(feature = "web"))]
                tokio::time::sleep(std::time::Duration::from_secs(3)).await;
                findings.restart();
                attack_chain.restart();
                session.restart();
                let next = poll_gen.peek().wrapping_add(1);
                poll_gen.set(next);
            });
        }
    });

    // Severity counts from findings data
    let (sev_critical, sev_high, sev_medium, sev_low, sev_info, exploitable_count) = {
        let f = findings.read();
        match &*f {
            Some(Some(data)) => {
                let list = &data.data;
                let c = list
                    .iter()
                    .filter(|f| f.get("severity").and_then(|v| v.as_str()) == Some("critical"))
                    .count();
                let h = list
                    .iter()
                    .filter(|f| f.get("severity").and_then(|v| v.as_str()) == Some("high"))
                    .count();
                let m = list
                    .iter()
                    .filter(|f| f.get("severity").and_then(|v| v.as_str()) == Some("medium"))
                    .count();
                let l = list
                    .iter()
                    .filter(|f| f.get("severity").and_then(|v| v.as_str()) == Some("low"))
                    .count();
                let i = list
                    .iter()
                    .filter(|f| f.get("severity").and_then(|v| v.as_str()) == Some("info"))
                    .count();
                let e = list
                    .iter()
                    .filter(|f| {
                        f.get("exploitable")
                            .and_then(|v| v.as_bool())
                            .unwrap_or(false)
                    })
                    .count();
                (c, h, m, l, i, e)
            }
            _ => (0, 0, 0, 0, 0, 0),
        }
    };

    let status_style = match session_status.as_str() {
        "running" => "background: #16a34a; color: #fff;",
        "completed" => "background: #2563eb; color: #fff;",
        "failed" => "background: #dc2626; color: #fff;",
        "paused" => "background: #d97706; color: #fff;",
        _ => "background: var(--bg-tertiary); color: var(--text-secondary);",
    };

    // Export handler
    let sid_for_export = session_id.clone();
    let do_export = move |_| {
        let pw = export_password.read().clone();
        if pw.len() < 8 {
            export_error.set(Some("Password must be at least 8 characters".to_string()));
            return;
        }
        export_error.set(None);
        export_sha256.set(None);
        exporting.set(true);
        let sid = sid_for_export.clone();
        spawn(async move {
            // TODO: get real user info from auth context
            match export_pentest_report(sid.clone(), pw, String::new(), String::new()).await {
                Ok(resp) => {
                    export_sha256.set(Some(resp.sha256.clone()));
                    // Trigger download via JS
                    let js = format!(
                        r#"
                        try {{
                            var raw = atob("{}");
                            var bytes = new Uint8Array(raw.length);
                            for (var i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
                            var blob = new Blob([bytes], {{ type: "application/octet-stream" }});
                            var url = URL.createObjectURL(blob);
                            var a = document.createElement("a");
                            a.href = url;
                            a.download = "{}";
                            document.body.appendChild(a);
                            a.click();
                            document.body.removeChild(a);
                            URL.revokeObjectURL(url);
                        }} catch(e) {{ console.error("Download failed:", e); }}
                        "#,
                        resp.archive_base64, resp.filename,
                    );
                    document::eval(&js);
                }
                Err(e) => {
                    export_error.set(Some(format!("{e}")));
                }
            }
            exporting.set(false);
        });
    };

    rsx! {
        div { class: "back-nav",
            Link {
                to: Route::PentestDashboardPage {},
                class: "btn btn-ghost btn-back",
                Icon { icon: BsArrowLeft, width: 16, height: 16 }
                "Back to Pentest Dashboard"
            }
        }

        // Session header
        div { style: "display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 8px;",
            div {
                h2 { style: "margin: 0 0 4px 0;", "{target_name}" }
                div { style: "display: flex; gap: 8px; align-items: center; flex-wrap: wrap;",
                    span { class: "badge", style: "{status_style}", "{session_status}" }
                    span { class: "badge", style: "background: var(--bg-tertiary); color: var(--text-secondary);",
                        "{strategy}"
                    }
                    if is_running {
                        span { style: "font-size: 0.8rem; color: var(--text-secondary);",
                            Icon { icon: BsPlayCircle, width: 12, height: 12 }
                            " Running..."
                        }
                    }
                    if is_paused {
                        span { style: "font-size: 0.8rem; color: #d97706;",
                            Icon { icon: BsPauseCircle, width: 12, height: 12 }
                            " Paused"
                        }
                    }
                }
            }
            div { style: "display: flex; gap: 8px;",
                if is_running {
                    {
                        let sid_pause = session_id.clone();
                        rsx! {
                            button {
                                class: "btn btn-ghost",
                                style: "font-size: 0.85rem; color: #d97706; border-color: #d97706;",
                                onclick: move |_| {
                                    let sid = sid_pause.clone();
                                    spawn(async move {
                                        let _ = pause_pentest_session(sid).await;
                                        session.restart();
                                    });
                                },
                                Icon { icon: BsPauseCircle, width: 14, height: 14 }
                                " Pause"
                            }
                        }
                    }
                }
                if is_paused {
                    {
                        let sid_resume = session_id.clone();
                        rsx! {
                            button {
                                class: "btn btn-ghost",
                                style: "font-size: 0.85rem; color: #16a34a; border-color: #16a34a;",
                                onclick: move |_| {
                                    let sid = sid_resume.clone();
                                    spawn(async move {
                                        let _ = resume_pentest_session(sid).await;
                                        session.restart();
                                    });
                                },
                                Icon { icon: BsPlayCircle, width: 14, height: 14 }
                                " Resume"
                            }
                        }
                    }
                }
                button {
                    class: "btn btn-primary",
                    style: "font-size: 0.85rem;",
                    onclick: move |_| {
                        export_password.set(String::new());
                        export_sha256.set(None);
                        export_error.set(None);
                        show_export_modal.set(true);
                    },
                    Icon { icon: BsDownload, width: 14, height: 14 }
                    " Export Report"
                }
            }
        }

        // Summary cards
        div { class: "stat-cards", style: "margin-bottom: 20px;",
            div { class: "stat-card-item",
                div { class: "stat-card-value", "{findings_count}" }
                div { class: "stat-card-label",
                    Icon { icon: BsShieldExclamation, width: 14, height: 14 }
                    " Findings"
                }
            }
            div { class: "stat-card-item",
                div { class: "stat-card-value", style: "color: #dc2626;", "{exploitable_count}" }
                div { class: "stat-card-label",
                    Icon { icon: BsExclamationTriangle, width: 14, height: 14 }
                    " Exploitable"
                }
            }
            div { class: "stat-card-item",
                div { class: "stat-card-value", "{tool_invocations}" }
                div { class: "stat-card-label",
                    Icon { icon: BsWrench, width: 14, height: 14 }
                    " Tool Invocations"
                }
            }
            div { class: "stat-card-item",
                div { class: "stat-card-value", "{success_rate:.0}%" }
                div { class: "stat-card-label",
                    Icon { icon: BsCheckCircle, width: 14, height: 14 }
                    " Success Rate"
                }
            }
        }

        // Severity distribution bar
        div { class: "card", style: "margin-bottom: 20px; padding: 14px;",
            div { style: "display: flex; align-items: center; gap: 14px; flex-wrap: wrap;",
                span { style: "font-weight: 600; color: var(--text-secondary); font-size: 0.85rem;", "Severity Distribution" }
                span { class: "badge", style: "background: #dc2626; color: #fff;", "Critical: {sev_critical}" }
                span { class: "badge", style: "background: #ea580c; color: #fff;", "High: {sev_high}" }
                span { class: "badge", style: "background: #d97706; color: #fff;", "Medium: {sev_medium}" }
                span { class: "badge", style: "background: #2563eb; color: #fff;", "Low: {sev_low}" }
                span { class: "badge", style: "background: #6b7280; color: #fff;", "Info: {sev_info}" }
            }
        }

        // Session details row
        div { class: "card", style: "margin-bottom: 20px; padding: 14px;",
            div { style: "display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; font-size: 0.85rem;",
                div {
                    span { style: "color: var(--text-secondary);", "Started: " }
                    span { "{started_at}" }
                }
                if !completed_at.is_empty() {
                    div {
                        span { style: "color: var(--text-secondary);", "Completed: " }
                        span { "{completed_at}" }
                    }
                }
                div {
                    span { style: "color: var(--text-secondary);", "Tools: " }
                    span { "{tool_successes}/{tool_invocations} successful" }
                }
            }
        }

        // Tabs: Findings / Attack Chain
        div { class: "card", style: "overflow: hidden;",
            div { style: "display: flex; border-bottom: 1px solid var(--border-color);",
                button {
                    style: if *active_tab.read() == "findings" {
                        "flex: 1; padding: 12px; background: none; border: none; border-bottom: 2px solid #2563eb; color: var(--text-primary); cursor: pointer; font-weight: 600; font-size: 0.9rem;"
                    } else {
                        "flex: 1; padding: 12px; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-secondary); cursor: pointer; font-size: 0.9rem;"
                    },
                    onclick: move |_| active_tab.set("findings".to_string()),
                    Icon { icon: BsShieldExclamation, width: 14, height: 14 }
                    " Findings ({findings_count})"
                }
                button {
                    style: if *active_tab.read() == "chain" {
                        "flex: 1; padding: 12px; background: none; border: none; border-bottom: 2px solid #2563eb; color: var(--text-primary); cursor: pointer; font-weight: 600; font-size: 0.9rem;"
                    } else {
                        "flex: 1; padding: 12px; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-secondary); cursor: pointer; font-size: 0.9rem;"
                    },
                    onclick: move |_| {
                        active_tab.set("chain".to_string());
                    },
                    Icon { icon: BsDiagram3, width: 14, height: 14 }
                    " Attack Chain"
                }
            }

            // Tab content
            div { style: "padding: 16px;",
                if *active_tab.read() == "findings" {
                    // Findings list
                    match &*findings.read() {
                        Some(Some(data)) => {
                            let finding_list = &data.data;
                            if finding_list.is_empty() {
                                rsx! {
                                    div { style: "text-align: center; color: var(--text-secondary); padding: 24px;",
                                        if is_running {
                                            p { "Scan in progress — findings will appear here." }
                                        } else {
                                            p { "No findings discovered." }
                                        }
                                    }
                                }
                            } else {
                                rsx! {
                                    div { style: "display: flex; flex-direction: column; gap: 10px;",
                                        for finding in finding_list {
                                            {
                                                let title = finding.get("title").and_then(|v| v.as_str()).unwrap_or("Untitled").to_string();
                                                let severity = finding.get("severity").and_then(|v| v.as_str()).unwrap_or("info").to_string();
                                                let vuln_type = finding.get("vuln_type").and_then(|v| v.as_str()).unwrap_or("-").to_string();
                                                let endpoint = finding.get("endpoint").and_then(|v| v.as_str()).unwrap_or("").to_string();
                                                let method = finding.get("method").and_then(|v| v.as_str()).unwrap_or("").to_string();
                                                let exploitable = finding.get("exploitable").and_then(|v| v.as_bool()).unwrap_or(false);
                                                let description = finding.get("description").and_then(|v| v.as_str()).unwrap_or("").to_string();
                                                let remediation = finding.get("remediation").and_then(|v| v.as_str()).unwrap_or("").to_string();
                                                let cwe = finding.get("cwe").and_then(|v| v.as_str()).unwrap_or("").to_string();
                                                let linked_sast = finding.get("linked_sast_finding_id").and_then(|v| v.as_str()).unwrap_or("").to_string();

                                                rsx! {
                                                    div { style: "background: var(--bg-tertiary); border-radius: 8px; padding: 14px;",
                                                        // Header
                                                        div { style: "display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;",
                                                            div { style: "display: flex; align-items: center; gap: 8px;",
                                                                SeverityBadge { severity: severity }
                                                                span { style: "font-weight: 600; font-size: 0.95rem;", "{title}" }
                                                            }
                                                            div { style: "display: flex; gap: 4px;",
                                                                if exploitable {
                                                                    span { class: "badge", style: "background: #dc2626; color: #fff; font-size: 0.7rem;", "Exploitable" }
                                                                }
                                                                span { class: "badge", style: "font-size: 0.7rem;", "{vuln_type}" }
                                                            }
                                                        }
                                                        // Endpoint
                                                        if !endpoint.is_empty() {
                                                            div { style: "font-family: monospace; font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 6px;",
                                                                "{method} {endpoint}"
                                                            }
                                                        }
                                                        // CWE
                                                        if !cwe.is_empty() {
                                                            div { style: "font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 4px;",
                                                                "CWE: {cwe}"
                                                            }
                                                        }
                                                        // Description
                                                        if !description.is_empty() {
                                                            div { style: "font-size: 0.85rem; margin-bottom: 8px; line-height: 1.5;",
                                                                "{description}"
                                                            }
                                                        }
                                                        // Remediation
                                                        if !remediation.is_empty() {
                                                            div { style: "font-size: 0.8rem; padding: 8px 10px; background: rgba(56, 189, 248, 0.08); border-left: 3px solid #38bdf8; border-radius: 0 4px 4px 0; margin-top: 6px;",
                                                                span { style: "font-weight: 600;", "Recommendation: " }
                                                                "{remediation}"
                                                            }
                                                        }
                                                        // Linked SAST
                                                        if !linked_sast.is_empty() {
                                                            div { style: "font-size: 0.75rem; color: var(--text-secondary); margin-top: 4px;",
                                                                "Correlated SAST finding: "
                                                                code { "{linked_sast}" }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        Some(None) => rsx! { p { style: "color: var(--text-secondary);", "Failed to load findings." } },
                        None => rsx! { p { style: "color: var(--text-secondary);", "Loading..." } },
                    }
                } else {
                    // Attack chain visualization
                    match &*attack_chain.read() {
                        Some(Some(data)) => {
                            let steps = &data.data;
                            if steps.is_empty() {
                                rsx! {
                                    div { style: "text-align: center; color: var(--text-secondary); padding: 24px;",
                                        if is_running {
                                            p { "Scan in progress — attack chain will appear here." }
                                        } else {
                                            p { "No attack chain steps recorded." }
                                        }
                                    }
                                }
                            } else {
                                rsx! { AttackChainView {
                                    steps: steps.clone(),
                                    is_running: is_running,
                                    session_findings: findings_count as usize,
                                    session_tool_invocations: tool_invocations as usize,
                                    session_success_rate: success_rate,
                                } }
                            }
                        },
                        Some(None) => rsx! { p { style: "color: var(--text-secondary);", "Failed to load attack chain." } },
                        None => rsx! { p { style: "color: var(--text-secondary);", "Loading..." } },
                    }
                }
            }
        }

        // Export modal
        if *show_export_modal.read() {
            div {
                style: "position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; z-index: 1000;",
                onclick: move |_| show_export_modal.set(false),
                div {
                    style: "background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 12px; padding: 24px; width: 480px; max-width: 90vw;",
                    onclick: move |e| e.stop_propagation(),
                    h3 { style: "margin: 0 0 4px 0;", "Export Pentest Report" }
                    p { style: "font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 16px;",
                        "The report will be exported as a password-protected ZIP archive (AES-256) containing a professional HTML report and raw findings data. Open with any standard archive tool."
                    }

                    div { style: "margin-bottom: 14px;",
                        label { style: "display: block; font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 4px;",
                            "Encryption Password"
                        }
                        input {
                            class: "chat-input",
                            style: "width: 100%; padding: 8px;",
                            r#type: "password",
                            placeholder: "Minimum 8 characters",
                            value: "{export_password}",
                            oninput: move |e| {
                                export_password.set(e.value());
                                export_error.set(None);
                            },
                        }
                    }

                    if let Some(err) = &*export_error.read() {
                        div { style: "padding: 8px 12px; background: rgba(220, 38, 38, 0.1); border: 1px solid #dc2626; border-radius: 6px; color: #dc2626; font-size: 0.85rem; margin-bottom: 14px;",
                            "{err}"
                        }
                    }

                    if let Some(sha) = &*export_sha256.read() {
                        {
                            let sha_copy = sha.clone();
                            rsx! {
                                div { style: "padding: 10px 12px; background: rgba(22, 163, 74, 0.08); border: 1px solid #16a34a; border-radius: 6px; margin-bottom: 14px;",
                                    div { style: "font-size: 0.8rem; font-weight: 600; color: #16a34a; margin-bottom: 4px;",
                                        Icon { icon: BsCheckCircle, width: 12, height: 12 }
                                        " Archive downloaded successfully"
                                    }
                                    div { style: "font-size: 0.75rem; color: var(--text-secondary); margin-bottom: 2px;",
                                        "SHA-256 Checksum:"
                                    }
                                    div { style: "display: flex; align-items: center; gap: 6px;",
                                        div { style: "flex: 1; font-family: monospace; font-size: 0.7rem; word-break: break-all; color: var(--text-primary); background: var(--bg-primary); padding: 6px 8px; border-radius: 4px;",
                                            "{sha_copy}"
                                        }
                                        button {
                                            class: "btn btn-ghost",
                                            style: "padding: 4px 8px; font-size: 0.75rem; flex-shrink: 0;",
                                            onclick: move |_| {
                                                let js = format!(
                                                    "navigator.clipboard.writeText('{}');",
                                                    sha_copy
                                                );
                                                document::eval(&js);
                                            },
                                            Icon { icon: BsClipboard, width: 12, height: 12 }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    div { style: "display: flex; justify-content: flex-end; gap: 8px;",
                        button {
                            class: "btn btn-ghost",
                            onclick: move |_| show_export_modal.set(false),
                            "Close"
                        }
                        button {
                            class: "btn btn-primary",
                            disabled: *exporting.read() || export_password.read().len() < 8,
                            onclick: do_export,
                            if *exporting.read() { "Encrypting..." } else { "Export" }
                        }
                    }
                }
            }
        }
    }
}
