package com.xiaomai.cases.polar.membercluster;

import com.alibaba.fastjson.JSONObject;
import com.xiaomai.basetest.BaseTestImpl;
import com.xiaomai.cases.polar.coupon.CouponTools;
import com.xiaomai.cases.polar.experienceCard.Tools;
import com.xiaomai.cases.polar.memberCard.CardTools;
import com.xiaomai.enums.ApiModule;
import com.xiaomai.enums.LoginAccount;
import com.xiaomai.enums.RequestType;
import com.xiaomai.enums.Terminal;
import com.xiaomai.utils.RandomStringUtil;
import com.xiaomai.utils.XMJSONPath;
import org.apache.commons.lang3.StringUtils;
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.ArrayList;
import java.util.List;

/**
 * @author adu
 * data 2024/10/26 17:35
 */

public class TestCreateMemberCluster extends BaseTestImpl {
    @Resource(name = "memberClusterTools")
    MemberClusterTools memberClusterTools;

    @Resource(name = "couponTools")
    CouponTools couponTools;
    Tools tools = new Tools();
    @Resource(name = "cardTools")
    CardTools cardTools;
    String clusterIdNewA = "";
    String clusterIdNewB = "";
    String clusterIdA = "";
    String clusterIdB = "";

    @BeforeClass
    public void beforeTest() {
        setTestInfo(ApiModule.Polar_Membercluster, "API_createMemberCluster", LoginAccount.ADU_PROD, Terminal.B, "adu");
        super.beforeTest();
    }

