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

import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jpsoft.shinestar.modules.base.dao.MedicationInfoDAO;
import com.jpsoft.shinestar.modules.base.dao.MessageReceiverDAO;
import com.jpsoft.shinestar.modules.base.dto.DaysDTO;
import com.jpsoft.shinestar.modules.base.dto.MedicationDaysDTO;
import com.jpsoft.shinestar.modules.base.entity.MedicationInfo;
import com.jpsoft.shinestar.modules.base.service.MedicationInfoService;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author 墨鱼_mo
 * @date 2020-10-29 16:25
 */
@Slf4j
@Transactional
@Component(value="medicationInfoService")
public class MedicationInfoServiceImpl implements MedicationInfoService {


    @Resource(name="medicationInfoDAO")
    private MedicationInfoDAO medicationInfoDAO;

    @Autowired
    RabbitTemplate rabbitTemplate;

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

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

        return medicationInfoDAO.insert(model);
    }

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

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

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

        return count > 0 ? true : false;
    }

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

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

        return page;
    }

    @Override
    public List<MedicationInfo> findByBeRemindPopedomId(String beRemindPopedomId) {
        return medicationInfoDAO.findByBeRemindPopedomId(beRemindPopedomId);
    }

    @Override
    public List<DaysDTO> getMedicationDays(String id) {

        List<MedicationDaysDTO> medicationDaysDTOList = new ArrayList<>();
        MedicationInfo medicationInfo = get(id);
        List<DaysDTO> daysDTOList = new ArrayList<>();
        if (medicationInfo != null){
            int startMonth = DateUtil.month(medicationInfo.getStartTime()) +1;
            int endMonth = DateUtil.month(medicationInfo.getEndTime()) +1;

            int difference = endMonth - startMonth;


            if (difference == 0){

                for (int i =0;i<medicationInfo.getMedicationDays();i++){
                    DaysDTO daysDTO = new DaysDTO();
                    int num = i*(medicationInfo.getNextDays()+1);
                   // daysDTO.setName(String.valueOf(Integer.parseInt(DateUtil.format(medicationInfo.getStartTime(),"yyyy")) + i*(medicationInfo.getNextDays()+1)));
                    Date date = DateUtil.offsetDay(medicationInfo.getStartTime(),num);
                    daysDTO.setName(DateUtil.format(date,"yyyy-MM-dd"));
                    daysDTO.setTimes(String.valueOf(medicationInfo.getMedicationFrequency()));
                    daysDTOList.add(daysDTO);
                }
                /*MedicationDaysDTO medicationDaysDTO = new MedicationDaysDTO();
                medicationDaysDTO.setName(String.valueOf(startMonth));
                medicationDaysDTO.setList(daysDTOList);
                medicationDaysDTOList.add(medicationDaysDTO);*/
            }
            else {

                //当月有多少天
                int daysMonth = DateUtil.dayOfMonth(DateUtil.endOfMonth(medicationInfo.getStartTime()));
                //已计算的天数
                int daysCalc = 0;
             //   List<DaysDTO> daysDTOList = new ArrayList<>();
                List<DaysDTO> daysDTOList2 = new ArrayList<>();
                int lastDay = 0;
                for (int i =0;i<medicationInfo.getMedicationDays();i++){
                    DaysDTO daysDTO = new DaysDTO();

                    int num = i*(medicationInfo.getNextDays()+1);
                    Date date = DateUtil.offsetDay(medicationInfo.getStartTime(),num);
                //    daysDTO.setName(DateUtil.format(date,"yyyy-MM-dd"));
                    int day = Integer.parseInt(DateUtil.format(medicationInfo.getStartTime(),"dd")) + i*(medicationInfo.getNextDays()+1);

                //    if (day<=daysMonth) {


                     //   daysDTO.setName(String.valueOf(day));
                        daysDTO.setName(DateUtil.format(date,"yyyy-MM-dd"));
                        daysDTO.setTimes(String.valueOf(medicationInfo.getMedicationFrequency()));
                        daysDTOList.add(daysDTO);
                   //     lastDay = day;
                   //     daysCalc++;
                   //     continue;

            //        }


                    /*else {
                        int startDay = lastDay+medicationInfo.getNextDays()+1 - daysMonth;


                        int daySecond = startDay + (i - daysCalc)*(medicationInfo.getNextDays()+1);

                        daysDTO.setName(String.valueOf(daySecond));
                        daysDTO.setTimes(String.valueOf(medicationInfo.getMedicationFrequency()));
                        daysDTOList2.add(daysDTO);

                    }*/

                }

                MedicationDaysDTO medicationDaysDTO = new MedicationDaysDTO();
                MedicationDaysDTO medicationDaysDTO2 = new MedicationDaysDTO();

                medicationDaysDTO.setName(String.valueOf(startMonth));
                medicationDaysDTO.setList(daysDTOList);
                medicationDaysDTOList.add(medicationDaysDTO);
                medicationDaysDTO2.setName(String.valueOf(endMonth));
                medicationDaysDTO2.setList(daysDTOList2);
                medicationDaysDTOList.add(medicationDaysDTO2);



            }

        }

        return daysDTOList;
    }

    @Override
    public Boolean isMedication(MedicationInfo medicationInfo,Date date) {
        boolean result = false;
        int times = medicationInfo.getMedicationDays();
        Date newBeginDay =  DateUtil.beginOfDay(date);
        for (int i=0;i<times;i++){
            Date date1 = DateUtil.offsetDay(medicationInfo.getStartTime(),i*(medicationInfo.getNextDays()+1));
            Date begin = DateUtil.beginOfDay(date1);
            if (newBeginDay.compareTo(begin) == 0){
                result = true;
                break;
            }

        }
        return result;
    }

    @Override
    public void createRemindMessage(MedicationInfo medicationInfo) {
        //今天在用药提醒内时
        if (medicationInfo.getStartTime().compareTo(DateUtil.beginOfDay(new Date())) <=0 && medicationInfo.getEndTime().compareTo(DateUtil.beginOfDay(new Date())) >=0){
            List<String> timeList = Arrays.asList(medicationInfo.getRemindTime().split(","));
            log.warn("第一步");
            for (String time : timeList){
                log.warn("第二步");
                Date timeDate = DateUtil.parseTimeToday(time);
                if (timeDate.compareTo(DateUtil.date()) >0){
                    Long millisecond  = DateUtil.betweenMs(DateUtil.date(),timeDate);

                    log.warn("当前时间:{},延时:{}ms",
                            DateUtil.date().toString("yyyy-MM-dd HH:mm"),
                            millisecond);

                    rabbitTemplate.convertAndSend("jpMedicationDelayExchange", "submit",
                            medicationInfo.getId(), (message)->{
                            message.getMessageProperties().setHeader("x-delay",millisecond);
                            return message;
                        });
                    }
                }
            }
    }

    @Override
    public List<DaysDTO> getAllMedicationDays(String popedomId) {

        List<MedicationInfo> medicationInfoList = findByBeRemindPopedomId(popedomId);
        List<DaysDTO> list = new ArrayList<>();
        if (medicationInfoList.size()>0){
            for (int i = 0;i<7;i++){
                boolean result = false;
                for (MedicationInfo medicationInfo : medicationInfoList){
                    Boolean isMedication = isMedication(medicationInfo,DateUtil.offsetDay(new Date(),i));
                    if (isMedication){
                        result = true;
                        break;
                    }


                }
                if (result){
                    DaysDTO daysDTO = new DaysDTO();
                    daysDTO.setName(DateUtil.format(DateUtil.offsetDay(new Date(),i),"yyyy-MM-dd"));
                    daysDTO.setTimes("1");
                    list.add(daysDTO);
                }

            }

        }




        return list;
    }
}
