package com.mortals.xhx.module.attendance.web;

import com.mortals.framework.exception.AppException;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.GoWorkResultEnum;
import com.mortals.xhx.common.code.OffWorkResultEnum;
import com.mortals.xhx.module.attendance.model.*;
import com.mortals.xhx.module.attendance.service.AttendanceClassService;
import com.mortals.xhx.module.attendance.service.AttendanceGroupService;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mortals.framework.model.Context;

import com.mortals.xhx.module.attendance.service.AttendanceRecordService;

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

/**
 * 考勤打卡记录信息
 *
 * @author zxfei
 * @date 2023-04-07
 */
@RestController
@RequestMapping("attendance/record")
public class AttendanceRecordController extends BaseCRUDJsonBodyMappingController<AttendanceRecordService, AttendanceRecordEntity, Long> {

    @Autowired
    private ParamService paramService;

    @Autowired
    private AttendanceGroupService attendanceGroupService;

    @Autowired
    private DeptService deptService;

    @Autowired
    private AttendanceClassService attendanceClassService;

    public AttendanceRecordController() {
        super.setModuleDesc("考勤打卡记录信息");
    }

    @Override
    protected void init(Map<String, Object> model, Context context) {
        this.addDict(model, "deptId", deptService.find(new DeptQuery()).stream().collect(Collectors.toMap(x -> x.getId().toString(), y -> y.getDeptName())));
        this.addDict(model, "groupId", attendanceGroupService.find(new AttendanceGroupQuery()).stream().collect(Collectors.toMap(x -> x.getId().toString(), y -> y.getGroupName())));
        this.addDict(model, "classId", attendanceClassService.find(new AttendanceClassQuery()).stream().collect(Collectors.toMap(x -> x.getId().toString(), y -> y.getClassName())));
        this.addDict(model, "goWorkResult", GoWorkResultEnum.getEnumMap());
        this.addDict(model, "offWorkResult", OffWorkResultEnum.getEnumMap());

        //设置

        super.init(model, context);
    }


    @Override
    protected void doListBefore(AttendanceRecordEntity query, Map<String, Object> model, Context context) throws AppException {
        if (query.getClassId()!=null){
            query.setShiftsId(query.getClassId());
        }
        if (query.getGroupId()!=null){
            query.setAttendanceGroupId(query.getGroupId());
        }
        super.doListBefore(query, model, context);
    }

