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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaomai.client.DataUserInfo;
import com.xiaomai.enums.ApiModule;
import com.xiaomai.enums.RequestType;
import com.xiaomai.enums.Terminal;
import com.xiaomai.utils.CommUtil;
import com.xiaomai.utils.XMBaseTest;
import com.xiaomai.utils.XMJSONPath;
import org.springframework.stereotype.Component;
import org.testng.Assert;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 训练营排课相关工具类
 * @author adu
 * data 2024/7/9 10:19
 */
@Component("campScheduleTools")
public class CampScheduleTools extends XMBaseTest {

    public void setUP(String apiName, DataUserInfo... userInfo) {
        dataApi.setApiModule(ApiModule.Polar_Schedule)
                .setApiName(apiName)
                .setTerminal(Terminal.B);
        super.beforeDataRequest(userInfo);
    }

    /**
     * 创建训练营排课
     * @param campId 训练营活动ID
     * @param assistCoachIds 助教ID
     * @param chiefCoachId 教练ID
     * @param courseId 课程ID 这个值直接从选择的训练营活动中获取
     * @param minMemberNum 开课人数 这个值直接从选择的训练营活动中获取
     * @param maxMemberNum 人数上线 这个值直接从选择的训练营活动中获取
     * @param minuteOffset 上课开始时间 整点*60 获取这个值 24小时制
     * @param startDate 开课开始时间，这个值要大于等于训练营的开营时间
     * @param endDate 开课结束时间，这个值要小于等于训练营的结束时间
     * @param force 排课是否冲突，有冲突时true，无冲突时传false
     * @param venueAreaIds 场地ID
     * @param maxLoop  上课次数，按次数时要传这个值；如果设置按日期 则传""；
     * @param userInfo
     */
    public void createCampRuleSchedule(String campId, List<String> assistCoachIds,String chiefCoachId,String courseId,
                                       int minMemberNum,int maxMemberNum,String minuteOffset,String startDate,String endDate,
                                       Boolean force,List<String> venueAreaIds,String maxLoop,DataUserInfo... userInfo){
        setUP("API_createCampRuleSchedule", userInfo);
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        if(null!=maxLoop||!maxLoop.isEmpty()){
            body.put("maxLoop", maxLoop);
        }
        body.put("campId", campId);
        body.put("courseId", courseId);
        body.put("chiefCoachId", chiefCoachId);
        body.put("minMemberNum", minMemberNum); // 开课人数
        body.put("maxMemberNum", maxMemberNum); //人数上限
        body.put("minuteOffset", minuteOffset); //上课开始时间
        body.put("startDate", startDate); //排课开始日期
        body.put("endDate", endDate); //排课结束日期
        String[] weekDaysArray = {"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"};
        List<String> weekdaysList = Arrays.asList(weekDaysArray);
        body.put("weekdays", weekdaysList); //设置上课星期，目前是每天都会选择
        body.put("venueAreaIds", venueAreaIds); //场地，可设置为空 new ArrayList<>();
        body.put("assistCoachIds", assistCoachIds); //设置助教，可设置为空 new ArrayList<>();
        body.put("force", force); //是否有冲突 true，false
        body.put("enableCustomerReserve", "NO"); //能否用户自己约课，不能
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));

    }

    /**
     * 快速创建排课，周二，周四，周六，周日
     * @param campId
     * @param chiefCoachId
     * @param courseId
     * @param minMemberNum
     * @param maxMemberNum
     * @param minuteOffset
     * @param endDate
     * @param force
     * @param maxLoop
     */
    public void oneKeyCreateCampRuleSchedule(String campId,String chiefCoachId,String courseId,
                                             int minMemberNum,int maxMemberNum,String minuteOffset,String endDate,
                                             Boolean force,String maxLoop){
        setUP("API_createCampRuleSchedule");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        if(null!=maxLoop||!maxLoop.isEmpty()){
            body.put("maxLoop", maxLoop);
        }
        body.put("campId", campId);
        body.put("courseId", courseId);
        body.put("chiefCoachId", chiefCoachId);
        body.put("minMemberNum", minMemberNum); // 开课人数
        body.put("maxMemberNum", maxMemberNum); //人数上限
        body.put("minuteOffset", minuteOffset); //上课开始时间
        body.put("startDate", CommUtil.oneKeyGetAddDay(3));//大后天，晚于开营时间1天
        body.put("endDate", endDate); //排课结束日期,取训练营结束日期
        String[] weekDaysArray = { "TUESDAY", "THURSDAY", "SATURDAY", "SUNDAY"};
        List<String> weekdaysList = Arrays.asList(weekDaysArray);
        body.put("weekdays", weekdaysList); //设置上课星期，目前是每天都会选择
        body.put("venueAreaIds", new ArrayList<>()); //场地，可设置为空 new ArrayList<>();
        body.put("assistCoachIds", new ArrayList<>()); //设置助教，可设置为空 new ArrayList<>();
        body.put("force", force); //是否有冲突 true，false
        body.put("enableCustomerReserve", "NO"); //能否用户自己约课，不能
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));


    }

    /**
     * 查看训练营排课日程
     * @param campId 根据训练营活动查询 ，传值时有筛选条件，""时不传该值，看了前端传值一般没筛选条件时不传，只要有一个筛选条件，其他筛选条件要传null
     * @param courseId 根据课程查询
     * @param coachId 根据教练查询
     * @param userInfo
     */
    public void getCampRuleScheduleList(String campId,String courseId,String coachId,DataUserInfo... userInfo){
        setUP("API_getCampRuleScheduleList", userInfo);
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("coachId", coachId);
        body.put("courseId", courseId);
        body.put("campId", campId);
       /* if(null!= campId && !campId.isEmpty()){
            body.put("campId", campId);
        }
        if(null!=courseId||!courseId.isEmpty()){
            body.put("courseId", courseId);

        }
        if(null!=coachId||!coachId.isEmpty()){
            body.put("coachId", coachId);
        }*/

        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));


    }

    /**
     * 删除训练营排课日程
     * @param ruleId 日程对应的规则ID
     */
    public void delCampRuleSchedule(String ruleId){
        setUP("API_delCampRuleSchedule");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("force", true);//删除学员约课记录
        body.put("ruleId", ruleId);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));


    }

    /**
     * 查看训练营排课课表
     * @param startDate 开始日期，如果查看的是日课表，传当前的开始日期00；如果是周课表，传的是指定周的周一开始日期
     * @param endDate 结束日期 ，如果查看的是日课表，传当前的结束日期23：59：59；如果是周课表，传的是指定周的周日结束日期
     * @return
     */
    public JSONArray getCampScheduleTable(String startDate, String endDate) {
        setUP("API_getCampScheduleTable");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("startDate", startDate);
        body.put("endDate", endDate);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));

        if (Integer.valueOf(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.totalCount")) > 0) {
            return dataApi.getBodyInJSON().getJSONObject("result").getJSONArray("timetableGroups").getJSONObject(0).getJSONArray("timetableList");
        }
        else {
            return null;
        }
    }

    /**
     * @description: 查询训练营排课课表
     * @author: xuyamei
     * @date:  2024/7/31 10:48
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param campId ：训练营活动id
     * @return: com.alibaba.fastjson.JSONArray
     **/
    public JSONArray getCampScheduleTable(Long startDate, Long endDate,String campId) {
        setUP("API_getCampScheduleTable");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("startDate", startDate);
        body.put("endDate", endDate);
        body.put("campId", campId);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs).assetsSuccess(true);
        if (Integer.valueOf(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.totalCount")) > 0) {
            return dataApi.getBodyInJSON().getJSONObject("result").getJSONArray("timetableGroups").getJSONObject(0).getJSONArray("timetableList");
        }
        else {
            return null;
        }
    }

    /**
     * 根据时间和星期查询有效循环次数
     * @param startDate
     * @param endDate
     * @param weekdaysList
     * @return
     */
    public int queryExpectedLoopNum(String startDate, String endDate,List<String> weekdaysList){
        setUP("API_queryExpectedLoopNum");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("startDate", startDate);
        body.put("endDate", endDate);
        body.put("weekdays", weekdaysList);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));

        return Integer.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.result"));
    }

    /**
     * 查看训练营排课日程详情
     * @param ruldId
     */
    public void getCampRuleScheduleDetail(String ruldId){
        setUP("API_getCampRuleScheduleDetail");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("id", ruldId);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));


    }

    /**
     * 查看训练营排课课次详情
     * @param scheduleId
     */
    public void getCampScheduleItemDetail(String scheduleId){
        setUP("API_getCampScheduleItemDetail");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("id", scheduleId);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));

    }

    /**
     * 删除训练营课次
     * @param scheduleId 课次ID
     * @param applyRestRule 是否删除后续课次 false（只删除当前课次） ；true（当前及后续）
     */
    public void delCampScheduleItem(String scheduleId,Boolean applyRestRule){
        setUP("API_delCampScheduleItem");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("scheduleId", scheduleId);
        body.put("applyRestRule", applyRestRule);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(),"$.success"))==true,"调用接口返回结果："+XMJSONPath.readPath(dataApi.getApi_response(),"$.message"));

    }

    /**
     * 获取指定下周某一天的训练营课次ID
     * @param n
     * @return 判断某天没排课 scheduleIds5.size() == 0 || scheduleIds5 == null
     */
    public Set<String> getCampTableDate(int n) {
        //查看下周训练营课表
        getCampScheduleTable(CommUtil.oneKeyGetNextWeekStartDay(), CommUtil.oneKeyGetNextWeekEndDay());
        String date = CommUtil.oneKeyGetNextWeekXDay(n);//下周N 日期时间戳
        int count = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups").size();
        if (count > 0) {
            JSONArray array = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups");
            Set<String> scheduleIds = array.toJavaList(JSONObject.class).stream()
                    .filter(e -> e.getString("date").equals(date))//过滤出日期等于下周N的数据
                    .flatMap(e -> e.getJSONArray("timetableList").toJavaList(JSONObject.class).stream())//对过滤出的数据再次取目标数据重新组合成一个新的数据流
                    .map(e -> e.getString("scheduleId"))//获取scheduleId
                    .collect(Collectors.toSet());
            return scheduleIds; //如果当天没排课，则scheduleIds.size()==0
        }
        return null;

    }

    /**
     * 选择匹配到对应规则ID的课次
     * @param n
     * @param ruldId
     * @return
     */
