package com.bs.mes.cal;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.ximai.mes.cal.domain.CalPlan;
import com.ximai.mes.cal.domain.CalPlanWorkunit;
import com.ximai.mes.cal.domain.CalShift;
import com.ximai.mes.cal.domain.CalWorkunit;
import com.ximai.mes.cal.service.impl.CalPlanServiceImpl;
import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

public class CalPlanServiceImplTest
{
    @Test public void genRecords(){
        CalPlanServiceImpl calPlanService = new CalPlanServiceImpl();
        CalPlan calPlan = this.getCalPlan1();
        List<CalWorkunit> calWorkunitList = new ArrayList<>();
        List<CalPlanWorkunit> list = calPlanService.genRecords(calPlan, calWorkunitList);
        Assert.assertEquals(0, list.size());
        list = calPlanService.genRecords(calPlan, this.getCalWorkunitList(5));
        //每天分为2个班+1个休息班次，10天中4天为周天
        Assert.assertEquals(5*3*(10-4), list.size());
        System.out.println(CollectionUtil.join(list,"\r\n"));
        Assert.assertEquals("24-11-08 12:00",
                DateUtil.format(list.get(list.size()-2).getStartDate(), "yy-MM-dd HH:mm"));
        Assert.assertEquals("24-11-08 13:30",
                DateUtil.format(list.get(list.size()-2).getEndDate(), "yy-MM-dd HH:mm"));

        Assert.assertEquals("24-11-08 13:30",
                DateUtil.format(list.get(list.size()-1).getStartDate(),"yy-MM-dd HH:mm"));
        Assert.assertEquals("24-11-08 18:00",
                DateUtil.format(list.get(list.size()-1).getEndDate(),"yy-MM-dd HH:mm"));
        long weekend1 = DateUtil.parse("2024-11-02","yyyy-MM-dd").getTime();
        long weekend2 = DateUtil.parse("2024-11-03","yyyy-MM-dd").getTime();
        long weekend3 = DateUtil.parse("2024-11-04","yyyy-MM-dd").getTime();
        //不存在周未数据
        for (CalPlanWorkunit calPlanWorkunit : list) {
            //计划开始、结束时间不会同时在周六-周日0点之间
            Assert.assertFalse(
                    calPlanWorkunit.getStartDate().getTime()>=weekend1&&calPlanWorkunit.getStartDate().getTime()<weekend2
            &&
                            calPlanWorkunit.getEndDate().getTime()>=weekend2&&calPlanWorkunit.getEndDate().getTime()<weekend3);
            //计划开始、结束时间不会同时在周日-周一0点之间
            Assert.assertFalse(calPlanWorkunit.getStartDate().getTime()>=weekend2&&calPlanWorkunit.getStartDate().getTime()<weekend3
            &&
                    calPlanWorkunit.getEndDate().getTime()>=weekend2&&calPlanWorkunit.getEndDate().getTime()<weekend3);
        }
        // 测试2， 2班次，白/夜班次
        calPlan = getCalPlan2();
        long weekend4 = DateUtil.parse("2024-11-02 08:00","yyyy-MM-dd HH:mm").getTime();
        long weekend5 = DateUtil.parse("2024-11-03 08:00","yyyy-MM-dd HH:mm").getTime();
        long weekend6 = DateUtil.parse("2024-11-04 08:00","yyyy-MM-dd HH:mm").getTime();
        list = calPlanService.genRecords(calPlan, this.getCalWorkunitList(5));
        //每天分为2*2个班+2个休息班次，10天中8天为工作日
        Assert.assertEquals(5*6*8, list.size());
        //不存在周日数据
        for (CalPlanWorkunit calPlanWorkunit : list) {
            //计划开始、结束时间不会同时在周日-周一0点之间
            Assert.assertFalse(calPlanWorkunit.getStartDate().getTime()>=weekend5&&calPlanWorkunit.getStartDate().getTime()<weekend6
                    &&
                    calPlanWorkunit.getEndDate().getTime()>=weekend5&&calPlanWorkunit.getEndDate().getTime()<weekend6);
        }
        //存在周六数据
        Assert.assertTrue(list.stream().anyMatch(s->{
            return s.getStartDate().getTime()>=weekend1&&s.getStartDate().getTime()<weekend2
                    &&
                    s.getEndDate().getTime()>=weekend2&&s.getEndDate().getTime()<weekend3;
        }));
        System.out.println(CollectionUtil.join(list,"\r\n"));

        Assert.assertEquals(0, list.get(list.size()-1).getRestFlag());
        Assert.assertEquals("24-11-10 01:00",
                DateUtil.format(list.get(list.size()-1).getStartDate(),"yy-MM-dd HH:mm"));
        Assert.assertEquals("24-11-10 08:00",
                DateUtil.format(list.get(list.size()-1).getEndDate(),"yy-MM-dd HH:mm"));

        Assert.assertEquals(1, list.get(list.size()-2).getRestFlag());
        Assert.assertEquals("24-11-10 00:00",
                DateUtil.format(list.get(list.size()-2).getStartDate(),"yy-MM-dd HH:mm"));
        Assert.assertEquals("24-11-10 01:00",
                DateUtil.format(list.get(list.size()-2).getEndDate(),"yy-MM-dd HH:mm"));

        // 测试3， 2班次，白/夜班次 无休息
        calPlan = getCalPlan3();
        list = calPlanService.genRecords(calPlan, this.getCalWorkunitList(5));
        //每天分为2个班，10天中8天为工作日
        Assert.assertEquals(5*2*8, list.size());

        Assert.assertEquals(0, list.get(list.size()-1).getRestFlag());
        Assert.assertEquals("24-11-09 20:00",
                DateUtil.format(list.get(list.size()-1).getStartDate(),"yy-MM-dd HH:mm"));
        Assert.assertEquals("24-11-10 08:00",
                DateUtil.format(list.get(list.size()-1).getEndDate(),"yy-MM-dd HH:mm"));

    }

