package com.jeeplus.test.cw.contractRegistration.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeeplus.flowable.model.MyNoticeList;
import com.jeeplus.flowable.service.FlowTaskService;
import com.jeeplus.flowable.service.MyNoticeService;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.DictUtils;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.cw.contractRegistration.domain.CwWorkContractBorrow;
import com.jeeplus.test.cw.contractRegistration.domain.CwWorkContractBorrowMessage;
import com.jeeplus.test.cw.contractRegistration.mapper.ContractInfoMapper;
import com.jeeplus.test.cw.contractRegistration.mapper.CwWorkContractBorrowMapper;
import com.jeeplus.test.cw.contractRegistration.mapper.CwWorkContractBorrowMessageMapper;
import com.jeeplus.test.cw.contractRegistration.service.dto.CwWorkContractBorrowDto;
import org.flowable.bpmn.model.FlowNode;
import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author: 王强
 * @create: 2022-11-27 13:51
 **/
@Service
public class CwWorkContractBorrowService {

    @Resource
    private CwWorkContractBorrowMapper borrowMapper;

    @Resource
    private CwWorkContractBorrowMessageMapper messageMapper;

    @Resource
    private ContractInfoMapper infoMapper;

    @Resource
    private MyNoticeService myNoticeService;

    @Resource
    private FlowTaskService flowTaskService;

    public String saveInfo(CwWorkContractBorrowDto workContractBorrowDto) throws Exception {
        if (StringUtils.isNotEmpty(workContractBorrowDto.getId())) {
            CwWorkContractBorrow info = borrowMapper.selectById( workContractBorrowDto.getId());
            if (info != null) {
                infoMapper.updateBorrowTypeById(info.getContractInfoId(),workContractBorrowDto.getBorrowType());
                return update(workContractBorrowDto, info.getContractInfoId());
            }
        }
        return add(workContractBorrowDto);
    }

    /**
     * 合同登记借用新增
     */
    @Transactional(rollbackFor = Exception.class)
    public String add(CwWorkContractBorrowDto workContractBorrowDto) throws Exception{
        //获取当前登录人信息
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        String id = UUID.randomUUID().toString().replace("-", "");
        CwWorkContractBorrow borrow = new CwWorkContractBorrow();
        BeanUtils.copyProperties(workContractBorrowDto, borrow);
        borrow.setId(id);
        borrow.setCreateBy(userDTO.getId());
        borrow.setCreateDate(new Date());
        borrow.setUpdateBy(userDTO.getId());
        borrow.setUpdateDate(new Date());
        borrowMapper.insert(borrow);
        //借用记录信息
        this.saveMessage(workContractBorrowDto, id);
        return id;
    }

    /**
     * 合同登记修改
     */
    @Transactional(rollbackFor = Exception.class)
    public String update(CwWorkContractBorrowDto workContractBorrowDto, String id) {
        //获取当前登录人信息
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        CwWorkContractBorrow borrow = new CwWorkContractBorrow();
        BeanUtils.copyProperties(workContractBorrowDto, borrow);
        borrow.setContractInfoId(id);
        borrow.setUpdateBy(userDTO.getId());
        borrow.setUpdateDate(new Date());
        borrowMapper.updateById(borrow);
        //借用记录信息
        this.saveMessage(workContractBorrowDto, workContractBorrowDto.getId());
        return borrow.getId();
    }
    /**
     * 根据id修改status
     */
    public void updateStatusById(CwWorkContractBorrowDto workContractBorrowDto) {
        borrowMapper.updateStatusById(workContractBorrowDto.getId(), workContractBorrowDto.getBorrowType());
    }

    public void updateStatusByContractInfoId(CwWorkContractBorrowDto workContractBorrowDto) {
        infoMapper.updateBorrowTypeById(workContractBorrowDto.getId(),workContractBorrowDto.getBorrowType());
        borrowMapper.updateStatusByContractInfoId(workContractBorrowDto.getId(), workContractBorrowDto.getBorrowType());
    }

