/*
 * Copyright [2022] [https://www.baiduc.com]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.baiduc.com
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.baiduc.com
 */
package vip.xiaonuo.hr.modular.baseemployeeinfo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.hr.modular.basedepartment.entity.HrBaseDepartment;
import vip.xiaonuo.hr.modular.basedepartment.mapper.HrBaseDepartmentMapper;
import vip.xiaonuo.hr.modular.baseemployeeinfo.entity.HrBaseEmployeeInfo;
import vip.xiaonuo.hr.modular.baseemployeeinfo.entity.vo.CountPerson;
import vip.xiaonuo.hr.modular.baseemployeeinfo.entity.vo.EoucationVo;
import vip.xiaonuo.hr.modular.baseemployeeinfo.entity.vo.HrBaseEmployeeInfoVo;
import vip.xiaonuo.hr.modular.baseemployeeinfo.entity.vo.PerNum;
import vip.xiaonuo.hr.modular.baseemployeeinfo.mapper.HrBaseEmployeeInfoMapper;
import vip.xiaonuo.hr.modular.baseemployeeinfo.param.*;
import vip.xiaonuo.hr.modular.baseemployeeinfo.service.HrBaseEmployeeInfoService;
import vip.xiaonuo.purchase.entity.PurchaseContract;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 人员明细Service接口实现类
 *
 * @author 余
 * @date  2024/11/14 15:02
 **/
@Service
public class HrBaseEmployeeInfoServiceImpl extends ServiceImpl<HrBaseEmployeeInfoMapper, HrBaseEmployeeInfo> implements HrBaseEmployeeInfoService {
    @Autowired
    private  HrBaseEmployeeInfoMapper hrBaseEmployeeInfoMapper;
    @Autowired
    private HrBaseDepartmentMapper hrBaseDepartmentMapper;