    @Override
    protected int doListAfter(AttendanceRecordEntity query, Map<String, Object> model, Context context) throws AppException {

        List<AttendanceRecordEntity> list = (List<AttendanceRecordEntity>) model.get(KEY_RESULT_DATA);
        List<AttendanceRecordDetailEntity> collect = list.parallelStream()
                .flatMap(item -> item.getAttendanceRecordDetailList().stream())
                .distinct()
                .sorted(Comparator.comparingInt(AttendanceRecordDetailEntity::getOrderNum))
                .collect(Collectors.toList());
        List<AttDsyncColumn> dsyncColumns = new ArrayList<>();
        List<AttDsyncColumn> resultDsyncColumns = new ArrayList<>();
        collect.forEach(item -> {
            AttDsyncColumn attDsyncColumn = new AttDsyncColumn();
            attDsyncColumn.setName(String.format("上班%s打卡时间", item.getOrderNum()));
            attDsyncColumn.setProperty("goWorkDate");
            attDsyncColumn.setOrderNum(item.getOrderNum());
            dsyncColumns.add(attDsyncColumn);

            attDsyncColumn = new AttDsyncColumn();
            attDsyncColumn.setName(String.format("上班%s打卡结果", item.getOrderNum()));
            attDsyncColumn.setProperty("goWorkResult");
            attDsyncColumn.setOrderNum(item.getOrderNum());
            dsyncColumns.add(attDsyncColumn);

            attDsyncColumn = new AttDsyncColumn();
            attDsyncColumn.setName(String.format("下班%s打卡时间", item.getOrderNum()));
            attDsyncColumn.setProperty("offWorkDate");
            attDsyncColumn.setOrderNum(item.getOrderNum());
            dsyncColumns.add(attDsyncColumn);

            attDsyncColumn = new AttDsyncColumn();
            attDsyncColumn.setName(String.format("下班%s打卡结果", item.getOrderNum()));
            attDsyncColumn.setProperty("offWorkResult");
            attDsyncColumn.setOrderNum(item.getOrderNum());
            dsyncColumns.add(attDsyncColumn);
        });
        Set<Integer> dsyncSet = dsyncColumns.stream().map(i -> i.getOrderNum()).collect(Collectors.toSet());
        //填充空的detail 对象
        Iterator<AttendanceRecordEntity> iterator = list.iterator();
        while (iterator.hasNext()) {
            AttendanceRecordEntity recordEntity = iterator.next();
            Set<Integer> existSet = recordEntity.getAttendanceRecordDetailList().stream().map(i -> i.getOrderNum()).collect(Collectors.toSet());
            //判断详细列表中是否存在顺序 没有自动填充空对象数据
            List<AttendanceRecordDetailEntity> addDetailList = dsyncSet.stream().map(i -> {
                if (!existSet.contains(i)) {
                    AttendanceRecordDetailEntity recordDetailEntity = new AttendanceRecordDetailEntity();
                    recordDetailEntity.initAttrValue();
                    recordDetailEntity.setOrderNum(i);
                    return recordDetailEntity;
                }
                return null;
            }).filter(f -> f != null).collect(Collectors.toList());

            if (ObjectUtils.isEmpty(addDetailList)) {
                recordEntity.getAttendanceRecordDetailList().addAll(addDetailList);

                List<AttendanceRecordDetailEntity> orderList = recordEntity.getAttendanceRecordDetailList().stream().sorted(Comparator.comparingInt(AttendanceRecordDetailEntity::getOrderNum))
                        .collect(Collectors.toList());
                recordEntity.setAttendanceRecordDetailList(orderList);
            }
        }

        model.put("dyncColumns", dsyncColumns);
        //出勤情况
        //总人数
        Integer total = (Integer)model.get("total");
        //未出勤
        Integer noAtt = 0;
        //迟到
        Integer beLate = 0;
        //早退
        Integer leaveEarly = 0;
        //缺卡
        Integer lackOfCards = 0;
        for (AttendanceRecordEntity attendanceRecordEntity : list) {
            boolean a = true;
            for (AttendanceRecordDetailEntity item : attendanceRecordEntity.getAttendanceRecordDetailList()) {
                if (item.getGoWorkResult()==3){
                    lackOfCards=lackOfCards+1;
                }
                if (item.getGoWorkResult()==4){
                    beLate = beLate+1;
                }
                if (item.getOffWorkResult()==3){
                    lackOfCards=lackOfCards+1;
                }
                if (item.getOffWorkResult()==5){
                    leaveEarly = leaveEarly +1;
                }
                if (item.getGoWorkResult()!=3 || item.getOffWorkResult()!=3){
                    a  = false;
                }
            }
            if (a){
                noAtt = noAtt+1;
            }
        }

        String attPercentage = "";
        if (total!=0){
            float l = ((total - noAtt) / total)*100;
            attPercentage =l+"%";
        }else {
            attPercentage = "0";
        }
        AttendanceStatus attendanceStatus = new AttendanceStatus();
        attendanceStatus.setNeedAttNum(total);
        attendanceStatus.setAttPercentage(attPercentage);
        attendanceStatus.setNoAtt(noAtt);
        attendanceStatus.setBeLate(beLate);
        attendanceStatus.setLeaveEarly(leaveEarly);
        attendanceStatus.setLackOfCards(lackOfCards);
        model.put("attendanceStatus",attendanceStatus);

        return super.doListAfter(query, model, context);
    }
}
