package com.malk.service.integration;

import java.util.List;
import java.util.Map;

/**
 * 集成平台 - 用户管理原子接口
 * <p>
 * 文档来源：apifox 公开站；本接口覆盖鉴权 + 用户 CRUD（4 个写/查方法）。
 * <p>
 * 调用方约定：
 * <ul>
 *   <li>每个方法第一个参数 access_token 必传，调用方先调 {@link #getAccessToken()} 拿到再传入</li>
 *   <li>{@link #getAccessToken()} 内部由 UtilToken 缓存（namespace = {@link com.malk.server.integration.INTPConf#NS} / key = {@code "token:" + clientId}），过期前自动刷新</li>
 *   <li>响应失败由 INTPR.assertSuccess 抛 McException，全局拦截转 HTTP 4xx；调用方无需手动判 result</li>
 * </ul>
 * <p>
 * 典型用法：
 * <pre>
 * String token = client.getAccessToken();
 * client.createUser(token, "alice", "Pwd@123", null);
 * </pre>
 */
public interface INTPClient_User {

    /**
     * 获取 access_token（自带缓存）
     * <p>
     * 接口：POST /iam/token，grant_type=client_credentials
     *
     * @return Bearer 令牌字符串
     */
    String getAccessToken();

    /**
     * 创建用户
     * <p>
     * 接口：POST /iam/api/users
     * <p>
     * body_ext 可选字段（全部非必填）：
     * <ul>
     *   <li>name (String) - 用户全名，1-64 字符</li>
     *   <li>email (String) - 邮箱地址</li>
     *   <li>phone_number (String) - 手机号</li>
     *   <li>user_job_number (String) - 员工 ID，1-32 字符</li>
     *   <li>nick_name (String) - 昵称，1-64 字符</li>
     *   <li>picture (String) - 头像 base64 编码</li>
     *   <li>org_ids (List&lt;String&gt;) - 用户所属组织 ID 列表</li>
     *   <li>address (String) - 办公地点</li>
     *   <li>title (String) - 职位</li>
     *   <li>hired_date (String) - 入职日期（时间戳）</li>
     *   <li>tag (List&lt;Map&gt;) - 标签/角色信息，子字段：id/name/code/type/description/expression/app_id/app_name/app_code/group_is_default/group_description</li>
     *   <li>group_positions (List&lt;Map&gt;) - 部门属性，子字段：is_main/is_manager/position/user_code/org_id/org_name/user_order</li>
     * </ul>
     *
     * @param access_token Bearer token
     * @param username     登录名（必填，1-64 字符）
     * @param password     密码（必填）
     * @param body_ext     可选字段，传 null 表示不传
     * @return data 字段：{ sub, username, name, phone_number, user_job_number, email, nickname, org_ids, address, title, hired_date, created_at }
     */
    Map createUser(String access_token, String username, String password, Map body_ext);

    /**
     * 修改用户
     * <p>
     * 接口：PATCH /iam/api/user?username={username}
     * <p>
     * username 走 Query Param 而非 Path（**与 RESTful 惯例不同**）。
     * body_ext 字段同 createUser（除 username/password 外），不传字段保持服务端原值。
     *
     * @param access_token Bearer token
     * @param username     待修改用户的登录名（必填）
     * @param body_ext     待更新字段
     * @return result=true 时返回 true
     */
    Boolean updateUser(String access_token, String username, Map body_ext);

    /**
     * 批量删除用户（按登录名）
     * <p>
     * 接口：POST /iam/api/users/delete（**HTTP 方法是 POST，因 body 需带数组**）
     *
     * @param access_token Bearer token
     * @param usernames    待删除用户的登录名列表
     * @return result=true 时返回 true
     */
    Boolean deleteUsers(String access_token, List<String> usernames);

    /**
     * 查询用户列表
     * <p>
     * 接口：GET /iam/api/users
     * <p>
     * query 可选字段：
     * <ul>
     *   <li>q (String) - 姓名/用户名/手机/邮箱/工号 模糊查询</li>
     *   <li>org_id (String) - 组/部门 id</li>
     *   <li>page (Integer) - 页码</li>
     *   <li>size (Integer) - 每页条数</li>
     *   <li>attrs (String) - 用户属性，多个属性用逗号分隔</li>
     *   <li>return_users_in_sub_org (Boolean) - 是否查询子组/子部门用户，默认 true</li>
     * </ul>
     *
     * @param access_token Bearer token
     * @param query        查询条件，传 null 表示返回全量第一页
     * @return data 字段：{ items: [...], total, size, page, pages }
     */
    Map queryUsers(String access_token, Map query);
}
