package com.jpsoft.shinestar.modules.business.service.impl;

import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jpsoft.shinestar.config.WxConfig;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.PersonInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonPopedomService;
import com.jpsoft.shinestar.modules.base.service.WorkPersonSchedulingService;
import com.jpsoft.shinestar.modules.base.service.WorkShiftInfoService;
import com.jpsoft.shinestar.modules.business.dao.AdjustShiftDAO;
import com.jpsoft.shinestar.modules.business.dto.UpdatePersonAttendanceDTO;
import com.jpsoft.shinestar.modules.common.utils.WechatMessageUtil;
import com.jpsoft.shinestar.modules.business.entity.AdjustShift;
import com.jpsoft.shinestar.modules.business.entity.AdjustShiftPerson;
import com.jpsoft.shinestar.modules.business.service.AdjustShiftPersonService;
import com.jpsoft.shinestar.modules.business.service.AdjustShiftService;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.utils.JwtUtil2;
import com.jpsoft.shinestar.modules.workflow.entity.*;
import com.jpsoft.shinestar.modules.workflow.service.*;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author 墨鱼_mo
 * @date 2021-4-27 15:13
 */
@Transactional(rollbackFor = Exception.class)
@Component(value = "adjustShiftService")
public class AdjustShiftServiceImpl implements AdjustShiftService {

    @Resource(name = "adjustShiftDAO")
    private AdjustShiftDAO adjustShiftDAO;

    @Autowired
    private WorkPersonSchedulingService workPersonSchedulingService;

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Autowired
    private WxConfig wxConfig;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    private ProcinstService procinstService;

    @Autowired
    private ProcinstActivityService procinstActivityService;

    @Autowired
    private ProcinstActUserService procinstActUserService;

    @Autowired
    private WorkShiftInfoService workShiftInfoService;

    @Autowired
    private ProcessActivityService processActivityService;

    @Autowired
    private AdjustShiftPersonService adjustShiftPersonService;

    @Autowired
    private ValueOperations<String, Object> valueOperations;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private PersonPopedomService personPopedomService;

    @Override
    public AdjustShift get(String id) {
        // TODO Auto-generated method stub
        return adjustShiftDAO.get(id);
    }

    @Override
    public int insert(AdjustShift model) {
        // TODO Auto-generated method stub
        //model.setId(UUID.randomUUID().toString());

        return adjustShiftDAO.insert(model);
    }

    @Override
    public int update(AdjustShift model) {
        // TODO Auto-generated method stub
        return adjustShiftDAO.update(model);
    }

    @Override
    public int delete(String id) {
        // TODO Auto-generated method stub
        return adjustShiftDAO.delete(id);
    }

    @Override
    public boolean exist(String id) {
        // TODO Auto-generated method stub
        int count = adjustShiftDAO.exist(id);

        return count > 0 ? true : false;
    }

    @Override
    public List<AdjustShift> list() {
        // TODO Auto-generated method stub
        return adjustShiftDAO.list();
    }

    @Override
    public Page<AdjustShift> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<AdjustShift> page = PageHelper.startPage(pageNumber, pageSize, count).doSelectPage(() -> {
            adjustShiftDAO.search(searchParams, sortList);
        });

