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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaomai.cases.polar.setting.venue.VenueAreaTools;
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.springframework.util.CollectionUtils;
import org.testng.Assert;

import javax.annotation.Resource;
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/6/12 11:51
 */
@Component("groupScheduleTools")
public class GroupScheduleTools extends XMBaseTest {

    @Resource(name = "venueAreaTools")
    VenueAreaTools venueAreaTools;


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

    /**
     * 创建团课排课
     *
     * @param courseId       团课课程ID
     * @param chiefCoachId   教练ID
     * @param startDate      排课开始日期
     * @param endDate        排课结束日期
     * @param venueAreaIds   场馆ID
     * @param assistCoachIds 助教ID
     * @param force          是否冲突 false有2种场景：1无冲突时直接传false排课创建成功，2是有冲突时传false代表不忽略冲突，不会创建排课；true是指有冲突时忽略冲突，选择仍要排课【没冲突时就传false，有冲突就传true，如果排课时有冲突但是传了false不会创建排课哈】
     * @param endType        排课结束方式：1 按日期，2 按次数
     */
    public void createGroupRuleSchedule(String courseId, String chiefCoachId, String startDate, String endDate, List<String> venueAreaIds, List<String> assistCoachIds, Boolean force, int endType, int minuteOffset, DataUserInfo... userInfo) {
        setUP("API_createGroupRuleSchedule", 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("courseId", courseId);
        body.put("chiefCoachId", chiefCoachId);
        body.put("minMemberNum", 2); // 开课人数
        body.put("maxMemberNum", 999); //人数上限
        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
        if (endType == 2) {
            body.put("maxLoop", 60); //如果排课方式选择按次数，设置次数为60
            body.put("endDate", CommUtil.getNDayEndTimeTamp(60)); //排课结束日期，这里就设置自动延顺60天，结束日期会覆盖你传的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"));


    }

    /**
     * 查看排课日程
     *
     * @param courseId 可根据课程查询
     * @param coachId  可根据教练查询
     * @return
     */

    public JSONArray getGroupRuleScheduleList(String courseId, String coachId, DataUserInfo... userInfo) {
        setUP("API_getGroupRuleScheduleList", userInfo);
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        if (courseId != null && courseId.length() != 0) {
            body.put("courseId", courseId);
        }
        if (coachId != null && coachId.length() != 0) {
            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"));
        return XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result");

    }

    /**
     * 查询存量团课课程
     *
     * @param courseName
     * @return
     */
    public String getStockGroupCourseId(String courseName) {
        dataApi.setApiModule(ApiModule.Polar_Course)
                .setApiName("API_getGroupClassPage")
                .setTerminal(Terminal.B);
        super.beforeDataRequest();
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("courseState", "ON");
        body.put("current", 0);
        body.put("size", 50);
        body.put("courseNameLike", courseName);
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs).assetsSuccess(true);
        if (XMJSONPath.readPath(dataApi.getApi_response(), "$.result.records").length() == 0) {
            return "";
        } else {
            return XMJSONPath.readPath(dataApi.getApi_response(), "$.result.records[0].brandCourseId");
        }

    }

    /**
     * 删除团课排课日程
     *
     * @param ruleId
     */
    public void delGroupRuleSchedule(String ruleId, Boolean force, DataUserInfo... userInfo) {
        setUP("API_delGroupRuleSchedule", 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("force", force);
        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"));


    }

    /**
     * 获取教练ID
     *
     * @param nickNameList 可根据传入的昵称，获取对应的ID
     * @return
     */
    public List<String> getStudioAdminId(List<String> nickNameList) {
        dataApi.setApiModule(ApiModule.Polar_Admin)
                .setApiName("API_pageStudioAdmin")
                .setTerminal(Terminal.B);
        super.beforeDataRequest();
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        body.put("current", 0);
        body.put("size", 50);
        body.put("state", "DUTY");
        body.put("teachingType", "LEAGUE_CLASS");
        dataApi.doRequest(RequestType.JSON, dataparams, body.toString(), dataheadrs).assetsSuccess(true);

        int count = Integer.valueOf(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.total"));
        List<String> adminIds = new ArrayList<>();
        if (count > 0) {
            JSONArray records = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records");
            adminIds = records.stream()
                    .filter(obj -> CollectionUtils.isEmpty(nickNameList) || nickNameList.contains(((JSONObject) obj).getString("nickName"))) //如果nickNameList为空或者包含搜索结果集中对应的昵称，就会过滤
                    .map(obj -> {
                                JSONObject adminIdInfo = (JSONObject) obj;
                                return adminIdInfo.getString("id");
                            }
                    ).collect(Collectors.toList());
            return adminIds;
        }
        return null;

    }

    /**
     * 获取存量场地
     *
     * @param areaName 根据指定场地名称，匹配出对应的场地ID，如果无匹配的则新建，如果场地列表无数据，则新建个
     * @return
     */
    public List<String> getStockArea(String areaName) {
        JSONObject result = venueAreaTools.getVenueAreaPage();
        int count = XMJSONPath.getJSONArrayByReadPath(result, "$.records").size();
        List<String> areaIds = new ArrayList<>();
        if (count > 0) {
            areaIds = result.getJSONArray("records").toJavaList(JSONObject.class).stream().filter(obj -> (areaName).equals(obj.getString("groupName")))
                    .map(obj -> {
                                JSONObject areaIdInfo = (JSONObject) obj;
                                return areaIdInfo.getJSONArray("areaList").getJSONObject(0).getString("id");
                            }
                    ).collect(Collectors.toList());
            if (areaIds.isEmpty()) {//如果无匹配的则新建一个匹配的场地
                String areaId = venueAreaTools.createVenueArea(areaName);
                areaIds.add(areaId);
                return areaIds;
            }
            return areaIds;//如果匹配到了，取匹配到的场地ID
        } else {//如果场地列表为空，则新建一个
            String areaId = venueAreaTools.createVenueArea(areaName);
            areaIds.add(areaId);
            return areaIds;
        }
    }

    /**
     * 查看团课排课日程详情
     *
     * @param ruldId
     */
    public void getGroupRuleScheduleDetail(String ruldId) {
        setUP("API_getGroupRuleScheduleDetail");
        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
     * @description:获取课次详情
     * @author: xuyamei
     * @date: 2024/6/23 17:45
     * @return: com.alibaba.fastjson.JSONObject
     **/
    public JSONObject getScheduleItemDetail(String scheduleId, DataUserInfo... dataUserInfo) {
        setUP("API_getScheduleItemDetail", dataUserInfo);

        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"));

        return dataApi.getBodyInJSON().getJSONObject("result");
    }

    /**
     * @param startDate
     * @param endDate
     * @description:查询课表
     * @author: xuyamei
     * @date: 2024/6/23 17:46
     * @return: com.alibaba.fastjson.JSONArray
     **/
    public JSONArray getGroupScheduleTable(Long startDate, Long endDate, String courseId) {
        setUP("API_getGroupScheduleTable");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        if (courseId.equals("")) {
            body.put("courseId", courseId);
        }
        body.put("startDate", startDate);
        body.put("endDate", endDate);
        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 scheduleId:课次id
     * @param startTime：开始时间
     * @param chiefCoachId：教练
     * @param minMemberNum：开课人数
     * @param maxMemberNum：最大人数上限
     * @param dataUserInfos
     * @description:编辑课次
     * @author: xuyamei
     * @date: 2024/6/23 20:45
     * @return: void
     **/
    public void editGroupSchedule(String scheduleId, Long startTime, String chiefCoachId, int minMemberNum, int maxMemberNum, DataUserInfo... dataUserInfos) {
        setUP("API_editGroupSchedule", dataUserInfos);

        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("startTime", startTime);
        body.put("chiefCoachId", chiefCoachId);
        body.put("applyRestRule", false);
        body.put("minMemberNum", minMemberNum);
        body.put("maxMemberNum", maxMemberNum);
        body.put("venueAreaIds", new ArrayList());
        body.put("assistCoachIds", new ArrayList());
        body.put("spanMinutes", 60);
        body.put("force", false);
        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 dataUserInfos
     * @description:删除单个排课
     * @author: xuyamei
     * @date: 2024/6/23 21:12
     * @return: void
     **/
    public void delGroupScheduleItem(String scheduleId, DataUserInfo... dataUserInfos) {
        setUP("API_delGroupScheduleItem", dataUserInfos);

        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", false);

        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> getTableDate(int n) {
        //查看团课课表
        getGroupScheduleTable(Long.valueOf(CommUtil.oneKeyGetNextWeekStartDay()), Long.valueOf(CommUtil.oneKeyGetNextWeekEndDay()), "");
        //获取下周周N及后续的课次
        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 String getTableDate(int n, String ruldId) {
        //查看团课课表
        getGroupScheduleTable(Long.valueOf(CommUtil.oneKeyGetNextWeekStartDay()), Long.valueOf(CommUtil.oneKeyGetNextWeekEndDay()), "");
        //获取下周周N及后续的课次
        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 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
                    .findFirst().orElse("");
            return scheduleIds;

        }
        return "";


    }

    /**
     * 团课分享课表时获取课表配置
     */
    public void getShareScheduleConfig() {
        setUP("API_getShareScheduleConfig");
        JSONObject body = new JSONObject();
        body.put("operatorId", dataApi.getLoginInfo().getAdminId());
        body.put("studioId", dataApi.getLoginInfo().getStudioId());
        body.put("brandId", dataApi.getLoginInfo().getBrandId());
        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 data
     */
    public void saveShareScheduleConfig(JSONObject data) {
        setUP("API_saveShareScheduleConfig");
        data.put("operatorId", dataApi.getLoginInfo().getAdminId());
        data.put("studioId", dataApi.getLoginInfo().getStudioId());
        data.put("brandId", dataApi.getLoginInfo().getBrandId());
        dataApi.doRequest(RequestType.JSON, dataparams, data.toString(), dataheadrs);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(), "$.success")) == true, "调用接口返回结果：" + XMJSONPath.readPath(dataApi.getApi_response(), "$.message"));

    }


}


