package com.mortals.xhx.module.staff.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.framework.util.SecurityUtil;
import com.mortals.xhx.base.system.role.model.RoleUserQuery;
import com.mortals.xhx.base.system.role.service.RoleUserService;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.module.attendance.model.AttendanceStatEntity;
import com.mortals.xhx.module.attendance.model.AttendanceStatQuery;
import com.mortals.xhx.module.attendance.model.AttendanceVacationBalanceEntity;
import com.mortals.xhx.module.attendance.model.AttendanceVacationBalanceQuery;
import com.mortals.xhx.module.attendance.service.AttendanceStatService;
import com.mortals.xhx.module.attendance.service.AttendanceVacationBalanceService;
import com.mortals.xhx.module.dept.model.DeptEntity;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import com.mortals.xhx.module.hik.person.model.req.person.PersonReq;
import com.mortals.xhx.module.hik.person.model.rsp.person.PersonDataInfo;
import com.mortals.xhx.module.hik.person.model.rsp.person.PersonInfo;
import com.mortals.xhx.module.hik.person.service.IHikPersonService;
import com.mortals.xhx.module.staff.dao.StaffDao;
import com.mortals.xhx.module.staff.dao.ibatis.StaffDaoImpl;
import com.mortals.xhx.module.staff.dao.ibatis.StaffLeaveDaoImpl;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.model.vo.StaffInfoVo;
import com.mortals.xhx.module.staff.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

/**
 * StaffService
 * 员工基本信息 service实现
 *
 * @author zxfei
 * @date 2023-04-07
 */
@Service("staffService")
@Slf4j
public class StaffServiceImpl extends AbstractCRUDCacheServiceImpl<StaffDao, StaffEntity, Long> implements StaffService {

    @Autowired
    private UserService userService;
    @Autowired
    private DeptService deptService;

    @Autowired
    private RoleUserService roleUserService;

    @Autowired
    private IHikPersonService hikPersonService;

    @Autowired
    private AttendanceStatService attendanceStatService;

    @Autowired
    private AttendanceVacationBalanceService balanceService;

    @Override
    protected String getExtKey(StaffEntity data) {
        //工号作为redis 扩展key
        return StrUtil.padPre(data.getWorkNum(), 8, "0");
        //  return "1000"+data.getWorkNum();
    }

    @Override
    protected void saveBefore(StaffEntity entity, Context context) throws AppException {
        int count = this.count(new StaffQuery().workNum(entity.getWorkNum()), context);
        if (count > 0) {
            throw new AppException("工号重复！工号:" + entity.getWorkNum());
        }
    }




    @Override
    public StaffInfoVo queryAll(Context context) {
        StaffInfoVo staffInfoVo = new StaffInfoVo();
        //在职
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setStatusList(Arrays.asList(StaffSatusEnum.正式.getValue(), StaffSatusEnum.试用.getValue()));
        List<StaffEntity> staffEntities = this.find(staffQuery);
        staffInfoVo.setInWorkStaff(staffEntities.size());
        //全职
        Map<Integer, Long> collect = staffEntities.stream().collect(Collectors.groupingBy(x -> x.getStaffType(), Collectors.counting()));
        staffInfoVo.setFullStaff(collect.getOrDefault(StaffTypeEnum.全职.getValue(), 0L).intValue());
        //实习
        staffInfoVo.setPricateStaff(collect.getOrDefault(StaffTypeEnum.实习.getValue(), 0L).intValue());
        //兼职
        staffInfoVo.setConcurrentlyStaff(collect.getOrDefault(StaffTypeEnum.兼职.getValue(), 0L).intValue());
        //试用
        staffInfoVo.setOnTrialStaff(this.find(new StaffQuery().status(StaffSatusEnum.试用.getValue())).size());
        //正式
        staffInfoVo.setFormalStaff(this.find(new StaffQuery().status(StaffSatusEnum.正式.getValue())).size());
        //待离职
        staffInfoVo.setResignationStaff(this.find(new StaffQuery().status(StaffSatusEnum.离职.getValue())).size());
        return staffInfoVo;
    }


