package com.xiaomai.cases.polar.schedule.camp;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaomai.cases.polar.schedule.group.GroupScheduleTools;
import com.xiaomai.enums.ApiModule;
import com.xiaomai.enums.LoginAccount;
import com.xiaomai.enums.RequestType;
import com.xiaomai.enums.Terminal;
import com.xiaomai.utils.CommUtil;
import com.xiaomai.utils.XMJSONPath;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

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

/**
 * 编辑训练营课次（单个/后续课次）
 *
 * @author adu
 * data 2024/7/12 17:08
 */

public class TestEditCurrentAndSubsequentCampSchedule extends SelectTargetTrainingCampAndGetInfo {

    public static Date now = new Date();
    //String scheduleIdsN;
    @Resource(name = "groupScheduleTools")
    GroupScheduleTools groupScheduleTools;
    @Resource(name = "campScheduleTools")
    CampScheduleTools campScheduleTools;
    String campId = "";
    String chiefCoachId = "";
    String ruldId = "";
    String newRuldId = "";
    //获取下周日某个时间点的开始时间戳
    String startStamp = CommUtil.getWholeHourTimeStamp(13, "13:30");

    public String sDateBefore;
    public String eDateBefore = "";
    public int scheduleClassHourEditBefore = 0;

    public int scheduleClassHourEditAfter = 0;
   // public List<String> venueAreaIdsEditAfter;
    public Boolean flag;

    @BeforeClass
    @Override
    public void beforeTest() {
        setTestInfo(ApiModule.Polar_Schedule, "API_editCampSchedule", LoginAccount.ADU_PROD, Terminal.B, "adu");
        super.beforeTest();
        // 获取选择的训练营ID
        campId = super.campId;
        //1.2获取训练营活动的指定教练ID
        chiefCoachId = super.chiefCoachId;
        //获取目标时间段内 最大有效课时数
        String[] weekDaysArray = {"TUESDAY", "THURSDAY", "SATURDAY", "SUNDAY"};
        List<String> weekdaysList = Arrays.asList(weekDaysArray);
        int loopNum = campScheduleTools.queryExpectedLoopNum(CommUtil.oneKeyGetAddDay(3), super.openEndDate, weekdaysList);

        //创建训练营排课：按次数 星期：2，4，6，7
        campScheduleTools.oneKeyCreateCampRuleSchedule(campId, chiefCoachId, super.courseId,
                super.traineeLowerLimit, super.traineeUpperLimit,
                "1140", super.openEndDate, true,
                String.valueOf(loopNum));
        //查询排课日程:根据训练营和关联课程查询
        campScheduleTools.getCampRuleScheduleList(super.campId, super.courseId, "");
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").size() == 1, "排课创建成功后，日程中没查询到对应数据");
        ruldId = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").getJSONObject(0).getString("ruleId");
        //获取训练营活动已排课课次数
        scheduleClassHourEditBefore = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").getJSONObject(0).getJSONObject("campVO").getIntValue("scheduleClassHour");

    }


