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

import cn.hutool.core.date.DateUtil;
import com.mortals.xhx.busiz.h5.req.AttendSaveReq;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.attendance.model.*;
import com.mortals.xhx.module.attendance.service.AttendanceClassDetailService;
import com.mortals.xhx.module.attendance.service.AttendanceClassService;
import com.mortals.xhx.module.attendance.service.AttendanceGroupFixedworkService;
import com.mortals.xhx.module.attendance.service.AttendanceGroupService;
import com.mortals.xhx.module.check.model.CheckAttendRecordEntity;
import com.mortals.xhx.module.check.model.CheckAttendRecordQuery;
import com.mortals.xhx.module.check.service.CheckAttendRecordService;
import com.mortals.xhx.module.dept.model.DeptEntity;
import com.mortals.xhx.module.dept.service.DeptService;
import com.mortals.xhx.module.perform.model.PerformAttendRecordQuery;
import com.mortals.xhx.module.perform.model.PerformRulesCategoryEntity;
import com.mortals.xhx.module.perform.model.PerformRulesEntity;
import com.mortals.xhx.module.perform.service.PerformRulesCategoryService;
import com.mortals.xhx.module.perform.service.PerformRulesService;
import com.mortals.xhx.module.perform.service.PerformStaffConfService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.service.StaffService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.perform.dao.PerformAttendRecordDao;
import com.mortals.xhx.module.perform.model.PerformAttendRecordEntity;
import com.mortals.xhx.module.perform.service.PerformAttendRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * PerformAttendRecordService
 * 考勤绩效记录信息 service实现
 *
 * @author zxfei
 * @date 2023-07-10
 */
@Service("performAttendRecordService")
@Slf4j
public class PerformAttendRecordServiceImpl extends AbstractCRUDServiceImpl<PerformAttendRecordDao, PerformAttendRecordEntity, Long> implements PerformAttendRecordService {

    @Autowired
    private CheckAttendRecordService checkAttendRecordService;
    @Autowired
    private AttendanceGroupService attendanceGroupService;
    @Autowired
    private AttendanceGroupFixedworkService fixedworkService;
    @Autowired
    private AttendanceClassDetailService classDetailService;
    @Autowired
    private PerformRulesCategoryService categoryService;
    @Autowired
    private PerformRulesService rulesService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private PerformStaffConfService performStaffConfService;

    @Override
    protected void saveBefore(PerformAttendRecordEntity entity, Context context) throws AppException {
        updateStaffRuleNames(entity, context);
    }

    @Override
    protected void updateBefore(PerformAttendRecordEntity entity, Context context) throws AppException {
        updateStaffRuleNames(entity, context);
    }


    private void updateStaffRuleNames(PerformAttendRecordEntity entity, Context context) {

        if (!ObjectUtils.isEmpty(entity.getRuleId())) {
            PerformRulesEntity rulesEntity = rulesService.getCache(entity.getRuleId().toString());
            entity.setRuleName(rulesEntity == null ? "" : rulesEntity.getName());
            entity.setSubAddType(rulesEntity == null ? 2 : rulesEntity.getSubAddType());
        }
        if (!ObjectUtils.isEmpty(entity.getStaffId())) {
            StaffEntity staffCache = staffService.getCache(entity.getStaffId().toString());
            entity.setStaffName(staffCache == null ? "" : staffCache.getName());
            entity.setDeptName(staffCache == null ? "" : staffCache.getDeptName());
            entity.setSalaId(staffCache == null ? null : staffCache.getSalaId());
            entity.setSalaName(staffCache == null ? "" : staffCache.getSalaName());
            entity.setWorkNum(staffCache == null ? "" : staffCache.getWorkNum());
        }
        entity.setErrorResult(entity.getRuleName());
        entity.setDeductTime(new Date());
        if (ObjectUtils.isEmpty(entity.getDeductPerson())) {
            entity.setDeductPerson(context == null ? "" : context.getUser() == null ? "" : context.getUser().getRealName());
        }
        if (!ObjectUtils.isEmpty(entity.getAttendanceGroupId())) {
            AttendanceGroupEntity attendanceGroupEntity = attendanceGroupService.get(entity.getAttendanceGroupId());
            entity.setAttendanceGroupName(attendanceGroupEntity == null ? "" : attendanceGroupEntity.getGroupName());

            if (!ObjectUtils.isEmpty(attendanceGroupEntity)) {
                //判断上下班时间
                if (TypeEnum.固定班制.getValue() == attendanceGroupEntity.getType()) {
                    AttendanceGroupFixedworkEntity fixedworkEntity = fixedworkService.selectOne(new AttendanceGroupFixedworkQuery().groupId(attendanceGroupEntity.getId()));
                    if (!ObjectUtils.isEmpty(fixedworkEntity)) {
                        //查看当前时间是星期几
                        int dayOfWeek = DateUtil.dayOfWeek(entity.getAttendanceDate());
                        switch (dayOfWeek) {
                            case 1:
                                String goOffWorkStr = getGoOffWorkStr(fixedworkEntity.getSundayClassId());
                                entity.setGoOffTimeStr(goOffWorkStr);
                                break;
                            case 2:
                                goOffWorkStr = getGoOffWorkStr(fixedworkEntity.getMondayClassId());
                                entity.setGoOffTimeStr(goOffWorkStr);
                                break;
                            case 3:
                                goOffWorkStr = getGoOffWorkStr(fixedworkEntity.getTuesdayClassId());
                                entity.setGoOffTimeStr(goOffWorkStr);
                                break;
                            case 4:
                                goOffWorkStr = getGoOffWorkStr(fixedworkEntity.getWednesdayClassId());
                                entity.setGoOffTimeStr(goOffWorkStr);
                                break;
                            case 5:
                                goOffWorkStr = getGoOffWorkStr(fixedworkEntity.getTuesdayClassId());
                                entity.setGoOffTimeStr(goOffWorkStr);
                                break;
                            case 6:
                                goOffWorkStr = getGoOffWorkStr(fixedworkEntity.getFridayClassId());
                                entity.setGoOffTimeStr(goOffWorkStr);
                                break;
                            case 7:
                                goOffWorkStr = getGoOffWorkStr(fixedworkEntity.getSundayClassId());
                                entity.setGoOffTimeStr(goOffWorkStr);
                                break;
                            default:
                                entity.setGoOffTimeStr("");
                        }
                    }
                } else if (TypeEnum.自由工时.getValue() == attendanceGroupEntity.getType()) {

                } else if (TypeEnum.排班制.getValue() == attendanceGroupEntity.getType()) {

                } else {

                }

            }
        }


    }

