package com.qy.worksheetsystem.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.qy.worksheetsystem.model.MessageResult;
import com.qy.worksheetsystem.model.MessageResultV2;
import com.qy.worksheetsystem.model.mapper.*;
import com.qy.worksheetsystem.service.impl.EmployeeReportingServiceImpl;
import com.qy.worksheetsystem.service.impl.WeiXinAuthorizeServiceImpl;
import com.qy.worksheetsystem.vo.CancelOnDateVO;
import com.qy.worksheetsystem.vo.WorkSheetVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;

/**
 * 报工相关service
 */
@Slf4j
@Service
public class WorkSheetService {
    @Resource
    private EmployeeReportingMapper mapper;
    @Resource
    private EmployeeReportingServiceImpl service;
    @Value("${weixin.url}")
    private String WXUrl;
    @Resource
    private THRATSWorkCalendarItemMapper HRWorkmapper;
    @Resource
    private WeiXinAuthorizeServiceImpl wXService;
    @Resource
    private WorkSheetMapper workSheetMapper;
    @Resource
    private ProjectMapper projectMapper;
    @Value("${HR.OrgNumber}")
    private String OrgNumber;
    @Value("${HR.AttendanceType}")
    private String AttendanceType;
    @Transactional
    public synchronized MessageResult cancelOnDate(String number, CancelOnDateVO cancelOnDateVO) {
        try {
            if (StrUtil.isNotEmpty(cancelOnDateVO.getDetailId())) {
                Map map = workSheetMapper.getEntryById(cancelOnDateVO.getDetailId());
                if (ObjectUtil.isNull(map.get("FID"))) {
                    return MessageResult.error("未找到报工明细数据！");
                } else {
                    if(!"2".equals(map.get("CFStatus").toString())){
                        return MessageResult.error("只能撤回待审核的数据！");
                    }else{
                        cancelOnDateVO.setStatus(1);
                        this.splitWorkSheet(map,cancelOnDateVO);
                    }

                }
                return MessageResult.success();
            } else if (StrUtil.isNotEmpty(cancelOnDateVO.getTimeSheetId())) {
                Map map = workSheetMapper.getJobBookingById(cancelOnDateVO.getTimeSheetId());
                if (ObjectUtil.isNull(map.get("FID"))) {
                    return MessageResult.error("未找到报工数据！");
                } else {
                    if(!"2".equals(map.get("CFStatus").toString())){
                        return MessageResult.error("只能撤回待审核的数据！");
                    }else{
                        workSheetMapper.updateStatusById(1, cancelOnDateVO.getTimeSheetId());
                        workSheetMapper.updateEntryStatusByParentId(1, cancelOnDateVO.getTimeSheetId());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("====detailId==="+cancelOnDateVO.getDetailId()+"==========timeSheetId======"+cancelOnDateVO.getTimeSheetId());
            return MessageResult.error("失败！请联系管理员！");
        }
        return MessageResult.success();
    }

    private Map copyMap(Map<String,String> source,Map des){
        for(String key:source.keySet()){//keySet获取map集合key的集合  然后在遍历key即可
            des.put(key,source.get(key));
        }
        return des;
    }
    private synchronized void splitWorkSheet(Map map,CancelOnDateVO cancelOnDateVO){
        String parentId = map.get("FParentID").toString();
        Map jobBookingMap = workSheetMapper.getJobBookingById(parentId);
        DateTime reportDate = DateUtil.parse(map.get("CFReportDate").toString());
        Calendar reportCalendar = Calendar.getInstance();
        reportCalendar.setTime(reportDate);
        List<Map<String, String>> entryByParentId = workSheetMapper.getEntryByParentId(parentId);
        List<Map<String, String>> beforeList = new ArrayList<>();
        List<Map<String, String>> afterList = new ArrayList<>();
        for(int i=0;i<entryByParentId.size();i++){
            Map temp = entryByParentId.get(i);
            DateTime temp_date = DateUtil.parse(temp.get("CFReportDate").toString());
            if(reportDate.getTime() > temp_date.getTime()){
                beforeList.add(temp);
            }else if(reportDate.getTime() < temp_date.getTime()){
                afterList.add(temp);
            }else{

            }
        }
        if(null != beforeList && beforeList.size() >0){
            Map beforeMap = new HashMap();
            beforeMap = copyMap(jobBookingMap,beforeMap);
            String billId = mapper.selectKey();
            Date CFBeginDate = (Date)beforeMap.get("CFBeginDate");
            String beginTime = DateUtil.formatDate(CFBeginDate);
            String endTime ="";
            Date CFEndDate = (Date)map.get("CFReportDate");
            Calendar c = Calendar.getInstance();
            c.setTime(CFEndDate);
            c.add(Calendar.DAY_OF_MONTH,-1);
            int begin = Integer.parseInt(beginTime.substring(8,10));
            endTime = DateUtil.formatDate(c.getTime());
            int end = Integer.parseInt(endTime.substring(8,10));
            if(begin == end){
                endTime = beginTime;
                beforeMap.put("CFTitle", begin+"号");
            }else{
                beforeMap.put("CFTitle", begin+"-"+end+"号");
            }

            beforeMap.put("billId",billId);
            beforeMap.put("CFBeginDate",beginTime);
            beforeMap.put("CFEndDate",endTime);
            int workHours = 0;
            for(int i=0;i<beforeList.size();i++){
                Map tempEntry = beforeList.get(i);
                workHours = workHours+(tempEntry.get("CFWorkingHours") == null ? 0 : Integer.parseInt(tempEntry.get("CFWorkingHours").toString()));
                workSheetMapper.updateEntryParentIdById(billId,tempEntry.get("FID").toString());
            }
            beforeMap.put("CFWorkingHours",workHours);
            mapper.insertBill(beforeMap);
        }

        if(null != afterList && afterList.size() >0){
            Map afterMap = new HashMap();
            afterMap = copyMap(jobBookingMap,afterMap);
            String billId = mapper.selectKey();
            String beginTime = "";
            Date CFEndDate = (Date)afterMap.get("CFEndDate");
            String endTime = DateUtil.formatDate(CFEndDate);
            Date CFBeginDate = (Date)map.get("CFReportDate");
            Calendar c = Calendar.getInstance();
            c.setTime(CFBeginDate);
            c.add(Calendar.DAY_OF_MONTH,1);
            beginTime = DateUtil.formatDate(c.getTime());
            int begin = Integer.parseInt(beginTime.substring(8,10));
            int end = Integer.parseInt(endTime.substring(8,10));
            if(begin == end){
                afterMap.put("CFTitle", begin+"号");
            }else{
                afterMap.put("CFTitle", begin+"-"+end+"号");
            }

            afterMap.put("billId",billId);
            afterMap.put("CFBeginDate",beginTime);
            afterMap.put("CFEndDate",endTime);
            int workHours = 0;
            for(int i=0;i<afterList.size();i++){
                Map tempEntry = afterList.get(i);
                workHours = workHours+(tempEntry.get("CFWorkingHours") == null ? 0 : Integer.parseInt(tempEntry.get("CFWorkingHours").toString()));
                workSheetMapper.updateEntryParentIdById(billId,tempEntry.get("FID").toString());
            }
            afterMap.put("CFWorkingHours",workHours);
            mapper.insertBill(afterMap);
        }
        map.put("CFStatus","1");
        int report =  Integer.parseInt(map.get("CFReportDate").toString().substring(8,10));
        jobBookingMap.put("CFTitle",report+"号");
        jobBookingMap.put("CFStatus",cancelOnDateVO.getStatus());
        jobBookingMap.put("CFBeginDate",map.get("CFReportDate"));
        jobBookingMap.put("CFEndDate",map.get("CFReportDate"));
        jobBookingMap.put("CFWorkingHours",map.get("CFWorkingHours"));
        workSheetMapper.updateEntryStatusById(cancelOnDateVO.getStatus(),map.get("FID").toString());
        workSheetMapper.updateJobBooking(jobBookingMap);

    }
    private void sendWX( String wxUserId,String title, String personName) throws Exception {

        Map<String, Object> wwMap = Maps.newHashMap();
        Map<String, Object> valMap = Maps.newHashMap();
        wwMap.put("agentid",wXService.getKs_AgentId());
        wwMap.put("msgtype","textcard");
        wwMap.put("touser", wxUserId);
        wwMap.put("textcard",valMap);
        valMap.put("title", "报工审批提醒");
        StringBuilder content = new StringBuilder();
        content.append("员工"+title+personName+"报工");
        valMap.put("description", content);
        valMap.put("url", WXUrl);
        valMap.put("btntxt", "详情");
        wXService.sendKSMessage(wwMap);
    }
    @Transactional
    public MessageResult appProjectOnDate(String number, CancelOnDateVO cancelOnDateVO) {
        try {
            Map map = workSheetMapper.getEntryById(cancelOnDateVO.getDetailId());
            if (ObjectUtil.isNull(map.get("FID"))) {
                return MessageResult.error("未找到报工数据！");
            } else {
                Date CFBeginDate =  (Date)map.get("CFReportDate");
                Instant instant = CFBeginDate.toInstant();
                ZoneId zoneId = ZoneId.systemDefault();
                // atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
                LocalDate beginTime = instant.atZone(zoneId).toLocalDate();
                if (!service.checkAvailableDate(beginTime)) {
                    return MessageResult.error("已过7号，不能(通过,驳回)上个月的报工！");
                }
               // if ("2".equals(map.get("CFStatus").toString())) {
                    this.splitWorkSheet(map,cancelOnDateVO);
                    //workSheetMapper.updateStatusById(cancelOnDateVO.getStatus(), cancelOnDateVO.getDetailId());
              //  } else {
              //     return MessageResult.error("只能操作待审核数据！");
              //  }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("====detailId==="+cancelOnDateVO.getDetailId());
            return MessageResult.error("失败！请联系管理员！");
        }
        return MessageResult.success();
    }

    public synchronized MessageResult update(String number, WorkSheetVO workSheetVO) {
//        if(StrUtil.isNotEmpty(workSheetVO.getDetailId())){
//            Map<String,Object> personInfo =mapper.getShrPersonInfo(number);
//            String personId = (String) personInfo.get("personId");
//
//            //Map<String,Object> adminInfo =mapper.getShrAdminInfo(workSheetVO.getProjectId());
//            Map map = workSheetMapper.getEntryById(workSheetVO.getDetailId());
//            Map jobBooking = workSheetMapper.getJobBookingById(map.get("FParentID").toString());
//            Date CFReportDate = (Date)map.get("CFReportDate");
//            String reportDate = DateUtil.formatDate(CFReportDate);
//            List<Map<String, String>> reportDateWorkHoursByPerson = workSheetMapper.getReportDateWorkHoursByPerson(personId, reportDate, workSheetVO.getDetailId());
//            int hours = Integer.parseInt(workSheetVO.getWorkingHours());
//            if(null != reportDateWorkHoursByPerson && reportDateWorkHoursByPerson.size() >0){
//                for(int i = 0; i<reportDateWorkHoursByPerson.size();i++){
//                    Map temp_map = reportDateWorkHoursByPerson.get(i);
//                    int temp = Integer.parseInt(temp_map.get("CFWorkingHours").toString());
//                    hours= hours+temp;
//                }
//            }
//            if(hours>8){
//                return MessageResult.error("该日报工已超过8小时，请修正！");
//            }
//
//            Map updateMap = new HashMap();
//            updateMap.put("CFAttendanceID",workSheetVO.getAttendanceType());
//            updateMap.put("CFWorkingHours",workSheetVO.getWorkingHours());
//            updateMap.put("CFOrgID",workSheetVO.getProjectId());
//            updateMap.put("FID",workSheetVO.getDetailId());
//            workSheetMapper.updateEntry(updateMap);
//
//            jobBooking.put("CFAttendanceID",workSheetVO.getAttendanceType());
//            workSheetMapper.updateJobBooking(jobBooking);
//        }else
        try {
            if (StrUtil.isNotEmpty(workSheetVO.getTimeSheetId())) {
                Map<String, Object> personInfo = mapper.getShrPersonInfo(number);
                String personId = (String) personInfo.get("personId");
                //String personId = "ExRZlC0fRRKToAmpIRmnWoDvfe0=
                Map jobBooking = workSheetMapper.getJobBookingById(workSheetVO.getTimeSheetId());
                Date CFBeginDate =  (Date)jobBooking.get("CFBeginDate");
                Date CFEndDate = (Date) jobBooking.get("CFEndDate");
                List<Map<String, String>> entryByParentId = workSheetMapper.getEntryByParentId(workSheetVO.getTimeSheetId());
                if (AttendanceType.equals(workSheetVO.getAttendanceType())) {
                    Integer hours = Integer.parseInt(workSheetVO.getWorkingHours());


                    String beginDate = DateUtil.formatDate(CFBeginDate);
                    String endDate = DateUtil.formatDate(CFEndDate);
                    MessageResult result = service.checkAttWinter(number,beginDate, endDate, hours);
                    if (result.getCode() != 200) {
                        return result;
                    }
                }
                Instant instant = CFBeginDate.toInstant();
                ZoneId zoneId = ZoneId.systemDefault();
                // atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
                LocalDate beginTime = instant.atZone(zoneId).toLocalDate();
                if (!service.checkAvailableDate(beginTime)) {
                    return MessageResult.error("已过7号，不能(通过,驳回)上个月的报工！");
                }
                for (int i = 0; i < entryByParentId.size(); i++) {
                    Map entry = entryByParentId.get(i);

                    Date CFReportDate = (Date) entry.get("CFReportDate");
                    String reportDate = DateUtil.formatDate(CFReportDate);
                    List<Map<String, String>> reportDateWorkHoursByPerson = workSheetMapper.getReportDateWorkHoursByPerson(personId, reportDate, entry.get("FID").toString());
                    int hours = Integer.parseInt(workSheetVO.getWorkingHours());
                    if (null != reportDateWorkHoursByPerson && reportDateWorkHoursByPerson.size() > 0) {
                        for (int n = 0; n < reportDateWorkHoursByPerson.size(); n++) {
                            Map temp_map = reportDateWorkHoursByPerson.get(n);
                            int temp = Integer.parseInt(temp_map.get("CFWorkingHours").toString());
                            hours = hours + temp;
                        }
                    }
                    if (hours > 8) {
                        return MessageResult.error("该日报工已超过8小时，请修正！");
                    }
                    if(StringUtils.isEmpty(workSheetVO.getAttendanceType())){
                        return MessageResult.error("考勤类型为空异常！");
                    }

                    Map<String, String> dateTypeList = HRWorkmapper.getWorkCalendar(reportDate);
                    entry.put("CFAttendanceID", workSheetVO.getAttendanceType());
                    String dateType = dateTypeList.get("dateType");
                    switch (dateType) {
                        case "0":
                            entry.put("CFWorkingHours", workSheetVO.getWorkingHours());
                            break;
                        case "1":
                            entry.put("CFWorkingHours", "0");
                            break;
                        case "2":
                            entry.put("CFWorkingHours", "0");
                            break;
                        default:
                            break;
                    }
                    if (StrUtil.isNotEmpty(workSheetVO.getStatus())) {
                        entry.put("CFStatus", workSheetVO.getStatus());
                    }
                    workSheetMapper.updateEntry(entry);
                }

                jobBooking.put("CFAttendanceID", workSheetVO.getAttendanceType());
                jobBooking.put("CFWorkingHours", workSheetVO.getWorkingHours());
                if (StrUtil.isNotEmpty(workSheetVO.getStatus())) {
                    jobBooking.put("CFStatus", workSheetVO.getStatus());
                    if ("2".equals(workSheetVO.getStatus())) {
                        try {
                            String CFOrgID = (String) jobBooking.get("CFOrgID");

                            List<Map<String, String>> listMap = projectMapper.getProjectListV2(number, "", OrgNumber);
                            for (Map<String, String> stringMap : listMap) {
                                String orgid = stringMap.get("orgId");
                                if (CFOrgID.equals(orgid)) {
                                    sendWX(stringMap.get("wxUserId"), (String) jobBooking.get("CFTitle"), (String) personInfo.get("personName"));
                                    break;
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                workSheetMapper.updateJobBooking(jobBooking);
            } else {
                return MessageResult.error("请填写id");
            }
            return MessageResult.success();
        }catch (Exception e){
            e.printStackTrace();
            return MessageResult.error(e.getMessage());
        }
    }
}