package com.kingdee.eas.custom.szpgm.osf.service;


import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.bsf.service.app.IHRMsfService;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取角色/角色成员信息接口（分管领导接口）
 * <p>
 * 根据修改日期、角色名称、角色编号等条件分页查询角色成员-角色关联信息，
 * 包含角色名称、编号、类型、状态以及人员关联关系等字段。
 * 数据来源于 T_WFR_PERSONROLE（人员-角色关联表），左连 T_WFR_WFROLE（工作流角色表）、
 * t_org_admin（行政组织表）、t_bd_person（员工基础信息表）等。
 * </p>
 *
 * <h3>关联数据表</h3>
 * <ul>
 *     <li><b>T_WFR_PERSONROLE</b>（prole）—— 人员-角色关联表，主表</li>
 *     <li><b>T_WFR_WFROLE</b>（role）—— 工作流角色表</li>
 *     <li><b>t_org_admin</b>（org）—— 行政组织表</li>
 *     <li><b>t_bd_person</b>（pe）—— 员工基础信息表</li>
 *     <li><b>t_bd_person</b>（dpe）—— 员工基础信息表（二次关联，取委托操作人信息）</li>
 * </ul>
 *
 * <h3>入参说明</h3>
 * <pre>
 * modifyDate - 最后修改日期（yyyy-MM-dd），同时过滤角色-角色成员关联的最后修改时间
 * name       - 角色名称（左模糊匹配）
 * code       - 角色编号（精确匹配）
 * size       - 每页条数（可选，默认100，最大1000）
 * page       - 页码（可选，默认1）
 * </pre>
 *
 * <h3>返回值说明</h3>
 * <pre>
 * code    - 状态码（200:成功, 500:异常）
 * msg     - 提示信息
 * page    - 当前页码
 * size    - 每页条数
 * data    - 角色负责人列表，每项包含：
 *   id          - 主键（人员-角色关联表主键）
 *   roleid      - 角色ID（关联 T_WFR_WFROLE.FID）
 *   orgCode     - 组织编号
 *   personCode  - 人员编号
 *   isinclude   - 是否包含下级
 *   isdele      - 是否委托
 *   deleperson  - 委托操作人编号
 *   rolename    - 角色名称
 *   rolenumber  - 角色编号
 *   roledescribe- 角色描述
 *   roletype    - 角色类型
 *   state       - 角色状态
 * </pre>
 *
 * @author szpgm
 * @since 1.0.0
 */
public class GetRoleSupervisorInfoOsfService  implements IHRMsfService {

    /**
     * 处理角色-角色成员信息查询请求
     *
     * @param context 上下文对象
     * @param map     入参，支持以下 key：
     *                <ul>
     *                  <li><b>modifyDate</b> - 最后修改日期（可选，yyyy-MM-dd）</li>
     *                  <li><b>name</b>       - 角色名称（可选，左模糊匹配）</li>
     *                  <li><b>code</b>       - 角色编号（可选，精确匹配）</li>
     *                  <li><b>page</b>       - 页码（可选，默认1）</li>
     *                  <li><b>size</b>       - 每页条数（可选，默认100，最大1000）</li>
     *                </ul>
     * @return Map&lt;String, Object&gt;，包含 code、msg、page、size、data 字段
     * @throws EASBizException 业务异常
     * @throws BOSException    平台异常
     */
    @Override
    public Object process(Context context, Map map) throws EASBizException, BOSException {
        Map<String, Object> result = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<>();

        // ---------- 入参解析 ----------
        String modifyDate = (String) map.get("modifyDate");
        String name = (String) map.get("name");
        String code = (String) map.get("code");

        // 每页条数（默认100，上限1000）
        int maxSize = 1000;
        int size = 100;
        if (map.get("size") != null) {
            if (map.get("size") instanceof Integer) {
                size = (int) map.get("size");
            } else if (map.get("size") instanceof String) {
                size = Integer.parseInt((String) map.get("size"));
            }
            size = Math.min(maxSize, size);
        }

        // 页码（默认1）
        int page = 1;
        if (map.get("page") != null) {
            if (map.get("page") instanceof Integer) {
                page = (int) map.get("page");
            } else if (map.get("page") instanceof String) {
                page = Integer.parseInt((String) map.get("page"));
            }
        }

        // ---------- 查询数据 ----------
        try {
            result.put("msg", "成功");
            result.put("code", "200");
            result.put("page", page);
            result.put("size", size);
            result.put("data", list);

            // 构建基础SQL并动态追加过滤条件
            StringBuilder sql = getSql();
            List<Object> paramArr = new ArrayList<>();

            // 修改日期过滤：角色或角色成员-关联最后修改时间 >= 指定日期
            if (StringUtils.isNotBlank(modifyDate)) {
                sql.append(" and (role.flastupdatetime >= ? or prole.flastupdatetime >= ? ) ");
                paramArr.add(modifyDate);
                paramArr.add(modifyDate);
            }

            // 角色名称左模糊匹配
            if (StringUtils.isNotBlank(name)) {
                sql.append(" and role.frolename_l2 like ? ");
                paramArr.add(name + "%");
            }

            // 角色编号精确匹配
            if (StringUtils.isNotBlank(code)) {
                sql.append(" and role.fnumber = ? ");
                paramArr.add(code);
            }

            // 分页：LIMIT 条数 OFFSET 偏移量
            sql.append(" order by role.fid desc LIMIT ? OFFSET ? ");
            paramArr.add(size);
            paramArr.add(((page - 1) * size));

            IRowSet rs = DbUtil.executeQuery(context, sql.toString(), paramArr.toArray());

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            while (rs.next()) {
                Map<String, Object> params = new HashMap<String, Object>();

                // 主键（人员-角色关联表主键）
                params.put("id", rs.getString("id"));
                // 角色ID
                params.put("roleid", rs.getString("roleid"));
                // 组织编号
                params.put("orgCode", rs.getString("orgCode"));
                // 人员编号
                params.put("personCode", rs.getString("personCode"));
                // 是否包含下级
                params.put("isinclude", rs.getString("isinclude"));
                // 是否委托
                params.put("isdele", rs.getString("isdele"));
                // 委托操作人编号
                params.put("deleperson", rs.getString("deleperson"));
                // 角色名称
                params.put("rolename", rs.getString("rolename"));
                // 角色编号
                params.put("rolenumber", rs.getString("rolenumber"));
                // 角色描述
                params.put("roledescribe", rs.getString("roledescribe"));
                // 角色类型
                params.put("roletype", rs.getString("roletype"));
                params.put("layerType", rs.getString("layerType"));

                // 角色状态
                params.put("state", rs.getString("state"));
                list.add(params);
            }
        } catch (Exception e) {
            // 异常时返回错误信息
            e.printStackTrace();
            result.put("msg", e.getMessage());
            result.put("code", "500");
        }
        return result;
    }