    private String getGoOffWorkStr(Long sundayClassId) {
        if (ObjectUtils.isEmpty(sundayClassId)) return "";

        StringBuilder goOffWorkSb = new StringBuilder();
        List<AttendanceClassDetailEntity> classDetailEntities = classDetailService.find(new AttendanceClassDetailQuery().classId(sundayClassId));
        if (!ObjectUtils.isEmpty(classDetailEntities)) {
            for (AttendanceClassDetailEntity classDetailEntity : classDetailEntities) {
                String goWorkStr = "";
                String offWorkStr = "";
                if (!ObjectUtils.isEmpty(classDetailEntity.getGoWorkDate())) {
                    goWorkStr = DateUtil.format(classDetailEntity.getGoWorkDate(), "HH:mm");
                }
                if (!ObjectUtils.isEmpty(classDetailEntity.getOffWorkDate())) {
                    offWorkStr = DateUtil.format(classDetailEntity.getOffWorkDate(), "HH:mm");
                }
                goOffWorkSb.append(goWorkStr);
                goOffWorkSb.append("~");
                goOffWorkSb.append(offWorkStr);
                goOffWorkSb.append(" \n");
            }
        }
        return goOffWorkSb.toString();
    }

    @Override
    protected void saveAfter(PerformAttendRecordEntity entity, Context context) throws AppException {
        CheckAttendRecordEntity checkAttendRecordEntity = new CheckAttendRecordEntity();
        checkAttendRecordEntity.initAttrValue();
        BeanUtils.copyProperties(entity, checkAttendRecordEntity, BeanUtil.getNullPropertyNames(entity));
        checkAttendRecordEntity.setId(null);
        checkAttendRecordEntity.setRecordId(entity.getId());
        checkAttendRecordEntity.setCheckTime(entity.getErrorTime());
        checkAttendRecordEntity.setDeductTime(entity.getErrorTime());
        if(performStaffConfService.checkRules(entity.getStaffId(),entity.getDeptId(),entity.getRuleId())){
            checkAttendRecordEntity.setCheckStatus(CheckStatusEnum.已处理.getValue());
            if(checkAttendRecordEntity.getSubAddType()==SubAddTypeEnum.增加.getValue()){
                checkAttendRecordEntity.setCheckResult(CheckResultAddEnum.核查加分.getValue());
            }else {
                checkAttendRecordEntity.setCheckResult(CheckResultSubEnum.核查扣分.getValue());
            }
            checkAttendRecordEntity.setUpdateTime(new Date());
        }else {
            checkAttendRecordEntity.setCheckStatus(CheckStatusEnum.未处理.getValue());      //非自动扣分相设置为未处理
        }
        checkAttendRecordService.save(checkAttendRecordEntity, context);
    }

