//! Tool: project_list_members

use agent::{ToolContext, ToolDefinition, ToolError, ToolSchema};
use models::projects::project_members;
use models::users::User;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};

pub async fn list_members_exec(
    ctx: ToolContext,
    _args: serde_json::Value,
) -> Result<serde_json::Value, ToolError> {
    let project_id = ctx.project_id();
    let db = ctx.db();

    let members = project_members::Entity::find()
        .filter(project_members::Column::Project.eq(project_id))
        .all(db)
        .await
        .map_err(|e| ToolError::ExecutionError(e.to_string()))?;

    let user_ids: Vec<_> = members.iter().map(|m| m.user).collect();
    let users = User::find()
        .filter(models::users::user::Column::Uid.is_in(user_ids))
        .all(db)
        .await
        .map_err(|e| ToolError::ExecutionError(e.to_string()))?;

    let user_map: std::collections::HashMap<_, _> =
        users.into_iter().map(|u| (u.uid, u)).collect();

    let result: Vec<_> = members
        .into_iter()
        .filter_map(|m| {
            let user = user_map.get(&m.user)?;
            let role = m
                .scope_role()
                .map(|r| r.to_string())
                .unwrap_or_else(|_| "member".to_string());
            Some(serde_json::json!({
                "id": m.user.to_string(),
                "username": user.username,
                "display_name": user.display_name,
                "organization": user.organization,
                "role": role,
                "joined_at": m.joined_at.to_rfc3339(),
            }))
        })
        .collect();

    Ok(serde_json::to_value(result).map_err(|e| ToolError::ExecutionError(e.to_string()))?)
}

pub fn tool_definition() -> ToolDefinition {
    ToolDefinition::new("project_list_members")
        .description(
            "List all members in the current project. \
             Returns username, display name, organization, role, and join time.",
        )
        .parameters(ToolSchema {
            schema_type: "object".into(),
            properties: None,
            required: None,
        })
}