    @Test(description = "编辑当前及后续课次")
    public void testEditCurrentAndSubsequentCampSchedule() throws InterruptedException {
        //获取存量场地
        List<String> venueAreaIds = groupScheduleTools.getStockArea("流星花园秘密基地");
        //获取下下周二的课次ID
        //获取下下周二的开始时间和结束时间
        String targetStartDate = CommUtil.getXStartOfDateNextXWeek(1, 2);
        String targetendDate = CommUtil.getXEndOfDateNextXWeek(-5, 2);
        Set<String> scheduleId22;
        campScheduleTools.getCampScheduleTable(targetStartDate, targetendDate);
        int count = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups").size();
        if (count > 0) {
            JSONArray array = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups");
            scheduleId22 = array.toJavaList(JSONObject.class).stream()
                    .flatMap(e -> e.getJSONArray("timetableList").toJavaList(JSONObject.class).stream())//对过滤出的数据再次取目标数据重新组合成一个新的数据流
                    .filter(e -> null != e.getString("ruleId"))
                    .filter(e -> e.getString("ruleId").equals(ruldId))
                    .map(e -> e.getString("scheduleId"))//获取scheduleId
                    .collect(Collectors.toSet());
            if (scheduleId22.size() != 0 && scheduleId22 != null) {
                scheduleId22.stream().forEach(scheduleId -> {
                    //删除本次创建的下下周二的课次
                    campScheduleTools.delCampScheduleItem(scheduleId, false);
                });
            }
        }

        //获取下周六的课次ID
        String scheduleIds6 = campScheduleTools.getCampTableDate(12, ruldId);
        if (!StringUtils.isEmpty(scheduleIds6)) {
            //编辑下周六及后续课次
            JSONObject body = new JSONObject();
            body.put("operatorId", xmAppApi.getLoginInfo().getAdminId());
            body.put("studioId", xmAppApi.getLoginInfo().getStudioId());
            body.put("brandId", xmAppApi.getLoginInfo().getBrandId());
            body.put("applyRestRule", true);
            body.put("scheduleId", scheduleIds6);
            //获取下周六某个时间点的开始时间戳
            String startStamp = CommUtil.getWholeHourTimeStamp(12, "19:00");
            body.put("startTime", startStamp);//上课时间不做修改
            body.put("chiefCoachId", chiefCoachId);
            body.put("minMemberNum", super.traineeLowerLimit);
            body.put("maxMemberNum", super.traineeUpperLimit);
            body.put("venueAreaIds", venueAreaIds);//场地有空改为有数据
            body.put("assistCoachIds", new ArrayList<>());
            body.put("spanMinutes", 50);
            body.put("force", true);//有冲突时忽略冲突
            body.put("retainBooking", true);//保留学员预约
            xmAppApi.doRequest(RequestType.JSON, params, body.toString(), headers);
            Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(xmAppApi.getApi_response(), "$.success")) == true, "调用接口返回结果：" + XMJSONPath.readPath(xmAppApi.getApi_response(), "$.message"));

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            //check当前课次信息是否被同步修改
            campScheduleTools.getCampScheduleItemDetail(scheduleIds6);
            Assert.assertEquals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.startTime"), startStamp);
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.venueAreaIds").containsAll(venueAreaIds), "场地有空改为有数据，但是课次详情中显示不正确哦");

        }
        //后续检查点check
        Thread.sleep(3000);
        //1.查询排课日程:根据训练营查询，应该对应训练营可以查到2条数据，原日程和修改后生成的日程
        campScheduleTools.getCampRuleScheduleList(super.campId, super.courseId, "");
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").size() == 2, "编辑当前及后续课次成功后，日程中没查询到2条对应数据");
        //1.1获取到新生成的排课日程ID
        //过滤出刚创建的日程
        JSONArray array = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result");
        newRuldId = array.toJavaList(JSONObject.class).stream()
                .filter(e -> !e.getString("ruleId").equals(ruldId))//过滤出新规则
                .map(e -> e.getString("ruleId"))//获取新规则ID
                .findFirst().orElse(null);
        //1.2查看新规则，check修改的字段是否生效
        array.toJavaList(JSONObject.class).stream().forEach(obj -> {
            if (newRuldId.equals(obj.getString("ruleId"))) {
                sDateBefore = obj.getString("startDate");
                eDateBefore = obj.getString("endDate");
                scheduleClassHourEditAfter = Integer.parseInt(obj.getJSONObject("campVO").getString("scheduleClassHour"));
                flag = obj.getJSONArray("venueAreaIds").containsAll(venueAreaIds);
            }
        });
        Assert.assertTrue(flag == true, "新规则的场地数据为空了");
        //编辑当前及后续课次后，已排课次数量变更check 【独立出去的课次 又生成新的一个课次本次没造该场景】
        Assert.assertTrue(scheduleClassHourEditBefore  == scheduleClassHourEditAfter, "编辑当前及后续课次后，训练营已排课次数不变（之前删除的课次，也生成新的课次了）");
        //新日程的开始日期check
        Assert.assertEquals(sDateBefore, CommUtil.getXStartOfDateNextXWeek(5, 1), "新规则的开始日期不对，应该是下周六的时间");
        //Assert.assertEquals(eDateBefore.substring(0, 9), super.openEndDate.substring(0, 9), "新规则的结束日期不对");

        //2.断言check：获取下周四的课次，check是否还是原来的数据（不会受到影响）
        String scheduleIds4 = campScheduleTools.getCampTableDate(10, ruldId);
        if (!StringUtils.isEmpty(scheduleIds4)) {
            campScheduleTools.getCampScheduleItemDetail(scheduleIds4);
            String detailResult = dataApi.getApi_response();
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(detailResult, "$.result.assistCoachIds").size() == 0, "课次创建时助教为空，查看课次详情不为空");
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(detailResult, "$.result.venueAreaIds").size() == 0, "课次创建时场地为空，查看课次详情不为空");

        }
       //因为编辑单个课次 移除了本类，所以独立出去的课次 再本case中不设计了
        /*// 3.check下周日的课次（以独立出去的课次是否受到影响:不受影响）
        if (!StringUtils.isEmpty(scheduleIdsN)) {
            campScheduleTools.getCampScheduleItemDetail(scheduleIdsN);
            String detailResult = dataApi.getApi_response();
            Assert.assertEquals(XMJSONPath.readPath(detailResult, "$.result.startTime"), startStamp);
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(detailResult, "$.result.assistCoachIds").size() == 2, "助教修改后添加2个教练没生效");
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(detailResult, "$.result.venueAreaIds").size() == 0, "课次创建时为空，查看课次详情不为空");

        }

        //4.check 下周日是否又生成一条新的课次
        String scheduleIds77 = campScheduleTools.getCampTableDate(13, newRuldId);
        Assert.assertTrue(!StringUtils.isEmpty(scheduleIds77), "下周日没有生成一条新的数据");
        campScheduleTools.getCampScheduleItemDetail(scheduleIds77);
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.venueAreaIds").containsAll(venueAreaIds), "场地有空改为有数据，但是课次详情中显示不正确哦");*/

        //5.check 下下周二是否生成一条新的课次
        campScheduleTools.getCampScheduleTable(targetStartDate, targetendDate);

        List<String> ruleIdIds22 = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups").toJavaList(JSONObject.class).stream()
                .filter(e -> e.getString("date").equals(targetStartDate))//过滤出日期等于下周日的数据
                .flatMap(e -> e.getJSONArray("timetableList").toJavaList(JSONObject.class).stream())//对过滤出的数据再次取目标数据重新组合成一个新的数据流
                .filter(e -> null != e.getString("ruleId"))
                .filter(e -> e.getString("ruleId").equals(newRuldId))
                .map(e -> e.getString("ruleId"))//获取ruleId
                .collect(Collectors.toList());

        Assert.assertTrue(ruleIdIds22.size() == 1, "课次被删除后，编辑当前及后续，后续删除的课次没重新生成新的课次");
        //删除数据
        this.getTrainingTools().deleteTraining(campId);
        //训练营被删除后，对应的排课日程会被自动删除check
        Thread.sleep(2000);
        campScheduleTools.getCampRuleScheduleList(campId, "", "");
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").toJavaList(JSONObject.class).stream().filter(e -> e.getString("ruleId").equals(ruldId)).count()==0, "训练营被删除后，对应的排课日程会被自动删除，目前还有相关数据ruldId请检查");
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").toJavaList(JSONObject.class).stream().filter(e -> e.getString("ruleId").equals(newRuldId)).count()==0, "训练营被删除后，对应的排课日程会被自动删除，目前还有相关数据newRuldId请检查");


    }





}




    