//! 组织树 API
//!
//! 返回组织->项目->设备完整树状结构。
//! 根据用户角色进行数据隔离：总管理员看全部，企业管理员只看本组织。

use axum::extract::State;
use axum::Json;
use serde_json::{json, Value};

use super::organizations::{CabinetRow, OrganizationRow, ProjectRow, TreeNode};
use crate::error::AppError;
use crate::middleware::auth::{self, CurrentUser};
use crate::tcp::commands::AppState;

/// GET /api/organization-tree — 返回组织->项目->设备完整树
///
/// 需要 `device:view` 权限。
/// 数据隔离：总管理员看所有组织，企业管理员只看本组织下的数据。
pub async fn organization_tree(
    user: CurrentUser,
    State(state): State<AppState>,
) -> Result<Json<Value>, AppError> {
    auth::check_permission(&user, "device:view")?;

    let db = &state.mysql;

    // 根据角色过滤组织：总管理员看所有，企业管理员只看本组织
    let orgs: Vec<OrganizationRow> = if user.role_level >= 2 {
        sqlx::query_as(
            r#"SELECT id, name FROM organizations ORDER BY id"#,
        )
        .fetch_all(db)
        .await?
    } else if let Some(org_id) = user.organization_id {
        sqlx::query_as(
            r#"SELECT id, name FROM organizations WHERE id = ? ORDER BY id"#,
        )
        .bind(org_id)
        .fetch_all(db)
        .await?
    } else {
        // 无组织关联的用户看不到任何数据
        return Ok(Json(json!([])));
    };

    let projects: Vec<ProjectRow> = sqlx::query_as(
        r#"SELECT id, organization_id, name FROM projects ORDER BY id"#,
    )
    .fetch_all(db)
    .await?;

    let cabinets: Vec<CabinetRow> = sqlx::query_as(
        r#"SELECT id, project_id, abstract_id, imei, name, status
           FROM cabinets ORDER BY id"#,
    )
    .fetch_all(db)
    .await?;

    // 构建树
    let tree: Vec<TreeNode> = orgs
        .into_iter()
        .map(|org| {
            let org_projects: Vec<ProjectRow> = projects
                .iter()
                .filter(|p| p.organization_id == Some(org.id))
                .cloned()
                .collect();

            let children: Vec<TreeNode> = org_projects
                .into_iter()
                .map(|proj| {
                    let proj_cabinets: Vec<CabinetRow> = cabinets
                        .iter()
                        .filter(|c| c.project_id == Some(proj.id))
                        .cloned()
                        .collect();

                    let cab_nodes: Vec<TreeNode> = proj_cabinets
                        .into_iter()
                        .map(|c| TreeNode {
                            id: c.id,
                            name: c.name.unwrap_or_else(|| c.abstract_id.clone()),
                            children: None,
                            abstract_id: Some(c.abstract_id),
                            imei: Some(c.imei),
                            status: Some(c.status),
                        })
                        .collect();

                    TreeNode {
                        id: proj.id,
                        name: proj.name,
                        children: Some(cab_nodes),
                        abstract_id: None,
                        imei: None,
                        status: None,
                    }
                })
                .collect();

            TreeNode {
                id: org.id,
                name: org.name,
                children: Some(children),
                abstract_id: None,
                imei: None,
                status: None,
            }
        })
        .collect();

    Ok(Json(json!(tree)))
}