    public CwWorkContractBorrow findById(String id) {
        CwWorkContractBorrow borrow = borrowMapper.selectById(id);
        if (borrow == null) {
            LambdaQueryWrapper<CwWorkContractBorrow> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CwWorkContractBorrow::getContractInfoId, id);
            return borrowMapper.selectOne(wrapper);
        }
        return borrow;
    }

    public CwWorkContractBorrow findByContractInfoId(String id) {
        return borrowMapper.selectFileByContractInfoId(id);
    }

    /**
     * 借用记录保存
     * @param workContractBorrowDto
     * @param id
     * @return
     */
    public void saveMessage (CwWorkContractBorrowDto workContractBorrowDto, String id) {
        //保存借用信息
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        CwWorkContractBorrowMessage message = new CwWorkContractBorrowMessage();
        BeanUtils.copyProperties(workContractBorrowDto, message);
        String messageId = UUID.randomUUID().toString().replace("-", "");
        message.setId(messageId);
        message.setCreateBy(userDTO.getId());
        message.setCreateDate(new Date());
        message.setUpdateBy(userDTO.getId());
        message.setUpdateDate(new Date());
        message.setContractBorrowId(id);
//        message.setBorrowType("3");
        message.setBorrowType(workContractBorrowDto.getBorrowType());
//        message.setRetData(workContractBorrowDto.getBorrowRetData());
        messageMapper.insert(message);
    }

    /**
     * 根据contractBorrowId修改borrowType
     */
    public void updateMessageByBorrowId(CwWorkContractBorrowDto workContractBorrowDto, String type) {
        if ("reture".equals(type)) {
            CwWorkContractBorrow borrow = borrowMapper.selectFileByContractInfoId(workContractBorrowDto.getId());
            if (borrow != null) {
                borrowMapper.updateMessageByBorrowId(borrow.getId(), workContractBorrowDto.getBorrowType(), type);
            }
        } else {
            borrowMapper.updateMessageByBorrowId(workContractBorrowDto.getId(), workContractBorrowDto.getBorrowType(), null);
        }
    }

    public void deleteById(String id) {
        LambdaQueryWrapper<CwWorkContractBorrow> wrapper = new LambdaQueryWrapper<CwWorkContractBorrow>();
        wrapper.eq(CwWorkContractBorrow::getContractInfoId, id);
        CwWorkContractBorrow borrow = borrowMapper.selectOne(wrapper);
        if (borrow != null) {
            borrowMapper.deleteMessageById(borrow.getId());
        }
    }

    public List<CwWorkContractBorrowMessage> findMessageList(String id) {
        CwWorkContractBorrow borrow = findByContractInfoId(id);
        if (borrow != null) {
            return borrowMapper.findMessageList(borrow.getId());
        }
        return null;
    }

    /**
     * 查询临期合同借用信息
     * @return
     */
    public List<CwWorkContractBorrowMessage> getAdventMessageList() {
        String adventDay = DictUtils.getDictLabel("advent_day", "cw_borrow_advent", "");
        adventDay = "-" + adventDay;
        List<CwWorkContractBorrowMessage> adventMessageList = borrowMapper.getAdventMessageList(adventDay);
        if(null != adventMessageList && adventMessageList.size()>0){
            for (CwWorkContractBorrowMessage info : adventMessageList) {
                String taskName = null;
                String titleStr = null;

                //如果当前时间大于过期时间
                //Date类的一个方法，如果info.getAdventDateDate()早于 new Date() 返回true，否则返回false
                if(info.getBorrowRetData().before(new Date())){
                    taskName = "合同【"+ info.getContractName()+"】借用已超期";
                    titleStr = "合同【"+ info.getContractName()+"】借用已超期。超期时间："+dateToString(info.getBorrowRetData()) +"。";
                }else{
                    taskName = "合同【"+ info.getContractName()+"】即将借用超期";
                    titleStr = "合同【"+ info.getContractName()+"】即将借用超期。超期时间："+dateToString(info.getBorrowRetData());
                }


                //计算两日期之间的天数
                Integer interval = Integer.valueOf(this.getInterval(info.getBorrowRetData(), new Date()));
                if(interval > 0){
                    titleStr = titleStr + "已超期：" + interval + "天。请尽快归还";
                }

                Set<String> noticeUserSet = new HashSet<String>();
                if(StringUtils.isNotBlank(info.getBorrowName())){
                    UserDTO borrowUser = UserUtils.getByName(info.getBorrowName());
                    if(null != borrowUser && StringUtils.isNotBlank(borrowUser.getId())){
                        noticeUserSet.add(borrowUser.getId());
                    }
                }
                if(StringUtils.isNotBlank(info.getContractCreateById())){
                    noticeUserSet.add(info.getContractCreateById());
                }
                List<String> noticeUserList = new ArrayList<String>(noticeUserSet);
                if(noticeUserList.size()>0){
                    MyNoticeList myNotice = new MyNoticeList();
                    myNotice.setCreateBy("1");
                    myNotice.setCreateDate(new Date());
                    myNotice.setUpdateBy("1");
                    myNotice.setUpdateDate(new Date());
                    myNotice.setDelFlag(0);
                    //根据procInsId获取taskId
                    String currentTask = flowTaskService.getTaskIdByprocInstId(info.getProcInsId());
                    myNotice.setTaskId(currentTask);
                    myNotice.setDefId(info.getProcessDefinitionId());
                    myNotice.setTitle(titleStr);
                    myNotice.setTaskName(taskName);
                    myNotice.setLink("结束");
                    myNotice.setType("0");
                    myNotice.setCreateUser("管理员");
                    myNotice.setCreateTime(new Date());

                    for (String noticeUserId : noticeUserList) {
                        myNotice.setNoticeId(noticeUserId);
                        myNotice.setNoticeName(UserUtils.get(noticeUserId).getName());
                        //根据taskName和通知人 查询重复数量
                        MyNoticeList repetitionCountBymyNotice = myNoticeService.getRepetitionCountBymyNotice(myNotice);
                        if(null == repetitionCountBymyNotice){
                            // 生成id
                            String id = UUID.randomUUID().toString().replace("-", "");
                            myNotice.setId(id);
                            myNotice.setRepetitionCount(0);
                            myNoticeService.insertMyNotice(myNotice);
                        }else{
                            myNotice.setId(repetitionCountBymyNotice.getId());
                            myNotice.setRepetitionCount(repetitionCountBymyNotice.getRepetitionCount()+1);
                            myNoticeService.updateMyNotice(myNotice);
                        }
                    }

                }
            }
        }
        return null;
    }


    /**
     * 计算两日期相差天数
     * @param beginDate
     * @param endDate
     * @return
     * @throws Exception
     */
    public String getInterval(Date beginDate, Date endDate){
        long day = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            if(beginDate != null){
                String begin = sdf.format(beginDate);
                beginDate  = sdf.parse(begin);
            }
            if(endDate!= null){
                String end= sdf.format(endDate);
                endDate= sdf.parse(end);
            }
        } catch (Exception e){
            e.getMessage();
        }
        day = (endDate.getTime()-beginDate.getTime())/(24*60*60*1000);
        return String.valueOf(day);
    }
    public static String dateToString(Date date) {
        SimpleDateFormat sformat = new SimpleDateFormat("yyyy-MM-dd");//日期格式

        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//24小时制
        // SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//12小时制

        String s = sformat.format(date);

        return s;
    }

}
