//! 数据导出 tab。

use dioxus::prelude::*;

use crate::components::forms::{FORM_SELECT_COMPACT_CLASS, FormSelect};
use crate::components::ui::BTN_PRIMARY_SM;

/// 数据导出 tab：按表/按查询导出 SQL/CSV，走 Axum 流式下载。
#[allow(non_snake_case)]
pub(super) fn ExportTab() -> Element {
    use crate::components::ui::ADMIN_CARD_CLASS;
    // 导出模式："table" / "query"
    let mut mode = use_signal(|| "table".to_string());
    let mut table_name = use_signal(String::new);
    let mut query = use_signal(String::new);
    let mut format = use_signal(|| "csv".to_string());
    let mut include_columns = use_signal(|| true);

    // 触发下载：构造 GET /api/database/export?... URL 并打开
    let do_export = move || {
        #[cfg(target_arch = "wasm32")]
        {
            let source = if mode().as_str() == "table" {
                format!("table:{}", table_name.read().trim())
            } else {
                format!("query:{}", query.read())
            };
            let url = format!(
                "/api/database/export?source={}&format={}&include_columns={}",
                urlencode(&source),
                format(),
                include_columns(),
            );
            if let Some(window) = web_sys::window() {
                let _ = window.open_with_url(&url);
            }
        }
    };

    rsx! {
        div { class: "space-y-4",
            div { class: "{ADMIN_CARD_CLASS} p-4 space-y-4",
                // 模式选择
                div { class: "flex items-center gap-4",
                    label { class: "flex items-center gap-2 text-sm text-paper-primary",
                        input {
                            r#type: "radio",
                            name: "export-mode",
                            checked: mode() == "table",
                            onchange: move |_| mode.set("table".to_string()),
                        }
                        "按表导出"
                    }
                    label { class: "flex items-center gap-2 text-sm text-paper-primary",
                        input {
                            r#type: "radio",
                            name: "export-mode",
                            checked: mode() == "query",
                            onchange: move |_| mode.set("query".to_string()),
                        }
                        "按查询导出"
                    }
                }

                // 表名输入
                if mode().as_str() == "table" {
                    div {
                        label { class: "block text-sm text-paper-secondary mb-1", "表名" }
                        input {
                            r#type: "text",
                            class: "w-full px-3 py-2 text-sm border border-paper-border rounded bg-paper-theme text-paper-primary font-mono",
                            placeholder: "如 posts",
                            value: "{table_name}",
                            oninput: move |e| table_name.set(e.value()),
                        }
                        p { class: "text-xs text-paper-secondary mt-1",
                            "仅支持 public schema 下的用户表，表名需为合法标识符"
                        }
                    }
                } else {
                    // 查询输入
                    div {
                        label { class: "block text-sm text-paper-secondary mb-1",
                            "SELECT 查询（只读）"
                        }
                        textarea {
                            class: "w-full px-3 py-2 text-sm border border-paper-border rounded bg-paper-theme text-paper-primary font-mono",
                            rows: "4",
                            placeholder: "SELECT id, title FROM posts WHERE published = true",
                            value: "{query}",
                            oninput: move |e| query.set(e.value()),
                        }
                    }
                }

                // 格式 + 选项
                div { class: "flex flex-wrap items-center gap-4",
                    div { class: "flex items-center gap-2",
                        span { class: "text-sm text-paper-secondary", "格式" }
                        FormSelect {
                            trigger_class: Some(FORM_SELECT_COMPACT_CLASS),
                            value: format(),
                            options: vec![
                                ("csv".to_string(), "CSV"),
                                ("sql".to_string(), "SQL (INSERT)"),
                            ],
                            onchange: move |v| format.set(v),
                        }
                    }
                    label { class: "flex items-center gap-1 text-sm text-paper-secondary",
                        input {
                            r#type: "checkbox",
                            class: "mr-1",
                            checked: include_columns(),
                            onchange: move |e| include_columns.set(e.checked()),
                        }
                        "包含列名（CSV 表头 / INSERT 列清单）"
                    }
                }

                button { class: "{BTN_PRIMARY_SM}", onclick: move |_| do_export(), "导出并下载" }
            }
            p { class: "text-xs text-paper-secondary",
                "导出走流式响应，大表不会占满内存。SQL 格式仅含 INSERT 语句（不含 DDL/schema）。"
            }
        }
    }
}
/// 简易 URL 编码（避免引入新依赖；仅编码导出参数里的特殊字符）。
/// 仅在 WASM 前端的导出按钮里用。
#[cfg(target_arch = "wasm32")]
fn urlencode(s: &str) -> String {
    let mut out = String::with_capacity(s.len());
    for b in s.bytes() {
        match b {
            b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
                out.push(b as char);
            }
            b' ' => out.push('+'),
            _ => out.push_str(&format!("%{:02X}", b)),
        }
    }
    out
}