        return page;
    }

    @Override
    public String adjustShiftSubmit(PersonPopedom personPopedom, String date, String shiftIds, String remark, String formId,String ids,String draft) throws Exception {


            Date dateTime = DateUtil.parse(date, "yyyy-MM-dd HH:mm:ss");
            WorkPersonScheduling workPersonScheduling = workPersonSchedulingService.findByPersonIdSchedulingDay(personPopedom.getPersonId(), dateTime);

            List<AdjustShift> adjustShiftList = findBySchedulingIdAndStatus(workPersonScheduling.getId(), "1");
            if (adjustShiftList.size() > 0) {
                throw new Exception("当天有正在审核的调班记录");
            }

            if (shiftIds.equals(workPersonScheduling.getShiftIds())) {
                throw new Exception("变更前和变更后的班次不能一样");
            }




            AdjustShift adjustShift = new AdjustShift();
            AdjustShiftPerson adjustShiftPerson = new AdjustShiftPerson();

            if(StringUtils.isNotEmpty(ids)){
                adjustShift=adjustShiftDAO.get(ids);
                adjustShiftPerson=adjustShiftPersonService.findByAdjustShiftId(ids).get(0);
                }else{
                    adjustShift = new AdjustShift();
                    adjustShiftPerson = new AdjustShiftPerson();
                    adjustShift.setId(UUID.randomUUID().toString());
                    adjustShiftPerson.setId(UUID.randomUUID().toString());
            }

            //创建主业务表
            adjustShift.setPersonPopedomId(personPopedom.getId());
            //  adjustShift.setSchedulingId(workPersonScheduling.getId());
            adjustShift.setAdjustDate(DateUtil.format(dateTime, "yyyy-MM-dd"));
            //  adjustShift.setNewShiftId(shiftIds);

            List<String> idList = Arrays.asList(shiftIds.split(","));
            String shiftNumber = "";
            for (String shiftId : idList) {
                WorkShiftInfo workShiftInfo = workShiftInfoService.get(shiftId);
                if (StringUtils.isBlank(shiftNumber)) {
                    shiftNumber = workShiftInfo.getNumber();
                } else {
                    shiftNumber = shiftNumber + "," + workShiftInfo.getNumber();
                }
            }

            //   adjustShift.setNewShiftNumber(shiftNumber);


            //   adjustShift.setOldShiftId(workPersonScheduling.getShiftIds());
            adjustShift.setRemark(remark);
            adjustShift.setType("1");
            adjustShift.setStatus("-99");
            adjustShift.setSubmitTime(new Date());
            adjustShift.setCreateTime(new Date());


            //创建业务子表

            adjustShiftPerson.setAdjustShiftId(adjustShift.getId());
            adjustShiftPerson.setSchedulingId(workPersonScheduling.getId());
            adjustShiftPerson.setPersonPopedomId(personPopedom.getId());
            adjustShiftPerson.setNewShiftId(shiftIds);
            adjustShiftPerson.setNewShiftNumber(shiftNumber);
            adjustShiftPerson.setOldShiftId(workPersonScheduling.getShiftIds());
            adjustShiftPerson.setCreateTime(new Date());

            if(StringUtils.isNotEmpty(ids)){
                update(adjustShift);
                adjustShiftPersonService.update(adjustShiftPerson);
            }else {
                insert(adjustShift);
                adjustShiftPersonService.insert(adjustShiftPerson);
            }



            if ("1".equals(draft)) {
                // String procinstId = ((ProcinstService)AopContext.currentProxy()).addProcinst(adjustShift.getId(),"调班",formId,personPopedom);
                String procInstId = procinstService.addProcInst(adjustShift.getId(),  "调班", formId, personPopedom, null,null,null);

                adjustShift.setProcinstId(procInstId);
                adjustShift.setStatus("0");
                update(adjustShift);
                adjustShiftPersonService.update(adjustShiftPerson);


                ProcinstActivity procinstActivity = procinstActivityService.findByActivityIndexAndProcinstId(1, procInstId);

                if (procinstActivity != null) {
                    List<ProcinstActUser> procinstActUserList = procinstActUserService.findByProcinstActivityIdActionType(procinstActivity.getId(), "0", "1");
                    if (procinstActUserList.size() > 0) {
                        for (ProcinstActUser procinstActUser : procinstActUserList) {

                            try {
                                PersonInfo personInfo = personInfoService.get(Long.parseLong(procinstActUser.getUserId()));

                                if (StringUtils.isNotBlank(personInfo.getOpenId())) {
                                    //提交人
                                    PersonInfo personInfo1 = personInfoService.get(personPopedom.getPersonId());
                                    String accessToken = JwtUtil2.createToken(jwtSecret, personInfo.getId() + "", DateTime.now().plusHours(30 * 24).toDate());
                                    AdjustShift finalAdjustShift = adjustShift;
                                    new Thread(() -> {
                                        WechatMessageUtil.sendEvenMessage(personInfo.getOpenId(), "有一条新的调班信息待审核", personInfo1.getName(), com.jpsoft.shinestar.modules.common.utils.StringUtils.getApprovalNo(), "前往处理", wxConfig.getPortalUrl() + "xsy/approval/infosp?id=" + finalAdjustShift.getId() + "&procinstActUserId=" + procinstActUser.getId() + "&formId=" + formId + "&token=" + accessToken, wxConfig.getAppId(), wxConfig.getAppSecret());
                                    }).start();
                                }
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }

                        }
                    }
                }


            }


            return adjustShift.getId();


    }

    @Override
    public List<AdjustShift> findBySchedulingIdAndStatus(String schedulingId, String status) {
        return adjustShiftDAO.findBySchedulingIdAndStatus(schedulingId, status);
    }

    @Override
    public String arrangeShiftSubmit(PersonPopedom personPopedom, String personIds, String date, String shiftIds, String remark) {

        Date dateTime = DateUtil.parse(date, "yyyy-MM-dd HH:mm:ss");
        String shiftNums = "";
        List<String> shiftIdList = Arrays.asList(shiftIds.split(","));
        for (String shiftId : shiftIdList) {
            WorkShiftInfo workShiftInfo = workShiftInfoService.get(shiftId);
            if (StringUtils.isBlank(shiftNums)) {
                shiftNums = workShiftInfo.getNumber();
            } else {
                shiftNums = shiftNums + "," + workShiftInfo.getNumber();
            }
        }

        List<String> personIdList = Arrays.asList(personIds.split(","));
        String adjustShiftId = "";
        if (personIdList.size() > 0) {

            AdjustShift adjustShift = new AdjustShift();
            adjustShift.setId(UUID.randomUUID().toString());
            adjustShift.setPersonPopedomId(personPopedom.getId());
            adjustShift.setAdjustDate(DateUtil.format(dateTime, "yyyy-MM-dd"));
            adjustShift.setRemark(remark);
            adjustShift.setType("2");
            adjustShift.setStatus("4");
            adjustShift.setSubmitTime(new Date());
            adjustShift.setCreateTime(new Date());
            insert(adjustShift);
            adjustShiftId = adjustShift.getId();


            for (String personId : personIdList) {

                PersonInfo personInfo = personInfoService.get(Long.valueOf(personId));
                WorkPersonScheduling workPersonScheduling = workPersonSchedulingService.findByPersonIdSchedulingDay(Long.valueOf(personId), dateTime);
                String schedulingId = "";
                String oldShiftIds = "";

                if (workPersonScheduling == null) {
                    workPersonScheduling = new WorkPersonScheduling();
                    workPersonScheduling.setId(UUID.randomUUID().toString());
                    workPersonScheduling.setPersonId(Long.valueOf(personId));
                    workPersonScheduling.setYear(DateUtil.year(dateTime));
                    workPersonScheduling.setMonth(DateUtil.month(dateTime));
                    workPersonScheduling.setDay(DateUtil.dayOfMonth(dateTime));
                    workPersonScheduling.setSchedulingDay(dateTime);
                    workPersonScheduling.setShiftIds(shiftIds);
                    workPersonScheduling.setShiftNumbers(shiftNums);
                    workPersonScheduling.setCreateTime(new Date());
                    workPersonScheduling.setCreateBy(personPopedom.getId());
                    workPersonSchedulingService.insert(workPersonScheduling);
                    schedulingId = workPersonScheduling.getId();
                    oldShiftIds = shiftIds;
                } else {
                    oldShiftIds = workPersonScheduling.getShiftIds();
                    workPersonScheduling.setShiftIds(shiftIds);
                    workPersonScheduling.setShiftNumbers(shiftNums);
                    workPersonScheduling.setUpdateTime(new Date());
                    workPersonScheduling.setUpdateBy(personPopedom.getId());
                    workPersonSchedulingService.update(workPersonScheduling);
                    schedulingId = workPersonScheduling.getId();

                }

                //创建修改记录
                AdjustShiftPerson adjustShiftPerson = new AdjustShiftPerson();
                adjustShiftPerson.setId(UUID.randomUUID().toString());
                adjustShiftPerson.setAdjustShiftId(adjustShift.getId());
                adjustShiftPerson.setPersonPopedomId(personInfo.getPopedom());
                adjustShiftPerson.setSchedulingId(schedulingId);
                adjustShiftPerson.setNewShiftId(shiftIds);
                adjustShiftPerson.setNewShiftNumber(shiftNums);
                adjustShiftPerson.setOldShiftId(oldShiftIds);
                adjustShiftPerson.setCreateTime(new Date());
                adjustShiftPerson.setCreateBy(personPopedom.getId());
                adjustShiftPersonService.insert(adjustShiftPerson);

                //todo 如果调整当天之前的班次则重新生成考勤
                Date now = new Date();

                if(workPersonScheduling!=null
                && workPersonScheduling.getSchedulingDay()!=null
                && workPersonScheduling.getSchedulingDay().before(now)) {
                    DateTime startTime = new DateTime(workPersonScheduling.getSchedulingDay());
                    DateTime endTime = startTime; //updatePersonAttendance会自动加一天

                    PersonPopedom personPopedom1 = personPopedomService.get(adjustShiftPerson.getPersonPopedomId());

                    UpdatePersonAttendanceDTO updatePersonAttendanceDTO = new UpdatePersonAttendanceDTO(
                            personPopedom1.getPersonId(), startTime.toDate(), endTime.toDate());

                    rabbitTemplate.convertAndSend("updatePersonAttendanceQueue", updatePersonAttendanceDTO);
                }
            }
        }
        return adjustShiftId;
    }
}