    @Override
    public int queryAllPerson() {
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setStatusList(Arrays.asList(StaffSatusEnum.正式.getValue(), StaffSatusEnum.试用.getValue()));
        List<StaffEntity> staffEntities = this.find(staffQuery);
        return staffEntities.size();
    }

    @Override
    public Rest<Void> syncPersons(Context context) {
        log.info("同步人员！");

        PersonReq personReq = new PersonReq();
        personReq.setPageNo(1);
        personReq.setPageSize(1000);
        Rest<PersonDataInfo> personRest = hikPersonService.getPersonList(personReq);
        if (personRest.getCode() == YesNoEnum.YES.getValue()) {
            List<PersonInfo> personInfoList = personRest.getData().getList();
            for (PersonInfo personInfo : personInfoList) {
                StaffEntity staffEntity = this.getExtCache(StrUtil.padPre(personInfo.getJobNo(), 8, "0"));
                DeptEntity deptEntity = deptService.selectOne(new DeptQuery().deptCode(personInfo.getOrgIndexCode()));
                //判断本地数据是否为空
                if (ObjectUtils.isEmpty(staffEntity)) {
                    //新增员工信息
                    staffEntity = new StaffEntity();
                    staffEntity.initAttrValue();
                    if (!ObjectUtils.isEmpty(deptEntity)) {
                        staffEntity.setDeptId(deptEntity.getId());
                    }
                    staffEntity.setName(personInfo.getPersonName());
                    staffEntity.setRemarkId(personInfo.getPersonId());
                    staffEntity.setPicUri(personInfo.getPersonPhoto().getPicUri());
                    staffEntity.setServerIndexCode(personInfo.getPersonPhoto().getServerIndexCode());
                    staffEntity.setDeptName(personInfo.getOrgName());
                    staffEntity.setGender(personInfo.getGender());
                    staffEntity.setWorkNum(personInfo.getJobNo());
                    staffEntity.setPhoneNumber(personInfo.getPhoneNo());
                    staffEntity.setCreateUserId(1L);
                    staffEntity.setCreateTime(new Date());
                    this.save(staffEntity);

                } else {
                    //更新
                    if (!ObjectUtils.isEmpty(deptEntity)) {
                        staffEntity.setDeptId(deptEntity.getId());
                    }
                    staffEntity.setName(personInfo.getPersonName());
                    staffEntity.setRemarkId(personInfo.getPersonId());
                    staffEntity.setPicUri(personInfo.getPersonPhoto().getPicUri());
                    staffEntity.setServerIndexCode(personInfo.getPersonPhoto().getServerIndexCode());
                    staffEntity.setDeptName(personInfo.getOrgName());
                    staffEntity.setGender(personInfo.getGender());
                    staffEntity.setWorkNum(personInfo.getJobNo());
                    staffEntity.setPhoneNumber(personInfo.getPhoneNo());
                    staffEntity.setUpdateUserId(1L);
                    staffEntity.setUpdateTime(new Date());
                    this.update(staffEntity);
                }
            }
        }

        return Rest.ok();
    }