    @Override
    public Page<HrBaseEmployeeInfo> page(HrBaseEmployeeInfoPageParam hrBaseEmployeeInfoPageParam) {
        QueryWrapper<HrBaseEmployeeInfo> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isAllNotEmpty(hrBaseEmployeeInfoPageParam.getSortField(), hrBaseEmployeeInfoPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(hrBaseEmployeeInfoPageParam.getSortOrder());
            queryWrapper.orderBy(true, hrBaseEmployeeInfoPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(hrBaseEmployeeInfoPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(HrBaseEmployeeInfo::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(HrBaseEmployeeInfoAddParam hrBaseEmployeeInfoAddParam) {
        HrBaseEmployeeInfo hrBaseEmployeeInfo = BeanUtil.toBean(hrBaseEmployeeInfoAddParam, HrBaseEmployeeInfo.class);
        this.save(hrBaseEmployeeInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(HrBaseEmployeeInfoEditParam hrBaseEmployeeInfoEditParam) {
        HrBaseEmployeeInfo hrBaseEmployeeInfo = this.queryEntity(hrBaseEmployeeInfoEditParam.getId());
        BeanUtil.copyProperties(hrBaseEmployeeInfoEditParam, hrBaseEmployeeInfo);
        this.updateById(hrBaseEmployeeInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<HrBaseEmployeeInfoIdParam> hrBaseEmployeeInfoIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(hrBaseEmployeeInfoIdParamList, HrBaseEmployeeInfoIdParam::getId));
    }

    @Override
    public HrBaseEmployeeInfo detail(HrBaseEmployeeInfoIdParam hrBaseEmployeeInfoIdParam) {
        return this.queryEntity(hrBaseEmployeeInfoIdParam.getId());
    }

    @Override
    public HrBaseEmployeeInfo queryEntity(String id) {
        HrBaseEmployeeInfo hrBaseEmployeeInfo = this.getById(id);
        if(ObjectUtil.isEmpty(hrBaseEmployeeInfo)) {
            throw new CommonException("人员明细不存在，id值为：{}", id);
        }
        return hrBaseEmployeeInfo;
    }

    @Override
    public List<EoucationVo> listByEoucation(EmployeeInfoEoucation employeeInfoEoucation) {
        return hrBaseEmployeeInfoMapper.listByEoucation(employeeInfoEoucation.getOrgId());
    }

    @Override
    public CountPerson countPerson(EmployeeInfoEoucation employeeInfoEoucation) {
        CountPerson countPerson = new CountPerson();
        String orgId = employeeInfoEoucation.getOrgId();
        QueryWrapper<HrBaseEmployeeInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).ne("USER_TYPE",1);
        long count = this.count(queryWrapper);
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).eq("GENDER",0);
        long maleNum = this.count(queryWrapper);
        countPerson.setCountNum(count);
        countPerson.setMaleNum(maleNum);
        countPerson.setFemaleNum(count -maleNum);

        queryWrapper.clear();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).le("ENTRY_DATE",new Date()).eq("USER_TYPE",3);
        countPerson.setDutyNum(this.count(queryWrapper));

        queryWrapper.clear();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).eq("USER_TYPE",2);
        countPerson.setRetireAndDutyNum(this.count(queryWrapper));

        queryWrapper.clear();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).between("RETIRE_TIME", new Date(), DateUtil.offset(new Date(), DateField.YEAR, employeeInfoEoucation.getDateYear()));
        List<HrBaseEmployeeInfo> list = this.list(queryWrapper);
        List<HrBaseEmployeeInfoVo> voList = new ArrayList<>();
        List<EoucationVo> personList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(list)) {
            countPerson.setRetireNum(list.size());



            List<HrBaseDepartment> baseDepartments = hrBaseDepartmentMapper.selectList(new QueryWrapper<HrBaseDepartment>().eq(StringUtils.isNotBlank(orgId),"ORG_ID", orgId));

            Map<String, String> map = new HashMap<>();
            for (HrBaseDepartment department : baseDepartments) {
                map.put(department.getId(),department.getName());
            }
            for (HrBaseEmployeeInfo info : list) {
                HrBaseEmployeeInfoVo vo = new HrBaseEmployeeInfoVo();
                BeanUtil.copyProperties(info, vo);
                if (map.containsKey(info.getDepartmentId())) {
                    vo.setDepartName(map.get(info.getDepartmentId()));
                }
                voList.add(vo);
            }
            countPerson.setRetirePersonList(voList);

            Map<Object, Long> departmentCountMap = list.stream()
                    .collect(Collectors.groupingBy(
                            o -> o.getDepartmentId(), // 分组的键是部门ID
                            Collectors.counting()    // 分组的值是该部门ID对应的人数
                    ));
             personList = baseDepartments.stream()
                    .map(baseDepartment -> {
                        EoucationVo eoucationVo = new EoucationVo();
                        eoucationVo.setDepartmentName(baseDepartment.getName());
                        // 使用getOrDefault来避免Map中不存在的键导致的NullPointerException
                        eoucationVo.setCountNum(departmentCountMap.getOrDefault(baseDepartment.getId(), 0L).intValue());
                        return eoucationVo;
                    })
                    .collect(Collectors.toList());
            countPerson.setRetirePersonNum(personList);

        } else {
            countPerson.setRetireNum(list.size());
            countPerson.setRetirePersonList(voList);
            countPerson.setRetirePersonNum(personList);
        }
        return countPerson;
    }

    @Override
    public  List<EoucationVo>  listByDepart(EmployeeInfoEoucation employeeInfoEoucation) {
        return hrBaseEmployeeInfoMapper.listByDepart(employeeInfoEoucation.getOrgId());
    }
    @Override
    public    List<EoucationVo>  listByDepartGender(EmployeeInfoEoucation employeeInfoEoucation) {
        return hrBaseEmployeeInfoMapper.listByDepartGender(employeeInfoEoucation.getOrgId());
    }

    @Override
    public List<EoucationVo> listByDepartGenderEducationDis(EmployeeInfoEoucation employeeInfoEoucation) {
        return hrBaseEmployeeInfoMapper.listByDepartGenderEducationDis(employeeInfoEoucation.getOrgId());
    }

    @Override
    public List<PerNum> birthDis(EmployeeInfoEoucation employeeInfoEoucation) {
        return hrBaseEmployeeInfoMapper.birthDis(employeeInfoEoucation.getOrgId());
    }

    @Override
    public   List<PerNum> siLingDis(EmployeeInfoEoucation employeeInfoEoucation) {
        return hrBaseEmployeeInfoMapper.siLingDis(employeeInfoEoucation.getOrgId());
    }

    @Override
    public   List<PerNum> gongLingDis(EmployeeInfoEoucation employeeInfoEoucation) {
        return hrBaseEmployeeInfoMapper.gongLingDis(employeeInfoEoucation.getOrgId());
    }


}