/*    public Set<String> getCampTableDate(int n,String ruldId) {
        //查看下周训练营课表
        getCampScheduleTable(CommUtil.oneKeyGetNextWeekStartDay(), CommUtil.oneKeyGetNextWeekEndDay());
        String date = CommUtil.oneKeyGetNextWeekXDay(n);//下周N 日期时间戳
        int count = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups").size();
        if (count > 0) {
            JSONArray array = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups");
            Set<String> scheduleIds = array.toJavaList(JSONObject.class).stream()
                    .filter(e -> e.getString("date").equals(date))//过滤出日期等于下周N的数据
                    .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());
            return scheduleIds; //如果当天没排课，则scheduleIds.size()==0
        }
        return null;

    }*/

    public String getCampTableDate(int n,String ruldId) {
        //查看下周训练营课表
        getCampScheduleTable(CommUtil.oneKeyGetNextWeekStartDay(), CommUtil.oneKeyGetNextWeekEndDay());
        String date = CommUtil.oneKeyGetNextWeekXDay(n);//下周N 日期时间戳
        int count = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups").size();
        if (count > 0) {
            JSONArray array = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.timetableGroups");
           String scheduleId = array.toJavaList(JSONObject.class).stream()
                    .filter(e -> e.getString("date").equals(date))//过滤出日期等于下周N的数据
                    .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
                    .findFirst().orElse("");
            return scheduleId; //如果当天没排课，
        }
        return "";

    }




}

    