    @Override
    protected void saveAfter(StaffEntity entity, Context context) throws AppException {
        super.saveAfter(entity, context);
        //初始化
        int count = balanceService.count(new AttendanceVacationBalanceQuery().staffId(entity.getId()), context);
        if(count==0){
            AttendanceVacationBalanceEntity balanceEntity = new AttendanceVacationBalanceEntity();
            balanceEntity.initAttrValue();
            balanceEntity.setStaffId(entity.getId());
            balanceEntity.setStaffName(entity.getName());
            balanceEntity.setDeptId(entity.getDeptId());
            balanceEntity.setDeptName(entity.getDeptName());
            balanceEntity.setCreateUserId(1L);
            balanceEntity.setCreateTime(new Date());
            balanceService.save(balanceEntity);
        }
        AttendanceStatQuery attendanceStatQuery = new AttendanceStatQuery();
        attendanceStatQuery.setYear(DateUtil.year(new Date()));
        attendanceStatQuery.setMonth(DateUtil.month(new Date())+1);
        attendanceStatQuery.setDay(DateUtil.dayOfMonth(new Date()));
        attendanceStatQuery.setStaffId(entity.getId());
        int count1 = attendanceStatService.count(attendanceStatQuery, context);
        if(count1==0){
            AttendanceStatEntity attendanceStatEntity = new AttendanceStatEntity();
            attendanceStatEntity.initAttrValue();
            attendanceStatEntity.setStaffId(entity.getId());
            attendanceStatEntity.setStaffName(entity.getName());
            attendanceStatEntity.setDeptId(entity.getDeptId());
            attendanceStatEntity.setDeptName(entity.getDeptName());
            attendanceStatEntity.setPhoneNumer(entity.getPhoneNumber());
            attendanceStatEntity.setYear(DateUtil.year(new Date()));
            attendanceStatEntity.setMonth(DateUtil.month(new Date())+1);
            attendanceStatEntity.setDay(DateUtil.dayOfMonth(new Date()));
            attendanceStatEntity.setCreateUserId(1L);
            attendanceStatEntity.setCreateTime(new Date());
            attendanceStatService.save(attendanceStatEntity);
        }
        try {
            UserEntity userEntity = new UserEntity();
            if (ObjectUtils.isEmpty(entity.getLoginName())) {
                //姓名加工号作为登录名
                entity.setLoginName(entity.getName() + entity.getWorkNum());
            }
            if (ObjectUtils.isEmpty(entity.getLoginPwd())) {
                //设置初始密码
                entity.setLoginPwd("123456");
            }

            userEntity.setLoginName(StrUtil.cleanBlank(entity.getLoginName()));
            userEntity.setRealName(entity.getName());
            userEntity.setUserType(UserType.WORK_PERSON.getValue());
            userEntity.setSiteIds("1");
            userEntity.setAreaCodes("511500000000");
            userEntity.setMobile(entity.getPhoneNumber());
            userEntity.setStatus(UserStatus.NORMAL.getValue());
            userEntity.setCreateUserId(this.getContextUserId(context));
            userEntity.setCreateTime(new Date());
            userEntity.setCustomerId(entity.getId());

            userEntity.setLoginPwd(SecurityUtil.md5DoubleEncoding(entity.getLoginPwd()));
            int insert = userService.getUserDao().insert(userEntity);
            if (insert > 0) {
                RoleUserQuery roleUserQuery = new RoleUserQuery();
                roleUserQuery.setUserId(userEntity.getId());
                roleUserQuery.setRoleIdList(Arrays.asList(4L));
                roleUserService.assignRoleToUser(roleUserQuery);
            }

        } catch (Exception e) {
           log.error("保存系统用户异常!",e);
        }

    }


    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        deptService.updateDeptNum(context);
    }

    public static void main(String[] args) {
        System.out.println("1" + StrUtil.padPre("125", 7, "0"));

    }

    @Override
    protected StaffEntity findBefore(StaffEntity params, PageInfo pageInfo, Context context) throws AppException {
        if(params.getDeptId()!=null){
            List<DeptEntity> deptList = deptService.getAllChildrenDept(params.getDeptId());
            if(CollectionUtils.isNotEmpty(deptList)){
                List<Long> deptIdList = new ArrayList<>();
                deptIdList.add(params.getDeptId());
                deptList.forEach(item -> {
                    deptIdList.add(item.getId());
                });
                params.setDeptId(null);
                params.setDeptIdList(deptIdList);
            }
        }
        return params;
    }
}