// API測試 - 使用整合測試方式
// 因handler函數未公開，使用FileTree直接測試API邏輯

use markbase::filetree::node::NodeType;
use markbase::filetree::{mode, FileTree};
use rusqlite::Connection;
use uuid::Uuid;

fn temp_db() -> (Connection, String) {
    let user_id = format!("test_api_{}", Uuid::new_v4());
    let conn = FileTree::init_user_db(&user_id).unwrap();
    (conn, user_id)
}

#[test]
fn test_api_logic_create_folder() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let folder = FileTree::new_folder("API_Test_Folder", None);
    tree.insert_node(&conn, &folder).unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(loaded.nodes.len(), 1);
}

#[test]
fn test_api_logic_create_file() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let (file_node, register_sql) = FileTree::new_file_node(
        "test_api.mp4",
        "api_test_uuid",
        None,
        "test_api.mp4",
        Some(1024),
        Some("video/mp4"),
        None,
        None,
    );

    if let Some(sql) = register_sql {
        conn.execute_batch(&sql).unwrap();
    }

    tree.insert_node(&conn, &file_node).unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(loaded.nodes.len(), 1);
    assert_eq!(loaded.nodes[0].node_type, NodeType::File);
}

#[test]
fn test_api_logic_get_tree_with_mode() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let folder = FileTree::new_folder("Root", None);
    tree.insert_node(&conn, &folder).unwrap();

    //測試不同顯示模式
    let tree_mode = mode::get_mode("tree").unwrap();
    let tree_rendered = tree_mode.render(&tree);
    assert!(tree_rendered["nodes"].is_array());

    let list_mode = mode::get_mode("list").unwrap();
    let list_rendered = list_mode.render(&tree);
    assert!(list_rendered["nodes"].is_array());

    let grid_sm_mode = mode::get_mode("grid_sm").unwrap();
    let grid_sm_rendered = grid_sm_mode.render(&tree);
    assert!(grid_sm_rendered["nodes"].is_array());
}

#[test]
fn test_api_logic_update_node() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let mut folder = FileTree::new_folder("Original", None);
    tree.insert_node(&conn, &folder).unwrap();

    folder.label = "Updated_via_API".to_string();
    folder.icon = Some("🎬".to_string());
    tree.update_node(&conn, &folder.node_id, &folder).unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(loaded.nodes[0].label, "Updated_via_API");
    assert_eq!(loaded.nodes[0].icon, Some("🎬".to_string()));
}

#[test]
fn test_api_logic_delete_node() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let folder = FileTree::new_folder("ToDelete", None);
    let node_id = folder.node_id.clone();
    tree.insert_node(&conn, &folder).unwrap();

    assert_eq!(tree.nodes.len(), 1);

    tree.delete_node(&conn, &node_id).unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(loaded.nodes.len(), 0);
}

#[test]
fn test_api_logic_delete_all_nodes() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    for i in 1..=5 {
        let folder = FileTree::new_folder(&format!("Folder{}", i), None);
        tree.insert_node(&conn, &folder).unwrap();
    }

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(loaded.nodes.len(), 5);

    //模擬delete_all_nodes API邏輯
    for node in &loaded.nodes {
        conn.execute(
            "DELETE FROM file_nodes WHERE node_id = ?1",
            rusqlite::params![node.node_id],
        )
        .unwrap();
    }

    let after_delete = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(after_delete.nodes.len(), 0);
}

#[test]
fn test_api_logic_move_node() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let parent = FileTree::new_folder("Parent", None);
    let child = FileTree::new_folder("Child", Some(parent.node_id.clone()));

    tree.insert_node(&conn, &parent).unwrap();
    tree.insert_node(&conn, &child).unwrap();

    //移動到根目錄
    tree.move_node(&conn, &child.node_id, None).unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    let moved_node = loaded
        .nodes
        .iter()
        .find(|n| n.node_id == child.node_id)
        .unwrap();
    assert!(moved_node.parent_id.is_none());
}

#[test]
fn test_api_logic_update_alias() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let folder = FileTree::new_folder("Videos", None);
    tree.insert_node(&conn, &folder).unwrap();

    tree.update_node_alias(&conn, &folder.node_id, "zh_tw", "影片")
        .unwrap();
    tree.update_node_alias(&conn, &folder.node_id, "en_us", "Videos")
        .unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(
        loaded.nodes[0].aliases.get("zh_tw").map(|s| s.as_str()),
        Some("影片")
    );
    assert_eq!(
        loaded.nodes[0].aliases.get("en_us").map(|s| s.as_str()),
        Some("Videos")
    );
}

#[test]
fn test_api_logic_nested_structure() {
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    let root = FileTree::new_folder("Root", None);
    let level1 = FileTree::new_folder("Level1", Some(root.node_id.clone()));
    let level2 = FileTree::new_folder("Level2", Some(level1.node_id.clone()));

    tree.insert_node(&conn, &root).unwrap();
    tree.insert_node(&conn, &level1).unwrap();
    tree.insert_node(&conn, &level2).unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert_eq!(loaded.nodes.len(), 3);
}

#[test]
fn test_api_logic_get_modes() {
    let modes = mode::list_modes();

    assert_eq!(modes.len(), 4);

    let names: Vec<&str> = modes.iter().map(|m| m.name()).collect();
    assert!(names.contains(&"tree"));
    assert!(names.contains(&"list"));
    assert!(names.contains(&"grid_sm"));
    assert!(names.contains(&"grid_lg"));
}

#[test]
fn test_api_logic_file_info() {
    let (conn, _user_id) = temp_db();

    let file_uuid = "test_file_uuid_123";
    FileTree::add_location(&conn, file_uuid, "/path/to/file.mp4", Some("origin")).unwrap();

    let location: String = conn
        .query_row(
            "SELECT location FROM file_locations WHERE file_uuid = ?1",
            [file_uuid],
            |row| row.get(0),
        )
        .unwrap();

    assert_eq!(location, "/path/to/file.mp4");
}

#[test]
fn test_api_logic_restore_scenario() {
    //模擬restore_tree API邏輯
    let (conn, user_id) = temp_db();
    let mut tree = FileTree::load(&conn, &user_id).unwrap();

    //建立基本結構
    let home = FileTree::new_folder("Home", None);
    let movies = FileTree::new_folder("Movies", Some(home.node_id.clone()));

    tree.insert_node(&conn, &home).unwrap();
    tree.insert_node(&conn, &movies).unwrap();

    let loaded = FileTree::load(&conn, &user_id).unwrap();
    assert!(loaded.nodes.iter().any(|n| n.label == "Home"));
    assert!(loaded.nodes.iter().any(|n| n.label == "Movies"));
}