    @Override
    public void updateProcessStatus(Long id, Integer status) throws AppException {
        if (id == null) {
            throw new AppException("考勤绩效记录Id不能为空");
        }
        PerformAttendRecordEntity entity = this.get(id);
        if (entity == null) {
            throw new AppException("无效的考勤绩效记录Id");
        }
        if (status == null) {
            status = 1; //处理状态(1.未核查,2.已核查)
        }
        PerformAttendRecordEntity update = new PerformAttendRecordEntity();
        update.setId(id);
        update.setProcessStatus(status);
        update.setUpdateTime(new Date());
        dao.update(update);
    }

    @Override
    public void saveAttend(AttendSaveReq req, Context context) throws AppException {
        //考勤保存
        //通过手机号码查询员工属性
        PerformRulesEntity rule = getRule(req.getRuleCode());
        if (ObjectUtils.isEmpty(req.getStaffId())) return;
        StaffEntity staffEntity = staffService.getCache(req.getStaffId().toString());
        PerformAttendRecordEntity recordEntity = new PerformAttendRecordEntity();
        recordEntity.initAttrValue();
        recordEntity.setSubMethod(SubMethodEnum.系统自动.getValue());
        BeanUtils.copyProperties(req, recordEntity);
        recordEntity.setStaffId(staffEntity.getId());
        recordEntity.setStaffName(staffEntity.getName());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        recordEntity.setDeptId(staffEntity.getDeptId());
        recordEntity.setDeptName(staffEntity.getDeptName());
        recordEntity.setSalaId(staffEntity.getSalaId());
        recordEntity.setSalaName(staffEntity.getSalaName());
        recordEntity.setSubAddType(rule.getSubAddType());
        recordEntity.setScore(rule.getScore());
        recordEntity.setRuleId(rule.getId());
        recordEntity.setRuleName(rule.getName());
        recordEntity.setCategoryId(rule.getCategoryId());
        recordEntity.setCategoryName(rule.getCategoryName());
        recordEntity.setDeductPerson("系统管理员");
        recordEntity.setDeductTime(req.getErrorTime());
        recordEntity.setCreateUserId(1L);
        recordEntity.setCreateTime(new Date());
        recordEntity.setWorkNum(staffEntity.getWorkNum());
        PerformRulesCategoryEntity categoryEntity = categoryService.get(rule.getCategoryId());
        recordEntity.setCategoryName(categoryEntity == null ? "" : categoryEntity.getName());

        //校验是否已经存在 不存在再添加新记录
        PerformAttendRecordQuery query = new PerformAttendRecordQuery();
        query.setStaffId(recordEntity.getStaffId());
        query.setErrorTime(recordEntity.getErrorTime());
        query.setRuleId(recordEntity.getRuleId());

        PerformAttendRecordEntity performAttendRecordEntity = this.selectOne(query);
        if (ObjectUtils.isEmpty(performAttendRecordEntity)) {
            this.save(recordEntity);
        } else {
            if(performAttendRecordEntity.getRuleId().longValue()!=recordEntity.getRuleId().longValue()){
                Long[] ids = new Long[1];
                ids[0]=performAttendRecordEntity.getId();
                this.remove(ids,null);
                this.save(recordEntity);
            }
           // log.info("已经存在考勤记录，无需重复添加！");
        }
        //   this.save(recordEntity);
    }

    private PerformRulesEntity getRule(String ruleCode) {
        PerformRulesEntity rule = rulesService.getCache(ruleCode);
        if (ObjectUtils.isEmpty(rule))
            throw new AppException(String.format("当前绩效规则编码没有匹配到正确的规则！rule:%s", ruleCode));

        return rule;
    }


    @Override
    protected void removeBefore(Long[] ids, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(ids)) {
            PerformAttendRecordQuery query = new PerformAttendRecordQuery();
            query.setIdList(Arrays.asList(ids));
            List<PerformAttendRecordEntity> performAttendRecordEntities = this.find(query, context);

            if (!ObjectUtils.isEmpty(performAttendRecordEntities)) {
                Long[] delIds = performAttendRecordEntities.stream().map(i -> i.getId()).toArray(Long[]::new);
                if (!ObjectUtils.isEmpty(delIds)) {
                    CheckAttendRecordQuery checkAttendRecordQuery = new CheckAttendRecordQuery();
                    checkAttendRecordQuery.setRecordIdList(Arrays.asList(delIds));
                    List<CheckAttendRecordEntity> checkAttendRecordEntities = checkAttendRecordService.find(checkAttendRecordQuery, context);
                    if (!ObjectUtils.isEmpty(checkAttendRecordEntities)) {
                        Long[] checkIds = checkAttendRecordEntities.stream().map(i -> i.getId()).toArray(Long[]::new);
                        checkAttendRecordService.remove(checkIds,context);
                      //  log.info("删除考勤核查记录成功,size:{}",checkIds.length);
                    }
                }
            }

        }

    }
}