    /**
     * 构建角色负责人信息查询的基础SQL
     * <p>
     *     从 T_WFR_PERSONROLE（人员-角色关联表）出发，LEFT JOIN T_WFR_WFROLE（工作流角色表）、
     *     t_org_admin（行政组织表）、t_bd_person（员工基础信息表，两次关联分别取人员和委托操作人），
     *     查询角色与角色成员的关联信息，按修改日期、角色名称、角色编号过滤，支持分页。
     *     以 {@code where 1=1} 结尾，便于动态追加 AND 条件。
     * </p>
     * <p>
     * 涉及表：
     * <ul>
     *   <li><b>T_WFR_PERSONROLE</b>（prole）—— 人员-角色关联表，主表</li>
     *   <li><b>T_WFR_WFROLE</b>（role）—— 工作流角色表</li>
     *   <li><b>t_org_admin</b>（org）—— 行政组织表</li>
     *   <li><b>t_bd_person</b>（pe）—— 员工基础信息表</li>
     *   <li><b>t_bd_person</b>（dpe）—— 员工基础信息表（二次关联，取委托操作人信息）</li>
     * </ul>
     * </p>
     *
     * @return 包含占位符的基础SQL（以 {@code where 1=1} 结尾），过滤条件和分页参数由调用方动态追加
     */
    private static StringBuilder getSql() {
        StringBuilder sql = new StringBuilder();
        sql.append(" /*dialect*/ select ");
        sql.append(" prole.fid id, ");                             // 人员-角色关联表主键
        sql.append(" prole.froleid roleid, ");                     // 角色ID
        sql.append(" org.fnumber orgCode, ");                      // 组织编号
        sql.append(" pe.fnumber personCode, ");                    // 人员编号
        sql.append(" prole.fisinclude isinclude, ");               // 是否包含下级
        sql.append(" prole.fisdele isdele, ");                     // 是否委托
        sql.append(" dpe.fnumber deleperson, ");                   // 委托操作人编号
        sql.append(" role.frolename_l2 rolename, ");               // 角色名称
        sql.append(" role.fnumber rolenumber, ");                  // 角色编号
        sql.append(" role.froledescribe_l2 roledescribe, ");       // 角色描述
        sql.append(" role.froletype roletype, ");                  // 角色类型
        sql.append(" role.fstate state, "); //状态
        sql.append(" lt.fname_l2 layerType "); // 组织类型名称
        sql.append(" from T_WFR_PERSONROLE prole ");               // 人员-角色关联表（主表）
        sql.append(" LEFT JOIN T_WFR_WFROLE role on prole.FROLEID = role.FID ");   // 工作流角色表
        sql.append(" LEFT JOIN t_org_admin org on prole.forgid = org.FID ");       // 行政组织表
        sql.append(" LEFT JOIN t_bd_person pe on prole.fpsersonid = pe.FID ");     // 员工基础信息表
        sql.append(" LEFT JOIN t_bd_person dpe on prole.fdelepersonid = dpe.FID ");// 员工基础信息表（二次关联，取委托操作人）
        sql.append(" left join T_Org_LayerType lt on lt.fid = org.flayertypeid ");
        sql.append(" where 1=1 ");                                // 占位，便于后续动态拼接 AND 条件

        return sql;
    }
}
