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.*;

/**
 * 获取岗位信息接口
 * <p>
 * 根据修改日期、岗位名称、岗位编号等条件分页查询岗位基础信息，
 * 包含岗位名称、编号、所属组织、上级岗位、是否负责人岗等字段。
 * 数据来源于 t_org_position（岗位表），左连 t_org_admin（行政组织表）、
 * t_org_position（二次关联，取上级岗位信息），按修改时间降序排列。
 * </p>
 *
 * <h3>关联数据表</h3>
 * <ul>
 *     <li><b>t_org_position</b>（pos）—— 岗位表，主表</li>
 *     <li><b>t_org_admin</b>（org）—— 行政组织表</li>
 *     <li><b>t_org_position</b>（ppos）—— 岗位表（二次关联，通过 fparentid 取上级岗位信息）</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              - 主键
 *   name            - 岗位名称
 *   code            - 岗位编号
 *   department      - 所属组织编号
 *   parent          - 上级岗位编号
 *   vice            - 部门副职（1:是, 0:否）
 *   disporder       - 显示顺序
 *   description     - 备注
 *   isrespposition  - 是否负责人岗（1:是, 0:否）
 * </pre>
 *
 * @author szpgm
 * @since 1.0.0
 */
public class GetPosInfoOsfService  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 pos.flastupdatetime >= ? ");
                paramArr.add(modifyDate);
                //paramArr.add(modifyDate);
            }

            // 岗位名称左模糊匹配
            if (StringUtils.isNotBlank(name)) {
                sql.append(" and pos.fname_l2 like ? ");
                paramArr.add(name + "%");
            }
            // 岗位编号精确匹配
            if (StringUtils.isNotBlank(code)) {
                sql.append(" and pos.fnumber = ? ");
                paramArr.add(code);
            }

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

            // 执行查询
            IRowSet rs = DbUtil.executeQuery(context, sql.toString(), paramArr.toArray());
            while (rs.next()) {
                String id = rs.getString("id");
                Map<String, Object> params = new HashMap<>();
                // 是否负责人岗（1:是, 0:否）
                params.put("isrespposition", rs.getString("isrespposition"));
                // 岗位名称
                params.put("name", rs.getString("name"));
                // 所属组织编号
                params.put("department", rs.getString("department"));
                // 岗位编号
                params.put("code", rs.getString("code"));
                // 上级岗位编号
                params.put("parent", rs.getString("parent"));
                // 部门副职（1:是, 0:否）
                params.put("vice", rs.getString("vice"));
                // 显示顺序
                params.put("disporder", rs.getString("disporder"));
                // 主键ID
                params.put("id", rs.getString("id"));
                // 备注
                params.put("description", rs.getString("description"));
                list.add(params);
            }
            // 以 list 覆盖 result 中的 data（确保引用一致）
            result.put("data", list);
        } catch (Exception e) {
            // 异常时返回错误信息
            e.printStackTrace();
            result.put("msg", e.getMessage());
            result.put("code", "500");
        }
        return result;
    }

    /**
     * 构建岗位信息查询的基础SQL
     * <p>
     *     从 t_org_position（岗位表）出发，LEFT JOIN t_org_admin（取所属组织信息）、
     *     t_org_position（二次关联，取上级岗位信息），查询岗位名称、编号、显示顺序、
     *     所属组织、上级岗位、部门副职、备注、是否负责人岗等字段。
     *     以 {@code where 1=1} 结尾，便于后续动态追加 AND 条件。
     * </p>
     * <p>
     * 涉及表：
     * <ul>
     *   <li><b>t_org_position</b>（pos）—— 岗位表，主表</li>
     *   <li><b>t_org_admin</b>（org）—— 行政组织表</li>
     *   <li><b>t_org_position</b>（ppos）—— 岗位表（二次关联，通过 fparentid 取上级岗位信息）</li>
     * </ul>
     * </p>
     *
     * @return 包含占位符的基础SQL（以 {@code where 1=1} 结尾），过滤条件和分页参数由调用方动态追加
     */
    private static StringBuilder getSql() {
        StringBuilder sql = new StringBuilder();
        sql.append(" /*dialect*/ select ");
        sql.append(" pos.fname_l2 \"name\", ");                   // 岗位名称
        sql.append(" pos.fnumber code, ");                        // 岗位编号
        sql.append(" pos.findex disporder, ");                    // 显示顺序
        sql.append(" org.fnumber department, ");                  // 所属组织编号
        sql.append(" ppos.fnumber parent, ");                     // 上级岗位编号
        sql.append(" pos.cfsffz1 vice, ");                        // 部门副职（1:是，0:否）
        sql.append(" pos.fdescription_l2 description, ");          // 备注
        sql.append(" pos.fid id, ");                              // 主键ID
        sql.append(" pos.fisrespposition isrespposition ");        // 是否负责人岗（1:是，0:否）
        sql.append(" from t_org_position pos ");                  // 岗位表（主表）
        sql.append(" left join t_org_admin org on pos.fadminorgunitid=org.fid ");   // 行政组织表
        sql.append(" left join t_org_position ppos on pos.fparentid=ppos.fid ");    // 岗位表（二次关联，取上级岗位信息）
        sql.append(" where 1=1 ");                                // 占位，便于后续动态拼接 AND 条件

        return sql;
    }
}
