package nckd.jimin.jyyy.hr.wtc.wtis.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.util.StringUtils;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.ObjectUtils;
import kd.bos.exception.ErrorCode;
import kd.bos.exception.KDBizException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.wtc.wtis.business.punchcarddata.PunchCardDataHelper;
import kd.wtc.wtis.business.punchcarddata.PunchCardDataService;
import kd.wtc.wtis.webapi.punchcard.PunchCardSyncSupport;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class SyncPunchCardHelper {

    private static HRBaseServiceHelper PUNCH_CARD_HELPER = new HRBaseServiceHelper("wtis_punchcarddata");
    private static final Log logger = LogFactory.getLog(SyncPunchCardHelper.class);

    /**
     * 保存打卡数据
     * @param resultArr
     * @param openMap
     */
    public static void savePunchCardData(JSONArray resultArr, Map openMap) {
        //批次编码
        String batchNumber = String.valueOf(System.currentTimeMillis());
        //2025-06-09 如果invalidRecordType有值则为无效卡
        logger.info("钉钉返回信息过滤前条数：{}", resultArr.size());
        JSONArray actualArr = resultArr.stream().filter(obj -> StringUtils.isEmpty(((JSONObject) obj).getString("invalidRecordType")))
                .collect(Collectors.toCollection(JSONArray::new));
        logger.info("钉钉返回信息过滤后条数：{}", actualArr.size());
        //如果过滤后size == 0直接返回
        if(actualArr.size() == 0) {
            String msg = "钉钉返回条数：" + resultArr.size() + "条，有效卡：" + actualArr.size() + "条";
            DingTalkSyncUtil.createLog(DingTalkSyncUtil.v_success, msg, resultArr.toJSONString(), DingTalkSyncUtil.SyncPunch);
            return;
        }
        List<DynamicObject> saveList = actualArr.stream().map((data) -> {
            return dealPunchCardData((JSONObject) data, openMap, batchNumber);
        }).collect(Collectors.toList());
        logger.info("钉钉待保存过滤重复前条数：{}", saveList.size());
        //过滤下为空的
        List<DynamicObject> actualSaveList = saveList.stream().filter(dyo -> !ObjectUtils.isEmpty(dyo)).collect(Collectors.toList());
        logger.info("钉钉待保存过滤重复后条数：{}", actualSaveList.size());
        if(actualSaveList.size() == 0) {
            String msg = "钉钉返回条数：" + resultArr.size() + "条，" + "有效卡：" + actualArr.size() + "条，重复：" + (saveList.size()-actualSaveList.size()) + "条";
            DingTalkSyncUtil.createLog(DingTalkSyncUtil.v_success, msg, resultArr.toJSONString(), DingTalkSyncUtil.SyncPunch);
            return;
        }
        String msg = "钉钉返回条数：" + resultArr.size() + "条，" + "有效卡：" + actualArr.size() + "条，重复：" + (saveList.size()-actualSaveList.size()) + "条";
        DingTalkSyncUtil.createLog(DingTalkSyncUtil.v_success, msg, resultArr.toJSONString(), DingTalkSyncUtil.SyncPunch);
        PUNCH_CARD_HELPER.save((DynamicObject[])actualSaveList.toArray(new DynamicObject[0]));

        try {
            long l1 = System.currentTimeMillis();
            PunchCardSyncSupport.execute(() -> {
                syncCardRecord(actualArr,batchNumber);
            });
            long l2 = System.currentTimeMillis();
            logger.info("SyncPunchCardHelper_sync_cardData_{}", l2 - l1);
        } catch (Exception e) {
            logger.warn("SyncPunchCardHelper_sync_cardData_error ", e);
            DingTalkSyncUtil.createLog(DingTalkSyncUtil.v_error,resultArr.toJSONString(), e.getMessage(), DingTalkSyncUtil.SyncPunch);
        }

    }

    /**
     * 处理打卡数据
     * @param data 钉钉接口返回的打卡数据明细
     * @param batchNumber 批次编码
     * @param openMap 人员映射 key = openId, value = 人员工号
     */
    public static DynamicObject dealPunchCardData(JSONObject data, Map openMap, String batchNumber) {
        DynamicObject dyo = PUNCH_CARD_HELPER.generateEmptyDynamicObject();
        dyo.set("batchnumber", batchNumber);
        String card = openMap.get(data.getString("userId")).toString();
        String id = data.getString("id");
        //如果存在记录直接返回
        if(checkCardIsExists(card, id)) {
            return null;
        }
        dyo.set("number", card);
        dyo.set("card", card);
        //实际打卡时间
        Long unix = data.getLong("userCheckTime");
        dyo.set("punchcarddate", unixToDate(unix));
        dyo.set("punchcardtime", unixToTimeStamp(unix));
        //打卡地点
        dyo.set("place", data.getString("userAddress"));
        //进出卡
        String checkType = data.getString("checkType");
        if("OnDuty".equals(checkType)) {
            dyo.set("accesstag", "on");
        }
        else if("OffDuty".equals(checkType)) {
            dyo.set("accesstag", "off");
        }
        //时区
        dyo.set("timezone", 320881823238577152L);
        //打卡来源
        dyo.set("signsourcename", "钉钉同步");
        //打卡设备 设备编码
        dyo.set("equipment", "钉钉同步");
        dyo.set("equipnumber", "1020_S");
        // dataId
        dyo.set("dataid", id);

        //默认值
        dyo.set("times", 0);
        dyo.set("status", 0);

        return dyo;
    }

    /**
     * 同步打卡记录
     * @JSONArray resultArr
     * @param batchNumber
     */
    private static void syncCardRecord(JSONArray resultArr, String batchNumber) {
        try {
            long l1 = System.currentTimeMillis();
            DynamicObject[] date = PunchCardDataHelper.getDataByBatchNumber(batchNumber);
            PunchCardDataService.dealWithData(date);
            long l2 = System.currentTimeMillis();
            logger.info("SyncPunchCardHelper_sync_cardData：{}", l2 - l1);
            DingTalkSyncUtil.createLog(DingTalkSyncUtil.v_success,batchNumber + "批次号同步成功", "", DingTalkSyncUtil.SyncPunch);
        } catch (Exception e) {
            logger.warn("SyncPunchCardHelper_sync_cardData_error", e);
            DingTalkSyncUtil.createLog(DingTalkSyncUtil.v_error,"syncCardRecordError", e.getMessage(), DingTalkSyncUtil.SyncPunch);
            throw new KDBizException(e, new ErrorCode("", e.getMessage()), new Object[0]);
        } catch (Throwable e1) {
            logger.warn("SyncPunchCardHelper_sync_cardData_thr", e1);
            DingTalkSyncUtil.createLog(DingTalkSyncUtil.v_error,"syncCardRecordThrow", e1.getMessage(), DingTalkSyncUtil.SyncPunch);
            throw new KDBizException(e1, new ErrorCode("", e1.getMessage()), new Object[0]);
        }
    }


    /**
     * 根据考勤卡号和钉钉返回ID判断是否存在记录
     * @param card
     * @param id
     */
    public static boolean checkCardIsExists(String card, String id) {
        QFilter filter = new QFilter("card", QCP.equals, card);
        filter.and("dataid", QCP.equals, id);
        return QueryServiceHelper.exists("wtis_punchcarddata", new QFilter[]{filter});
    }



    /**
     * 时间戳转yyyy-MM-dd
     * @param unix
     * @return
     */
    public static Date unixToDate (Long unix) {
        Date date = new Date(unix);
        return date;
    }


    /**
     * 时间戳转HH:mm:ss
     * @param unix
     * @return
     */
    public static String unixToTimeStamp (Long unix) {
        Date date = new Date(unix);
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        return sdf.format(date);
    }
}
