package com.kingdee.eas.custom.integration.feishu.task;

import com.google.gson.JsonParser;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.metadata.entity.*;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.eas.base.permission.IUser;
import com.kingdee.eas.base.permission.UserCollection;
import com.kingdee.eas.base.permission.UserFactory;
import com.kingdee.eas.base.permission.UserInfo;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.integration.base.config.AppConfig;
import com.kingdee.eas.custom.integration.base.util.SpringContextHolder;
import com.kingdee.eas.custom.integration.base.service.IntegrationConfigService;
import com.kingdee.eas.custom.integration.feishu.util.SyncFeishuUserInfoUtil;
import com.kingdee.eas.hr.ats.*;
import com.kingdee.util.DateTimeUtils;
import com.lark.oapi.Client;
import com.lark.oapi.core.utils.Jsons;
import com.lark.oapi.service.attendance.v1.model.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 飞书业务Facade
 * @Date 2026/3/5 17:29
 * @Created by HeYuan
 */
public class FeishuBizFacadeControllerBean extends AbstractFeishuBizFacadeControllerBean {
    private static Logger logger = Logger.getLogger(FeishuBizFacadeControllerBean.class);
    //更新用户信息字段
    private static final SelectorItemCollection UPDATE_SIC = new SelectorItemCollection();

    static {
        UPDATE_SIC.add("feishuUserId");
    }

