package com.kingdee.eas.custom.handover.utils;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.metadata.data.SortType;
import com.kingdee.bos.metadata.entity.*;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.basedata.org.AdminOrgUnitInfo;
import com.kingdee.eas.basedata.org.HROrgUnitInfo;
import com.kingdee.eas.basedata.org.PositionInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.handover.WorkHandoverEntryInfo;
import com.kingdee.eas.custom.handover.WorkHandoverInfo;
import com.kingdee.eas.hr.affair.ResignBizBillEntryInfo;
import com.kingdee.eas.hr.ats.IWorkCalendarItem;
import com.kingdee.eas.hr.ats.WorkCalendarItemCollection;
import com.kingdee.eas.hr.ats.WorkCalendarItemFactory;
import com.kingdee.eas.hr.ats.WorkCalendarItemInfo;
import com.kingdee.eas.hr.ats.util.AtsDateUtils;
import com.kingdee.eas.hr.base.EmpPosOrgRelationCollection;
import com.kingdee.eas.hr.base.EmpPosOrgRelationFactory;
import com.kingdee.eas.hr.base.EmpPosOrgRelationInfo;
import com.kingdee.eas.hr.base.HRBillStateEnum;
import com.kingdee.util.DateTimeUtils;
import com.kingdee.util.StringUtils;
import org.apache.log4j.Logger;

import java.util.*;

/**
 * @Description 工作交接单工具类
 * @Date 2025/5/30 14:28
 * @Created by Heyuan
 */
public class WorkHandoverUtil {
    private static Logger logger = Logger.getLogger(WorkHandoverUtil.class);
    //工作交接单/离职单分录映射字段
    private static Map<String, String> propertyMap = new HashMap<String, String>();

    static {
        propertyMap.put("person", "person");//人员
        propertyMap.put("adminOrg", "adminOrg");//组织
        propertyMap.put("resHrBizDefine", "hrBizDefine");//离职变动操作
        propertyMap.put("position", "position");//职位
        propertyMap.put("jobGrade", "jobGrade");//职级
        propertyMap.put("oldEmpType", "oldEmpType");//离职前用工关系状态
        propertyMap.put("empType", "empType");//离职用工关系状态
        propertyMap.put("resVariationReason", "variationReason");//离职原因
        propertyMap.put("leftCompanyDate", "leftCompanyDate");//最后工作日
        propertyMap.put("leftDate", "bizDate");//离职日期
    }

    /**
     * 生成工作交接单
     *
     * @param resignBizBillEntryInfo
     * @return
     */
    public static WorkHandoverInfo generateWorkHandoverInfo(
            Context ctx,
            ResignBizBillEntryInfo resignBizBillEntryInfo
    ) throws BOSException {
        try {
            //人员id
            String personId = resignBizBillEntryInfo.getPerson().getId().toString();
            //工作交接单
            WorkHandoverInfo workHandoverInfo = new WorkHandoverInfo();
            workHandoverInfo.setBillState(HRBillStateEnum.SUBMITED);
            HROrgUnitInfo hrOrgUnitInfo = new HROrgUnitInfo();
            hrOrgUnitInfo.setId(BOSUuid.read("00000000-0000-0000-0000-000000000000CCE7AED4"));
            workHandoverInfo.setHrOrgUnit(hrOrgUnitInfo);
            //工作交接单分录
            WorkHandoverEntryInfo workHandoverEntryInfo = new WorkHandoverEntryInfo();
            workHandoverInfo.getEntrys().add(workHandoverEntryInfo);
            //批量赋值
            for (String workHandoverAttrName : propertyMap.keySet()) {
                String resignBizBillEntryAttrName = propertyMap.get(workHandoverAttrName);
                workHandoverEntryInfo.put(workHandoverAttrName, resignBizBillEntryInfo.get(resignBizBillEntryAttrName));
            }
            //离职单分录id
            workHandoverEntryInfo.setResignBizBillEntryId(resignBizBillEntryInfo.getId().toString());
            //离职单
            workHandoverEntryInfo.setResignBizBill(resignBizBillEntryInfo.getBill());
            //是否领导
            workHandoverEntryInfo.setBoolean("isLeader", isLeader(ctx, personId));
            //离职日期
            Date bizDate = resignBizBillEntryInfo.getBizDate();
            setResignBizDate(ctx, bizDate, workHandoverEntryInfo);
            return workHandoverInfo;
        } catch (BOSException e) {
            logger.error("generateWorkHandoverInfo error: " + e.getMessage(), e);
            throw new BOSException(e);
        }
    }