    /*
    单班计划，10天
    白班，8:00-18:00，中午休息12:00-13:30
     */
    private CalPlan getCalPlan1(){
        CalPlan calPlan = new CalPlan();
        calPlan.setSaturday(2);
        calPlan.setSunday(2);
        calPlan.setStartDate(DateUtil.parse("2024-11-01", "yyyy-MM-dd"));
        calPlan.setEndDate(DateUtil.parse("2024-11-10", "yyyy-MM-dd"));
        List<CalShift> calShifts = new ArrayList<>();
        CalShift dayShift = new CalShift();
        dayShift.setShiftName("白班");
        dayShift.setStartTime("8:00");
        dayShift.setEndTime("18:00");
        calShifts.add(dayShift);
        List<CalShift> calShiftBreakTimeList = new ArrayList<>();
        CalShift breakTime = new CalShift();
        breakTime.setBreakStartTime("12:00");
        breakTime.setBreakEndTime("13:30");
        calShiftBreakTimeList.add(breakTime);
        dayShift.setBreakTimeList(calShiftBreakTimeList);
        calPlan.setCalShifts(calShifts);
        return calPlan;
    }

    /**
    二班计划，10天，考虑周六加班
    白班，8:00-20:00，中午休息12:00-14:00
    夜班，20:00-8:00(隔天)，夜间休息00:00-1:00
     */
    private CalPlan getCalPlan2(){
        CalPlan calPlan = new CalPlan();
        calPlan.setSaturday(1);
        calPlan.setSunday(2);
        calPlan.setStartDate(DateUtil.parse("2024-11-01", "yyyy-MM-dd"));
        calPlan.setEndDate(DateUtil.parse("2024-11-10", "yyyy-MM-dd"));
        List<CalShift> calShifts = new ArrayList<>();
        //白班
        CalShift dayShift = new CalShift();
        dayShift.setShiftName("白班");
        dayShift.setStartTime("8:00");
        dayShift.setEndTime("20:00");
        calShifts.add(dayShift);
        List<CalShift> calShiftBreakTimeList = new ArrayList<>();
        CalShift breakTime = new CalShift();
        breakTime.setBreakStartTime("12:00");
        breakTime.setBreakEndTime("14:00");
        calShiftBreakTimeList.add(breakTime);
        dayShift.setBreakTimeList(calShiftBreakTimeList);
        //夜班
        CalShift nightShift = new CalShift();
        nightShift.setShiftName("夜班");
        nightShift.setStartTime("20:00");
        nightShift.setEndTime("8:00");
        calShifts.add(nightShift);
        List<CalShift> calShiftBreakTimeList2 = new ArrayList<>();
        CalShift breakTime2 = new CalShift();
        breakTime2.setBreakStartTime("0:00");
        breakTime2.setBreakEndTime("1:00");
        calShiftBreakTimeList2.add(breakTime2);
        nightShift.setBreakTimeList(calShiftBreakTimeList2);
        calPlan.setCalShifts(calShifts);
        return calPlan;
    }

    /**
     无休息
     二班计划，10天，考虑周六、周日加班
     白班，8:00-20:00
     夜班，20:00-8:00(隔天)
     */
    private CalPlan getCalPlan3(){
        CalPlan calPlan = new CalPlan();
        calPlan.setSaturday(1);
        calPlan.setSunday(2);
        calPlan.setStartDate(DateUtil.parse("2024-11-01", "yyyy-MM-dd"));
        calPlan.setEndDate(DateUtil.parse("2024-11-10", "yyyy-MM-dd"));
        List<CalShift> calShifts = new ArrayList<>();
        //白班
        CalShift dayShift = new CalShift();
        dayShift.setShiftName("白班");
        dayShift.setStartTime("8:00");
        dayShift.setEndTime("20:00");
        calShifts.add(dayShift);
        //夜班
        CalShift nightShift = new CalShift();
        nightShift.setShiftName("夜班");
        nightShift.setStartTime("20:00");
        nightShift.setEndTime("8:00");
        calShifts.add(nightShift);
        calPlan.setCalShifts(calShifts);
        return calPlan;
    }



    private List<CalWorkunit> getCalWorkunitList(int ct){
        List<CalWorkunit> rst = new ArrayList<>();
        for(int i=0;i<ct;i++){
            CalWorkunit temp = new CalWorkunit();
            temp.setWorkunitId(i+0l);
            temp.setWorkunitCode(i+"code");
            rst.add(temp);
        }
        return rst;
    }

}
