/*
 * Author: Zev
 * 生成ServiceImpl
 */
package com.tofly.gpsboot.service.sign.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.tofly.api.DepartmentClient;
import com.tofly.api.UserClent;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.gpsboot.common.system.SignFlagEnum;
import com.tofly.gpsboot.common.system.SignTypeEnum;
import com.tofly.pojo.plan.dto.PdasignhisDto;
import com.tofly.pojo.plan.vo.AttendanceReportVo;
import com.tofly.pojo.plan.vo.PdasignhisVo;
import com.tofly.gpsboot.mapper.plan.PdasignhisMapper;
import com.tofly.pojo.User;
import com.tofly.pojo.plan.Pdasignhis;
import com.tofly.gpsboot.service.sign.PdasignhisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * 上下班签到历史信息表：TF_YWPN_PDASIGNHIS_W
 *
 * @author admin
 * @date Thu Mar 18 00:00:00 CST 2021
 */
@Service("pdasignhisService")
public class PdasignhisServiceImpl extends ServiceImpl<PdasignhisMapper, Pdasignhis> implements PdasignhisService {

    @Autowired
    private UserClent userClent;
    @Autowired
    private DepartmentClient departmentClient;
    @Override
    public List<PdasignhisVo> viewConversion(List<Pdasignhis> infoList) {
        List<PdasignhisVo> infoVoList = new ArrayList<>();
        infoList.forEach(info -> {
            PdasignhisVo baseInfo = JSONObject.parseObject(JSON.toJSONString(info), PdasignhisVo.class);
            // 增加签到用户名称 转换签到类型/签到标识
            Long signUser = info.getSignUser();
            if (null != signUser && 0 != signUser) {
                User userAudit = userClent.getById(signUser).getResult();
                if(null!=userAudit){
                    baseInfo.setSignUserName(userAudit.getRealName());
                    baseInfo.setDeptId(userAudit.getDepartmentId());
                    baseInfo.setDeptName(userAudit.getDepartmentName());
                }

            }

            baseInfo.setSignType(SignTypeEnum.getCodeForValue(info.getSignType()));
            baseInfo.setFlag(SignFlagEnum.getCodeForValue(info.getFlag()));

            infoVoList.add(baseInfo);
        });
        return infoVoList;
    }

    @Override
    public Page<PdasignhisVo> getPdaSignHisPage(Page page, PdasignhisDto parDto) {
        String deptIds = parDto.getDeptIds();
        if (StringUtils.isBlank(deptIds)) {
            deptIds = String.valueOf(SecurityUtils.getUser().getDepartmentId());
        }
        // 当前部门下用户才有权限
//        Long departmentId = SecurityUtils.getUser().getDepartmentId();
        Set<Long> userIdList = departmentClient.getDeptUserList(deptIds).getResult().stream().map(User::getId).collect(Collectors.toSet());
        Date signStartTime = parDto.getSignStartTime();
        Date signEndTime = parDto.getSignEndTime();
        Pdasignhis pdasign = JSONObject.parseObject(JSON.toJSONString(parDto), Pdasignhis.class);
        QueryWrapper<Pdasignhis> queryWrapper = new QueryWrapper<>();
        if (null != signStartTime && null != signEndTime) {
            queryWrapper.ge("SIGN_TIME",signStartTime);
            queryWrapper.lt("SIGN_TIME",signEndTime);
        }
        Long signUser = pdasign.getSignUser();
        if(null==signUser){
            queryWrapper.in("SIGN_USER",userIdList);
        }

        queryWrapper.setEntity(pdasign);
        queryWrapper.orderByDesc("CREATE_TIME");
        Page infoPageList = this.page(page, queryWrapper);
        infoPageList.setRecords(this.viewConversion(infoPageList.getRecords()));
        return infoPageList;
    }

    @Override
    public List<AttendanceReportVo> attendanceReport(String startTime, String endTime, String deptIds) {
        List<AttendanceReportVo> res = new ArrayList<>();
        List<Date> dateList = getBetweenDate(startTime, endTime, 1);
        List<Long> queryUserIds = this.baseMapper.getUserIdList(deptIds);
        List<Pdasignhis> pdasignhisList = this.list();
        dateList.forEach(date -> {
            List<Pdasignhis> pdasignhisListFinal = pdasignhisList.stream()
                    .filter(e -> DateUtil.format(e.getSignTime(), "yyyy-MM-dd").equals(DateUtil.format(date, "yyyy-MM-dd")))
                    .collect(Collectors.toList());
            Map<Long, List<Pdasignhis>> pdUserMap = pdasignhisListFinal.stream().collect(Collectors.groupingBy(Pdasignhis::getSignUser));
            pdUserMap.forEach((k,v) -> {
                if (!queryUserIds.contains(k)) {
                    return;
                }
                AttendanceReportVo vo = new AttendanceReportVo();
                vo.setUserId(k);
                vo.setUserName(v.get(0).getSignUserName());
                vo.setDeptName(v.get(0).getDeptName());
                Map<String, List<Pdasignhis>> pdOnOffMap = v.stream().collect(Collectors.groupingBy(Pdasignhis::getSignType));
                pdOnOffMap.forEach((k1,v1) -> {
                    v1.sort(Comparator.comparing(Pdasignhis::getSignTime));
                    if (k1.equals("1")) {
                        vo.setOnTime(v1.get(0).getSignTime());
                        vo.setOnAddress(v1.get(0).getSignAddress());
                    } else if (k1.equals("2")) {
                        vo.setOffTime(v1.get(v1.size() - 1).getSignTime());
                        vo.setOffAddress(v1.get(v1.size() - 1).getSignAddress());
                    }
                });
                if (vo.getOnTime() != null && vo.getOffTime() != null) {
                    BigDecimal workHours = new BigDecimal(DateUtil.format(vo.getOffTime(), "HH"))
                            .subtract(new BigDecimal(DateUtil.format(vo.getOnTime(), "HH")));
                    vo.setWorkHour(workHours);
                }
                res.add(vo);
            });
        });
        return res;
    }


    /**
     * 获取两个日期之间的所有日期
     * @param start 开始日期
     * @param end 结束日期
     * @param type 0小时 1天 2月
     * @return list
     */
    List<Date> getBetweenDate(String start, String end, Integer type) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(DateUtil.parse(start, "yyyy-MM-dd HH:mm:ss"));
        List<Date> dateList = new ArrayList<>();
        while (DateUtil.format(cal.getTime(), "yyyy-MM-dd HH:mm:ss").compareTo(end) < 0) {
            dateList.add(cal.getTime());
            switch (type) {
                case 0:
                    cal.add(Calendar.HOUR, +1);
                    break;
                case 1:
                    cal.add(Calendar.DATE, +1);
                    break;
                case 2:
                    cal.add(Calendar.MONTH, +1);
                    break;
            }
        }
        return dateList;
    }
}