    /**
     * 获取指定日期到后置天数范围内的工作日
     *
     * @param ctx
     * @param bizDate  指定日期
     * @param afterDay 延后天数
     * @return
     * @throws BOSException
     */
    public static WorkCalendarItemCollection getWorkCalendarItemCollection(
            Context ctx,
            SortType sortType,
            Date bizDate,
            int afterDay
    ) throws BOSException {
        if (bizDate == null) {
            throw new BOSException("getWorkCalendarItemCollection bizDate is null");
        }
        IWorkCalendarItem iWorkCalendarItem = WorkCalendarItemFactory.getLocalInstance(ctx);
        FilterInfo filterInfo = new FilterInfo();
        FilterItemCollection filterItems = filterInfo.getFilterItems();
        Date afterDate = AtsDateUtils.getPreDay(bizDate, -afterDay);
        if (bizDate.before(afterDate)) {
            //日期大于等于指定日期
            filterItems.add(new FilterItemInfo("date", bizDate, CompareType.GREATER_EQUALS));
            //日期小于等于离职日期前延天
            filterItems.add(new FilterItemInfo("date", afterDate, CompareType.LESS_EQUALS));
        } else {
            filterItems.add(new FilterItemInfo("date", afterDate, CompareType.GREATER_EQUALS));
            filterItems.add(new FilterItemInfo("date", bizDate, CompareType.LESS_EQUALS));
        }
        //工作日
        filterItems.add(new FilterItemInfo("dayType", "0"));
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("date");
        SorterItemCollection sorts = new SorterItemCollection();
        //
        SorterItemInfo sorterItemInfo = new SorterItemInfo("date");
        if (sortType != null) {
            sorterItemInfo.setSortType(sortType);
        }
        sorts.add(sorterItemInfo);
        EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, sorts);
        WorkCalendarItemCollection workCalendarItemCollection = iWorkCalendarItem.getWorkCalendarItemCollection(viewInfo);
        if (workCalendarItemCollection.isEmpty()) {
            //没有查询到工作日历数据
            throw new BOSException("未查询到工作日历");
        }
        return workCalendarItemCollection;
    }


    /**
     * 判断指定日期是否为工作日
     *
     * @param ctx
     * @param bizDate 指定日期
     * @return
     * @throws BOSException
     */
    public static boolean isWorkDay(
            Context ctx,
            Date bizDate
    ) throws BOSException, EASBizException {
        if (bizDate == null) {
            throw new BOSException("isWorkDay bizDate is null");
        }
        IWorkCalendarItem iWorkCalendarItem = WorkCalendarItemFactory.getLocalInstance(ctx);
        FilterInfo filterInfo = new FilterInfo();
        FilterItemCollection filterItems = filterInfo.getFilterItems();
        //日期等于指定日期
        filterItems.add(new FilterItemInfo("date", bizDate));
        //工作日
        filterItems.add(new FilterItemInfo("dayType", "0"));
        return iWorkCalendarItem.exists(filterInfo);
    }

    /**
     * 获取员工当前任职情况
     *
     * @param ctx
     * @param personId 员工id
     * @return
     * @throws BOSException
     */
    public static EmpPosOrgRelationCollection getCurrntEmpOrgRelation(
            Context ctx,
            String personId
    ) throws BOSException {
        SelectorItemCollection sic = new SelectorItemCollection();
        sic.add("position.*");
        sic.add("adminOrg.level");
        EntityViewInfo view = new EntityViewInfo();
        FilterInfo filter = new FilterInfo();
        filter.getFilterItems().add(new FilterItemInfo("person.id", personId));
        Date curDate = DateTimeUtils.truncateDate(new Date());
        filter.getFilterItems().add(new FilterItemInfo(HistoryConstant.EFFDT, curDate, CompareType.LESS_EQUALS));
        filter.getFilterItems().add(new FilterItemInfo(HistoryConstant.LEFFDT, curDate, CompareType.GREATER_EQUALS));
        view.setFilter(filter);
        view.setSelector(sic);
        EmpPosOrgRelationCollection collection = EmpPosOrgRelationFactory.getLocalInstance(ctx).getEmpPosOrgRelationCollection(view);
        return collection;
    }

    /**
     * 通过上级职位id,获取下级职位任职员工信息
     *
     * @param ctx
     * @param positionId 上级职位id
     * @return
     * @throws BOSException
     */
    public static EmpPosOrgRelationCollection getCurrntEmpOrgRelationByParentPositionId(
            Context ctx,
            String positionId
    ) throws BOSException {
        EntityViewInfo view = new EntityViewInfo();
        FilterInfo filter = new FilterInfo();
        filter.getFilterItems().add(new FilterItemInfo("position.parent.id", positionId));
        Date curDate = DateTimeUtils.truncateDate(new Date());
        filter.getFilterItems().add(new FilterItemInfo(HistoryConstant.EFFDT, curDate, CompareType.LESS_EQUALS));
        filter.getFilterItems().add(new FilterItemInfo(HistoryConstant.LEFFDT, curDate, CompareType.GREATER_EQUALS));
        view.setFilter(filter);
        EmpPosOrgRelationCollection collection = EmpPosOrgRelationFactory.getLocalInstance(ctx).getEmpPosOrgRelationCollection(view);
        return collection;
    }

    /**
     * 判断指定员工是否为领导
     *
     * @param ctx
     * @param personId
     * @return
     * @throws BOSException
     */
    public static boolean isLeader(Context ctx, String personId) throws BOSException {
        if (StringUtils.isEmpty(personId)) {
            throw new BOSException("isLeader personId is null");
        }
        EmpPosOrgRelationCollection currntEmpOrgRelation = getCurrntEmpOrgRelation(ctx, personId);
        boolean isLeader = false;
        for (int i = 0; i < currntEmpOrgRelation.size(); i++) {
            EmpPosOrgRelationInfo empPosOrgRelationInfo = currntEmpOrgRelation.get(i);
            PositionInfo position = empPosOrgRelationInfo.getPosition();
            //是否负责人职位
            boolean isRespPosition = position.isIsRespPosition();
            //任职部门
            AdminOrgUnitInfo adminOrg = empPosOrgRelationInfo.getAdminOrg();
            //部门层级
            int level = adminOrg.getLevel();
            //1.校验是否为一二级部门负责人
            if (isRespPosition && (level == 2 || level == 3)) {
                isLeader = true;
                break;
            } else {
                //2.校验是否为直接上级(有下级职位且下级职位有人)
                EmpPosOrgRelationCollection minionOrgRelations = getCurrntEmpOrgRelationByParentPositionId(ctx, position.getId().toString());
                if (!minionOrgRelations.isEmpty()) {
                    isLeader = true;
                    break;
                }
            }
        }
        return isLeader;
    }

    /**
     * 设置离职年月日
     *
     * @param ctx
     * @param leftDate
     * @param workHandoverEntryInfo
     * @throws BOSException
     */
    public static void setResignBizDate(
            Context ctx,
            Date leftDate,
            WorkHandoverEntryInfo workHandoverEntryInfo
    ) throws BOSException {
        //获取指定日期到前延天数范围内的工作日
        WorkCalendarItemCollection workCalendarItemCollection = WorkHandoverUtil.getWorkCalendarItemCollection(ctx, SortType.DESCEND, leftDate, -30);
        //如果离职当天非工作日，则传离职前一个工作日的数据
        WorkCalendarItemInfo workCalendarItemInfo = workCalendarItemCollection.get(0);
        java.util.Date date = workCalendarItemInfo.getDate();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        workHandoverEntryInfo.setResignYear(year);
        int money = calendar.get(Calendar.MONTH) + 1;
        workHandoverEntryInfo.setResignMonth(money);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        workHandoverEntryInfo.setResignDay(day);
    }
}