    /**
     * 同步考勤记录
     *
     * @param ctx
     * @param startDate
     * @param endDate
     * @param advanceDays
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected Map _syncAttendanceRecord(Context ctx, Date startDate, Date endDate, int advanceDays)
            throws BOSException, EASBizException {
        try {
            super._syncAttendanceRecord(ctx, startDate, endDate, advanceDays);

            if (startDate == null || endDate == null) {
                if (advanceDays <= 0) {
                    advanceDays = 2;
                }
                endDate = new Date();
                startDate = DateTimeUtils.addDay(endDate, -advanceDays);
            }
            Calendar cal = Calendar.getInstance();
            cal.setTime(startDate);
            // 设置时间为当天的00:00:00
            cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
            startDate = cal.getTime();

            cal.setTime(endDate);
            // 设置时间为当天的23:59:59
            cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
            endDate = cal.getTime();

            if (startDate.after(endDate)) {
                throw new BOSException("开始日期不能晚于结束日期!");
            }

            String startDateTime = String.valueOf(startDate.getTime()).substring(0, 10);
            String endDateTime = String.valueOf(endDate.getTime()).substring(0, 10);

            Map<String, Object> result = new HashMap<String, Object>();
            result.put("startDate", startDate);
            result.put("endDate", endDate);

            IAttendanceFile iAttendanceFile = AttendanceFileFactory.getLocalInstance(ctx);
            IPunchCardRecord iPunchCardRecord = PunchCardRecordFactory.getLocalInstance(ctx);

            FilterInfo filterInfo = new FilterInfo();
            FilterItemCollection filterItems = filterInfo.getFilterItems();
            filterItems.add(new FilterItemInfo("proposer.idmusercode", null, CompareType.NOTEQUALS));//IDM用户编码非空
            filterItems.add(new FilterItemInfo("attendFileState", AttendFileStateEnum.enable));//考勤档案状态为启用

            SelectorItemCollection sic = new SelectorItemCollection();
            sic.add("attendanceNum");
            sic.add("proposer.idmusercode");

            sic.add("proposer.id");
            sic.add("adminOrgUnit.id");
            sic.add("hrOrgUnit.id");
            sic.add("attAdminOrgUnit.id");

            EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null);

            AttendanceFileCollection attendanceFileCol = iAttendanceFile.getAttendanceFileCollection(viewInfo);

            IUser iUser = UserFactory.getLocalInstance(ctx);
            FilterInfo userFilterInfo = new FilterInfo();
            FilterItemCollection userFilterItems = userFilterInfo.getFilterItems();
            //没有被删除的用户
            userFilterItems.add(new FilterItemInfo("isDelete", false));
            userFilterItems.add(new FilterItemInfo("feishuUserId", null, CompareType.NOTEQUALS));

            SelectorItemCollection userSic = new SelectorItemCollection();
            userSic.add("*");
            userSic.add("person.number");
            userSic.add("person.idmusercode");
            EntityViewInfo userViewInfo = EntityViewInfo.getInstance(userFilterInfo, userSic, null);
            UserCollection userCollection = iUser.getUserCollection(userViewInfo);
            logger.info("用户集合大小: " + userCollection.size());

            Set<String> idmUserCodeSet = new HashSet<String>();

            for (int i = 0; i < userCollection.size(); i++) {
                UserInfo userInfo = userCollection.get(i);
                PersonInfo person = userInfo.getPerson();
                if (person != null) {
                    idmUserCodeSet.add(person.getString("idmusercode"));
                } else {
                    logger.warn("用户集合中存在空的PersonInfo对象");
                }

            }

            result.put("attendanceFileCount", attendanceFileCol.size());

            Map<String, AttendanceFileInfo> attendanceFileMap = new HashMap<String, AttendanceFileInfo>();

            for (int i = 0; i < attendanceFileCol.size(); i++) {
                AttendanceFileInfo attendanceFileInfo = attendanceFileCol.get(i);

                //员工
                PersonInfo proposer = attendanceFileInfo.getProposer();
                if (proposer != null) {
                    //IDM用户编码
                    String idmUserCode = proposer.getString("idmusercode");
                    if (idmUserCodeSet.contains(idmUserCode)) {
                        attendanceFileMap.put(idmUserCode, attendanceFileInfo);
                    } else {
                        logger.warn("用户集合中不存在IDM用户编码: " + idmUserCode);
                    }
                }
            }

            //获取飞书应用默认配置
            IntegrationConfigService integrationConfigService = SpringContextHolder.getBean(IntegrationConfigService.class);

            AppConfig appConfig = integrationConfigService.getPrimaryApp("feishu");
            if (appConfig == null) {
                throw new BOSException("没有获取到飞书应用默认配置!");
            }
            // 构建client
            Client client = Client.newBuilder(appConfig.getAppId(), appConfig.getAppSecret()).build();
            //重复忽略打卡记录数量
            Integer ignoreCount = 0;
            //新增打卡记录数量
            Integer addCount = 0;
            //同步失败的打卡记录数量
            Integer failCount = 0;
            //打卡记录总数
            Integer totalCount = 0;

            ArrayList<String> idmUserCodeList = new ArrayList<>(attendanceFileMap.keySet());

            result.put("attendanceFileCount", idmUserCodeList.size());

            for (int i = 0; i < idmUserCodeList.size(); i += 49) {
                Set<String> values = idmUserCodeList.stream()
                        .skip(i)
                        .limit(50)
                        .collect(Collectors.toSet());

                String[] idmUserCodes = values.toArray(new String[50]);
                // 创建请求对象
                QueryUserFlowReq req = QueryUserFlowReq.newBuilder()
                        .employeeType("employee_id")
                        .queryUserFlowReqBody(QueryUserFlowReqBody.newBuilder()
                                .userIds(idmUserCodes)
                                .checkTimeFrom(startDateTime)
                                .checkTimeTo(endDateTime)
                                .build())
                        .build();

                logger.info("飞书打卡查询参数: " + Jsons.DEFAULT.toJson(req));

                // 发起请求
                QueryUserFlowResp resp = client.attendance().v1().userFlow().query(req);

                logger.info("飞书打卡流水响应: " + Jsons.DEFAULT.toJson(resp));

                // 处理服务端错误
                if (!resp.success()) {
                    logger.error(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
                            resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
                    throw new BOSException("调用飞书API获取打卡结果失败：" + resp.getCode() + resp.getMsg());
                }

                // 业务数据处理
                QueryUserFlowRespBody data = resp.getData();

                UserFlow[] userFlowResults = data.getUserFlowResults();
                totalCount += userFlowResults.length;
                for (int j = 0; j < userFlowResults.length; j++) {
                    try {
                        UserFlow userFlowResult = userFlowResults[j];
                        //对应打卡流水记录ID
                        String recordId = userFlowResult.getRecordId();

                        String feishuUserId = userFlowResult.getUserId();

                        AttendanceFileInfo attendanceFileInfo = attendanceFileMap.get(feishuUserId);
                        if (attendanceFileInfo == null) {
                            ignoreCount++;
                            continue;
                        }
                        FilterInfo existFilter = new FilterInfo();
                        existFilter.getFilterItems().add(new FilterItemInfo("number", recordId, CompareType.EQUALS));
                        if (iPunchCardRecord.exists(existFilter)) {
                            ignoreCount++;
                            continue;
                        }
                        long checkTime = Long.parseLong(userFlowResult.getCheckTime());

                        // 秒 -> 毫秒
                        Timestamp punchCardTime = new Timestamp(checkTime * 1000);
                        Date punchCardDate = DateTimeUtils.truncateDate(punchCardTime);
                        // 原始 打卡记录实体
                        PunchCardRecordInfo punchCardRecordInfo = new PunchCardRecordInfo();

                        punchCardRecordInfo.setNumber(recordId);
                        // 考勤机编码
                        punchCardRecordInfo.setEquipmentNum("1001");
                        //考勤编码
                        punchCardRecordInfo.setAttendanceNum(attendanceFileInfo.getAttendanceNum());
                        //打卡日期
                        punchCardRecordInfo.setPunchCardDate(punchCardDate);
                        //打卡时间
                        punchCardRecordInfo.setPunchCardTime(punchCardTime);
                        // 打卡来源
                        punchCardRecordInfo.setPunchCardSource(PunchCardSourceEnum.mobileRegistration);
                        // 打卡位置
                        punchCardRecordInfo.setPunchCardPlace(userFlowResult.getLocationName());
                        //是否外勤
                        punchCardRecordInfo.setOutSide(userFlowResult.getIsField());
                        //员工
                        punchCardRecordInfo.setProposer(attendanceFileInfo.getProposer());
                        //行政组织
                        punchCardRecordInfo.setAdminOrgUnit(attendanceFileInfo.getAdminOrgUnit());
                        //考勤业务组织
                        punchCardRecordInfo.setHrOrgUnit(attendanceFileInfo.getHrOrgUnit());
                        //状态有效
                        punchCardRecordInfo.setPunchCardState(PunchCardStateEnum.normal);
                        //
                        //punchCardRecordInfo.setAvailable(true);
                        //考勤地点
                        punchCardRecordInfo.setAttAdminOrgUnit(attendanceFileInfo.getAttAdminOrgUnit());

                        if (iPunchCardRecord.exists(existFilter)) {
                            ignoreCount++;
                            continue;
                        }
                        iPunchCardRecord.addnew(punchCardRecordInfo);
                        addCount++;
                    } catch (Exception e) {
                        failCount++;
                        logger.error("写入打卡记录失败：" + e.getMessage(), e);
                    }
                }
            }
            result.put("ignoreCount", ignoreCount);
            result.put("addCount", addCount);
            result.put("failCount", failCount);
            result.put("totalCount", totalCount);
            return result;
        } catch (Exception e) {
            logger.error("同步飞书打卡记录失败: " + e.getMessage(), e);
            throw new BOSException(e);
        }
    }

    /**
     * 同步飞书UserId
     *
     * @param ctx
     * @param userId     用户id
     * @param switchType 0:工号匹配; 1:手机号匹配; 默认值为0
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _syncFeishuUserId(Context ctx, String userId, int switchType)
            throws BOSException, EASBizException {
        logger.info("开始同步飞书UserId: " + userId + " switchType: " + switchType);
        IUser iUser = UserFactory.getLocalInstance(ctx);
        FilterInfo filterInfo = new FilterInfo();
        FilterItemCollection filterItems = filterInfo.getFilterItems();
        //没有被删除的用户
        filterItems.add(new FilterItemInfo("isDelete", false));
        if (switchType >= 0) {
            if (StringUtils.isBlank(userId)) {
                filterItems.add(new FilterItemInfo("feishuUserId", null));
            } else {
                //指定用户
                filterItems.add(new FilterItemInfo("id", userId, CompareType.INCLUDE));
            }
        }
        try {
            SelectorItemCollection sic = new SelectorItemCollection();
            sic.add("*");
            sic.add("person.number");
            sic.add("person.idmusercode");
            EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null);
            logger.info("_syncFeishuUserId viewInfo: " + viewInfo);
            UserCollection userCollection = iUser.getUserCollection(viewInfo);
            if (userCollection.isEmpty()) {
                throw new BOSException("没有获取到用户数据!");
            }
            //获取飞书应用默认配置
            IntegrationConfigService appConfigService = SpringContextHolder.getBean(IntegrationConfigService.class);
            AppConfig appConfig = appConfigService.getPrimaryApp("feishu");
            if (appConfig == null) {
                throw new BOSException("没有获取到飞书应用默认配置!");
            }
            // 构建client
            Client client = Client.newBuilder(appConfig.getAppId(), appConfig.getAppSecret()).build();

            UserCollection updateUserCol = null;
            switch (switchType) {
                case 0:
                    //通过工号匹配
                    updateUserCol = SyncFeishuUserInfoUtil.matchByPersonNumber(client, userCollection);
                    break;
                case 1:
                    //通过账号匹配
                    updateUserCol = SyncFeishuUserInfoUtil.matchByUserNumber(client, userCollection);
                    break;
                case 2:
                    //通过手机号码匹配
                    updateUserCol = SyncFeishuUserInfoUtil.matchByMobile(client, userCollection);
                    break;
                default:
                    //通过工号匹配
                    updateUserCol = SyncFeishuUserInfoUtil.matchByIMDUserCode(client, userCollection);
            }

            if (!updateUserCol.isEmpty()) {
                //更新
                iUser.updatePartialBatchData(updateUserCol, UPDATE_SIC);
            }
            logger.info("更新飞书用户id数量: " + updateUserCol.size());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BOSException("同步飞书用户id报错: " + e.getMessage());
        }
    }
}