    /**
     * 先造轮子
     * 1.标签"tags": ["1850100465387134978", "1834827617041047554"]创建2个存量便签，其中杜君丽便签A，B，吴彦祖便签B
     * 2.创建3个存量学员，杜君丽，吴彦祖，晨晨爸爸，杜君丽购买会员卡62次，晨晨爸爸购买会员卡61次，吴彦祖无购买记录，杜君丽储值卡余额999元
     */
    @Test(description = "创建客户分群")
    public void testCreateMemberCluster() throws InterruptedException {
        String name = "满足所有条件便签课程和储值卡" + RandomStringUtil.randomString(3);
        JSONObject body = new JSONObject();
        body.put("operatorId", xmAppApi.getLoginInfo().getAdminId());
        body.put("studioId", xmAppApi.getLoginInfo().getStudioId());
        body.put("brandId", xmAppApi.getLoginInfo().getBrandId());
        body.put("name", name);
        body.put("description", "自动化测试创建客户分群");

        body.put("requireFullHit", "YES");

        List<JSONObject> ruleList = new ArrayList<>();
        JSONObject ruleTypeTag = new JSONObject();
        List<String> tags = new ArrayList<>();
        tags.add("1850100465387134978");
        tags.add("1834827617041047554");
        ruleTypeTag.put("ruleType", "TAG");
        ruleTypeTag.put("tags", tags);
        ruleList.add(ruleTypeTag);

        JSONObject ruleTypeMember = new JSONObject();
        ruleTypeMember.put("ruleType", "MEMBER_CARD_COURSE_LEFT_BALANCE");
        ruleTypeMember.put("value", true);
        ruleTypeMember.put("lowerLimit", "60");
        ruleTypeMember.put("upperLimit", "62");
        ruleTypeMember.put("tags", null);
        ruleList.add(ruleTypeMember);


        JSONObject ruleTypeDeposit = new JSONObject();
        ruleTypeDeposit.put("ruleType", "DEPOSIT_CARD_LEFT_BALANCE");
        ruleTypeDeposit.put("value", true);
        ruleTypeDeposit.put("lowerLimit", "900");
        ruleTypeDeposit.put("upperLimit", "999");
        ruleTypeDeposit.put("tags", null);
        ruleList.add(ruleTypeDeposit);

        body.put("ruleList", ruleList);
        //1.创建人群
        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"));
        clusterIdNewA = XMJSONPath.readPath(xmAppApi.getApi_response(), "$.result");

        //2.查看详情，check人群信息
        memberClusterTools.getMemberClusterDetail(clusterIdNewA);
        //2.1 check创建的是不是满足所有条件
        Assert.assertEquals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.requireFullHit"), "YES");
        Assert.assertEquals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.displayRuleList"), "会员标签2个（满足其一即可）、会员卡课程剩余次数60~62次、储值卡剩余金额900~999元");

        //3.再创建一个分群，条件是满足以上任意一个，用工具类
        String nameB = "满足任意一个条件会员分群" + RandomStringUtil.randomString(3);
        memberClusterTools.createMemberCluster(nameB, "", "NO", ruleList);
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(), "$.success")) == true, "调用接口返回结果：" + XMJSONPath.readPath(dataApi.getApi_response(), "$.message"));
        clusterIdNewB = XMJSONPath.readPath(dataApi.getApi_response(), "$.result");

        //4.查看列表，check是否包含刚创建的人群
        memberClusterTools.getMemberClusterList();
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").toJavaList(JSONObject.class).stream().filter(e -> e.getString("id").equals(clusterIdNewA)).count() == 1, "列表中没获取到刚创建的会员分群（满足所有条件）");
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").toJavaList(JSONObject.class).stream().filter(e -> e.getString("id").equals(clusterIdNewB)).count() == 1, "列表中没获取到刚创建的会员分群（满足任意一个条件）");
        //5.操作手动更新
        memberClusterTools.manuaUpdatelMemberCluster();
        if (XMJSONPath.readPath(dataApi.getApi_response(), "$.message").equals("请稍后再试，手动更新需要间隔一小时")) {
            //5.1 如果遇到这种场景，那么就启动存量数据了
            clusterIdA = "1850830131517263874";
            clusterIdB = "1850835279266254850";

        } else {
            //5.2 可以操作手动更新时，用新数据
            Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(), "$.success")) == true, "调用接口返回结果：" + XMJSONPath.readPath(dataApi.getApi_response(), "$.message"));
            //休息20秒，等待拉取数据结果
            Thread.sleep(20000);
            clusterIdA = clusterIdNewA;
            clusterIdB = clusterIdNewB;


        }

        //6.check 2个人群对应的会员名单，核对人数
        memberClusterTools.getClusterMemberList(clusterIdA);
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").size() == 1, "更新后，满足所有条件的会员名单数量有问题，存量数据有1个满足条件的，请检查杜君丽学员为啥没满足条件");
        String memberId = XMJSONPath.readPath(dataApi.getApi_response(), "$.result.records[0].id");
        //6.1 check 会员名单-对应会员信息会员分群的账户情况
        memberClusterTools.findMemberClusterInfo(memberId);
        //6.1.1 check 会员卡课程剩余次数
        Assert.assertEquals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.memberCardCourseLeftBalance"), "61.00", "存量会员剩余购买会员卡次数61次，请检查是否是被人用了");
        //6.1.2 check 储值卡剩余金额
        Assert.assertEquals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.depositCardLeftBalance"), "999.00", "存量会员剩余购买储值卡金额999元，请检查是否是被人用了");
        //6.2. check 会员分群的会员名单
        memberClusterTools.getClusterMemberList(clusterIdB);
        System.out.println("满足任意一个分群会员名单数量" + XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").size());
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").size() >= 0, "更新后，满足任意条件的会员名单数量有问题，存量数据有3个满足条件的，请检查杜君丽，吴彦祖，晨晨爸爸这3个学员为啥没满足条件");

        //7. 操作定向运营
        //7.1 批量发放微信消息
        memberClusterTools.batchMessagePushForMemberCluster(clusterIdA, "WECHAT_COMMON");
        Assert.assertTrue(Boolean.valueOf(XMJSONPath.readPath(dataApi.getApi_response(), "$.success")) == true, "调用接口返回结果：" + XMJSONPath.readPath(dataApi.getApi_response(), "$.message"));

        Thread.sleep(2000);
        //7.1.2 check 运营记录中是够生成一条记录：消息推送
        memberClusterTools.getClusterOperateRecord(clusterIdA);
        Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records")
                .toJavaList(JSONObject.class).stream()
                .filter(e -> "WECHAT_COMMON".equals(e.getString("messageType"))).count() >= 1, "列表中没获到刚操作定向运营发微信消息生成的运营记录");
        //常量放前面，变量放后面，否则容易报空指针，因为有些对应没messageType这个字段，还有一种解决方案，就是先过滤掉messageType为空的对象

        //7.2 批量发放优惠券
        //获取存量优惠券：会员分群定向运营券，如果没有则新建
        String couponName = "会员分群定向运营券专用";
        couponTools.getStudioCouponList(couponName, "CLAIMABLE");
        String couponId = "";
        if (XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").size() == 1) {

            couponId = XMJSONPath.readPath(dataApi.getApi_response(), "$.result.records[0].id");
        } else {//创建新的用于营销活动的优惠券
            List<String> memberStatusLimitsA = new ArrayList<>();
            memberStatusLimitsA.add("POTENTIAL");
            memberStatusLimitsA.add("NORMAL");
            memberStatusLimitsA.add("HISTORY");

            couponId = couponTools.createCoupon("WITHOUT", "WITHOUT", memberStatusLimitsA, couponName, true,
                    "DISCOUNT", -1, "RELATIVE", couponName + "领取30天内有效；用于营销活动，客户分群定向运营，不要改动", true);
        }
        //批量发放优惠券
        if (!StringUtils.isEmpty(couponId)) {
            //7.2.1 操作定向运营发放优惠券
            memberClusterTools.batchSendCouponForMemberCluster(clusterIdA, couponId);
            String taskIdA = XMJSONPath.readPath(dataApi.getApi_response(), "$.result");
            Thread.sleep(2000);

            //7.2.2 check 运营记录中是够生成一条记录：发优惠券
            memberClusterTools.getClusterOperateRecord(clusterIdA);
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").toJavaList(JSONObject.class).stream().filter(e -> e.getString("operateType").equals("SEND_COUPON")).count() >= 1, "列表中没获到刚操作定向运营发优惠券生成的运营记录");

            String couponRecordId = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records")
                    .toJavaList(JSONObject.class).stream()
                    .filter(e -> "SEND_COUPON".equals(e.getString("operateType")))
                    .findFirst().map(e -> e.getString("id")).orElse(null);
            //7.2.2.1 查看运营详情
            memberClusterTools.fetchMemberClusterOperateRecordDetail(couponRecordId);
            Assert.assertEquals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.operateType"), "SEND_COUPON", "发送内容是优惠券，但是返回不对");
            Assert.assertEquals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.memberCount"), "1", "发送会员数量是1，但是返回不对");

            //7.2.2.2 check 运营详情-发送名单
            memberClusterTools.fetchListOfOperateMember(clusterIdA, couponRecordId);
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").size() == 1, "发送名单数量不等于0");
            Assert.assertTrue(XMJSONPath.readPath(dataApi.getApi_response(), "$.result.records[0].id").equals(memberId), "会员ID对不上");


            //7.2.3 check任务中心生成一条任务
            Thread.sleep(2000);
            couponTools.getStudioBatchTaskPage();
            Long goalTask = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").toJavaList(JSONObject.class).stream().filter(e ->
                    e.getString("id").equals(taskIdA)).count();
            Assert.assertTrue(goalTask == 1, "刚在会员分群中操作的定向运营发放优惠券，在任务中心查看，后端没返回目标数据");
            //7.2.3.1 check发送状态成功， 发送1个学员，1条成功，0条失败
            XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").toJavaList(JSONObject.class).stream().filter(e ->
                    e.getString("id").equals(taskIdA)).forEach(object ->
                    Assert.assertTrue("SUCCESS".equals(object.getString("state")) && 1 == object.getInteger("totalNumber") && 0 == object.getInteger("failNumber") &&
                            1 == object.getInteger("successNumber")));

            //学员详情，优惠券详情check 已发放的优惠券此处就不check了，因为优惠券那里相同的操作都check过了，那里不出问题，这里就OK

        }

        //7.3 批量发放体验卡
        //获取存量体验卡：会员分群定向运营券，如果没有则新建
        //全局搜索该体验卡
        String experienceCardName = "客户分群专用体验卡";
        cardTools.doMemberCardcommonSearch(experienceCardName, "EXPERIENCE_CARD");
        String experienceCardId = "";
        if (XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").size() >= 1 && "YES".equals(XMJSONPath.readPath(dataApi.getApi_response(), "$.result[0].shelfState"))) {

            experienceCardId = XMJSONPath.readPath(dataApi.getApi_response(), "$.result[0].id");
        } else {
            //创建新的用于营销活动的体验卡
            experienceCardId = tools.create("EXPERIENCE_CARD", experienceCardName, "全部", "YES", "课程次数", true).getString("result");

        }

        //批量发放体验卡
        if (!StringUtils.isEmpty(experienceCardId)) {
            //7.3.1 操作定向运营发放体验卡
            memberClusterTools.batchSendExpCardForMemberCluster(clusterIdA, experienceCardId);
            String taskIdB = XMJSONPath.readPath(dataApi.getApi_response(), "$.result");

            //7.3.2 check 运营记录中是够生成一条记录:发体验卡
            memberClusterTools.getClusterOperateRecord(clusterIdA);
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").toJavaList(JSONObject.class).stream().filter(e -> e.getString("operateType").equals("SEND_EXPERIENCE_CARD")).count() >= 1, "列表中没获到刚操作定向运营发优惠券生成的运营记录");

            //7.3.3check任务中心生成一条任务
            Thread.sleep(2000);
            couponTools.getStudioBatchTaskPage();
            Long goalTask = XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").toJavaList(JSONObject.class).stream().filter(e ->
                    e.getString("id").equals(taskIdB)).count();
            Assert.assertTrue(goalTask == 1, "刚在会员分群中操作的定向运营发放体验卡，在任务中心查看，后端没返回目标数据");
            //7.3.3.1 check发送状态成功， 发送1个学员，1条成功，0条失败
            /*XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result.records").toJavaList(JSONObject.class).stream().filter(e ->
                    e.getString("id").equals(taskIdB)).forEach(object ->
                    Assert.assertTrue("SUCCESS".equals(object.getString("state")) && 1==object.getInteger("totalNumber")  && 0==object.getInteger("failNumber")&&
                            1==object.getInteger("successNumber")));*/

        }


    }

    @AfterTest(description = "删除此case创建的会员分群")
    public void delData() {
        if (!StringUtils.isEmpty(this.clusterIdNewA)) {
            memberClusterTools.deleteMemberCluster(clusterIdNewA);
            //查看列表，check是否包含刚创建的人群
            memberClusterTools.getMemberClusterList();
            Assert.assertTrue(XMJSONPath.getJSONArrayByReadPath(dataApi.getApi_response(), "$.result").toJavaList(JSONObject.class).stream().filter(e -> e.getString("id").equals(clusterIdNewA)).count() == 0, "刚删除的分群在列表中还能搜索到");

        }

        if (!StringUtils.isEmpty(this.clusterIdNewB)) {
            memberClusterTools.deleteMemberCluster(clusterIdNewB);
        }


    }

}

    