package com.xiaomai.cases.polar.data.salesData;

import com.alibaba.fastjson.JSONObject;
import com.xiaomai.cases.polar.finance.order.OrderTools;
import com.xiaomai.cases.polar.member.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.TimeUtils;
import com.xiaomai.utils.XMBaseTest;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.math.BigDecimal;

public class TestCenterData extends XMBaseTest {

    Tools tools=new Tools();

    OrderTools orderTools=new OrderTools();

    CardTools cardTools=new CardTools();

    SalesDataTools salesDataTools=new SalesDataTools();

    String memberId;

    String cardId;

    String getDetailId;

    float paidAmount;

    @BeforeMethod
    public void beforeTest(){
        xmAppApi.setApiModule(ApiModule.Polar_Data)
                .setApiName("API_centerData")
                .setLoginUser(LoginAccount.GYM_PROD)
                .setTerminal(Terminal.B);

        dal.setCase_owner("yff")
                .setCase_name(Thread.currentThread().getStackTrace()[1].getFileName().split("\\.")[0]);
        super.beforeTest();
    }

    @Test(description = "销售数据-数据分析-汇总")
    public void testCenterData(){

        //先查一下当前今天的销售数据-数据分析-汇总
        JSONObject beforeAnalysis=salesDataTools.centerData("DAY",TimeUtils.getTodayEndTime(),TimeUtils.getTodayTime());
        int beforeNewMemberCount=Integer.parseInt(beforeAnalysis.getJSONObject("result").getString("newMemberCount"));//新增会员数
        BigDecimal beforeActualAmount=new BigDecimal(beforeAnalysis.getJSONObject("result").getString("actualAmount"));//签单实收金额


        //先查一下当前今天的销售数据-按照来源是无筛选数据明细的数据
        JSONObject beforeResourceDataDetail=salesDataTools.resourceDataDetail(TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime(),"-1","DAY","NEW_MEMBER_COUNT_DESC");
        int beforeResourceDataDetailNewMemberCount=Integer.parseInt(beforeResourceDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("newMemberCount"));
        BigDecimal beforeResourceDataDetailActualAmount=new BigDecimal(beforeResourceDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));


        //先查一下当前今天的销售数据-按照添加人是当前人筛选数据明细的数据
        JSONObject beforeCreatorDataDetail=salesDataTools.creatorDataDetail(TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime(),xmAppApi.getLoginInfo().getAdminId(),"DAY","NEW_MEMBER_COUNT_DESC");
        int beforeCreatorDataDetailNewMemberCount=Integer.parseInt(beforeCreatorDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("newMemberCount"));
        BigDecimal beforeCreatorDataDetailActualAmount=new BigDecimal(beforeCreatorDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));


        //先查一下当前今天的销售数据-按照跟进销售是无筛选数据明细的数据
        JSONObject beforeSalesDataDetail=salesDataTools.salesDataDetail(TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime(),"-1","DAY","NEW_MEMBER_COUNT_DESC");
        int beforeSalesDataDetailNewMemberCount=Integer.parseInt(beforeSalesDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("newMemberCount"));
        BigDecimal beforeSalesDataDetailActualAmount=new BigDecimal(beforeSalesDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));



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


        //①新增会员，并签单完成之后，校验新增会员数和签单实收金额增加

        String name = "创建数据中心潜在会员"+ RandomStringUtil.randomString(3);
        String phone = RandomStringUtil.randomMobile("111");
        //添加线索
        memberId = tools.create(name,phone).getString("result");

        //获取会员卡信息
        //获取会员卡列表,没有则新建一个
        int cardTotal = Integer.parseInt(orderTools.fetchPageOfMemberCard("次卡","MEMBER_CARD").getJSONObject("result").getString("total"));
        if (cardTotal == 0) {
            cardId = cardTools.memberCardCreate("次卡-创建订单会员卡"+TimeUtils.getCurrentTime()).getString("result");
        }
        JSONObject memberCard=orderTools.fetchPageOfMemberCard("次卡","MEMBER_CARD");
        cardId=memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("id");
        BigDecimal quantity= new BigDecimal(memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getJSONArray("benefitList").getJSONObject(0).getString("balance"));
        float price= Float.parseFloat(memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("price"));
        int validPeriod= Integer.parseInt(memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("validPeriod"));

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

        //获取签单要用的卡快照id
        String latestSnapshotId=orderTools.fetchDetailById(cardId,xmAppApi.getLoginInfo().getBrandId(),xmAppApi.getLoginInfo().getStudioId(),xmAppApi.getLoginInfo().getAdminId()).getJSONObject("result").getString("latestSnapshotId");

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

        //检查会员对该卡是否超出购买上限
        boolean limitResult=orderTools.checkAllowPurchase("MEMBER_CARD",cardId,memberId,"1",xmAppApi.getLoginInfo().getBrandId(),xmAppApi.getLoginInfo().getStudioId(),xmAppApi.getLoginInfo().getAdminId()).getBoolean("success");

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

        if(limitResult == true) {

            //创建订单
            JSONObject orderResult = orderTools.signOrder(cardId, latestSnapshotId, quantity, price, validPeriod, latestSnapshotId, price / 2, "PURCHASE",
                    "MEMBER_CARD", memberId, price - price / 2, price - price / 2, "1",true);
            getDetailId = orderResult.getString("result");

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

            //获取订单详情的实收金额
            JSONObject getDetailResult=orderTools.getDetail(getDetailId);
            paidAmount = Float.parseFloat(getDetailResult.getJSONObject("result").getString("paidAmount"));//实收金额

        }


        JSONObject analysis=new JSONObject();
        analysis.put("dateType","DAY");
        analysis.put("endTime", TimeUtils.getTodayEndTime());
        analysis.put("startTime", TimeUtils.getTodayTime());
        analysis.put("brandId",xmAppApi.getLoginInfo().getBrandId());
        analysis.put("studioId",xmAppApi.getLoginInfo().getStudioId());
        analysis.put("operatorId",xmAppApi.getLoginInfo().getAdminId());

        xmAppApi.doRequest(RequestType.JSON,params,analysis.toJSONString(),headers).assetsSuccess(true);
        JSONObject analysisResult=xmAppApi.getBodyInJSON();
        Assert.assertEquals(analysisResult.getString("success"),"true","获取销售数据-数据分析-汇总失败");
        int newMemberCount=Integer.parseInt(analysisResult.getJSONObject("result").getString("newMemberCount"));//新增会员数
        BigDecimal actualAmount=new BigDecimal(analysisResult.getJSONObject("result").getString("actualAmount"));//签单实收金额
//        BigDecimal qoqOfActualAmount=new BigDecimal(analysisResult.getJSONObject("result").getString("qoqOfActualAmount"));//签单实收金额环比
//        BigDecimal qoqOfNewMemberCount=new BigDecimal(analysisResult.getJSONObject("result").getString("qoqOfNewMemberCount"));//新增会员数环比
//        BigDecimal yoyOfActualAmount=new BigDecimal(analysisResult.getJSONObject("result").getString("yoyOfActualAmount"));//签单实收金额同比
//        BigDecimal yoyOfNewMemberCount=new BigDecimal(analysisResult.getJSONObject("result").getString("yoyOfNewMemberCount"));//新增会员数同比

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


        //校验：
        //1.校验新增一个会员和签单之后销售数据-数据分析汇总的新增会员数与签单实收金额
        Assert.assertEquals(newMemberCount,beforeNewMemberCount+1,"新建一个线索之后数据分析的新增会员数未加1");
        Assert.assertEquals(actualAmount,beforeActualAmount.add(BigDecimal.valueOf(paidAmount)),"签单完成之后，销售数据数据分析的签单实收金额未增加对应的签单实收金额");


        //2.校验销售数据-趋势图的签单实收金额(注意：暂时无法在这里直接校验新增会员数的趋势图，因为beforeNewMemberCount是int型，而趋势图返回的value这个接口他定义的是BigDecimal类型，如果都改了BigDecimal上面接口比较的时候又要用int)
        JSONObject trendResult=salesDataTools.trend("DAY","SIGN_ORDER_ACTUAL_AMOUNT",TimeUtils.getTodayEndTime(),TimeUtils.getTodayTime());
        BigDecimal value=new BigDecimal(trendResult.getJSONArray("result").getJSONObject(0).getJSONArray("items").getJSONObject(0).getString("value"));
        Assert.assertEquals(value,beforeActualAmount.add(BigDecimal.valueOf(paidAmount)),"签单完成之后，销售数据趋势图的签单实收金额未增加对应的签单实收金额");


        //3.校验销售数据-按照来源为无筛选数据明细-有无上述新增会员数和签单实收金额
        JSONObject resourceDataDetail=salesDataTools.resourceDataDetail(TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime(),"-1","DAY","NEW_MEMBER_COUNT_DESC");
        int resourceDataDetailNewMemberCount=Integer.parseInt(resourceDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("newMemberCount"));
        BigDecimal resourceDataDetailActualAmount=new BigDecimal(resourceDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
        Assert.assertEquals(resourceDataDetailNewMemberCount,beforeResourceDataDetailNewMemberCount+1,"新建一个来源为无的线索之后，销售数据明细筛选来源为无的新增会员数未加1");
        Assert.assertEquals(resourceDataDetailActualAmount,beforeResourceDataDetailActualAmount.add(BigDecimal.valueOf(paidAmount)),"签单完成之后，销售数据明细来源为无的签单实收金额未增加对应的签单实收金额");


        //4.校验销售数据-按照添加人是当前人筛选数据明细-有无上述新增会员数和签单实收金额

        JSONObject creatorDataDetail=salesDataTools.creatorDataDetail(TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime(),xmAppApi.getLoginInfo().getAdminId(),"DAY","NEW_MEMBER_COUNT_DESC");
        int creatorDataDetailNewMemberCount=Integer.parseInt(creatorDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("newMemberCount"));
        BigDecimal creatorDataDetailActualAmount=new BigDecimal(creatorDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
        Assert.assertEquals(creatorDataDetailNewMemberCount,beforeCreatorDataDetailNewMemberCount+1,"新建一个线索之后，销售数据明细筛选添加人是当前人的新增会员数未加1");
        Assert.assertEquals(creatorDataDetailActualAmount,beforeCreatorDataDetailActualAmount.add(BigDecimal.valueOf(paidAmount)),"签单完成之后，销售数据明细筛选添加人是当前人的签单实收金额未增加对应的签单实收金额");



        //5.校验销售数据-按照跟进销售为无筛选数据明细-有无上述新增会员数和签单实收金额
        JSONObject salesDataDetail=salesDataTools.salesDataDetail(TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime(),"-1","DAY","NEW_MEMBER_COUNT_DESC");
        int salesDataDetailNewMemberCount=Integer.parseInt(salesDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("newMemberCount"));
        BigDecimal salesDataDetailActualAmount=new BigDecimal(salesDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
        Assert.assertEquals(salesDataDetailNewMemberCount,beforeSalesDataDetailNewMemberCount+1,"新建一个线索之后，销售数据明细筛选跟进销售为无的新增会员数未加1");
        Assert.assertEquals(salesDataDetailActualAmount,beforeSalesDataDetailActualAmount.add(BigDecimal.valueOf(paidAmount)),"签单完成之后，销售数据明细筛选跟进销售为无的签单实收金额未增加对应的签单实收金额");


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



        //②退单--校验签单实收金额不变


        //创建退单订单
        //查询要退的卡id 从listUserRefundableCard-查询用户可退的会员卡列表中获取
        JSONObject listUserRefundableCardResult=orderTools.listUserRefundableCard("MEMBER","",memberId);
        String listUserRefundableId=listUserRefundableCardResult.getJSONArray("result").getJSONObject(0).getString("id");

        //查询订单或者收支可退流水金额（包含乐动收银状态信息）
        boolean checkRefundableAmountResult=orderTools.checkRefundableAmount(getDetailId,price - price / 2).getBoolean("success");

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

        if(checkRefundableAmountResult == true) {
            //退单-会员卡
            JSONObject refundOrderResult = orderTools.refundOrder(0, listUserRefundableId, quantity, price - price / 2, "MEMBER_CARD",
                    memberId, price - price / 2, price - price / 2, "1");
            String refundOrderGetDetailId = refundOrderResult.getString("result");

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


            //校验：
            //1.校验退单之后销售数据-数据分析汇总的签单实收金额应不变
            JSONObject afterAnalysis1 = salesDataTools.centerData("DAY", TimeUtils.getTodayEndTime(), TimeUtils.getTodayTime());
            BigDecimal afterActualAmount1 = new BigDecimal(afterAnalysis1.getJSONObject("result").getString("actualAmount"));//签单实收金额
            Assert.assertEquals(afterActualAmount1, actualAmount, "退单订单之后，销售数据数据分析的签单实收金额不应有变动");


            //2.校验销售数据-趋势图的签单实收金额应不变
            JSONObject afterTrendResult1 = salesDataTools.trend("DAY", "SIGN_ORDER_ACTUAL_AMOUNT", TimeUtils.getTodayEndTime(), TimeUtils.getTodayTime());
            BigDecimal afterValue1 = new BigDecimal(afterTrendResult1.getJSONArray("result").getJSONObject(0).getJSONArray("items").getJSONObject(0).getString("value"));
            Assert.assertEquals(afterValue1, actualAmount, "退单订单之后，销售数据趋势图的签单实收金额不应有变动");


            //3.校验销售数据-按照来源为无筛选数据明细-上述签单实收金额应不变
            JSONObject afterResourceDataDetail1 = salesDataTools.resourceDataDetail(TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime(), "-1", "DAY", "NEW_MEMBER_COUNT_DESC");
            BigDecimal afterResourceDataDetailActualAmount1 = new BigDecimal(afterResourceDataDetail1.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
            Assert.assertEquals(afterResourceDataDetailActualAmount1, resourceDataDetailActualAmount, "退单订单之后，销售数据明细来源为无的签单实收金额不应有变动");


            //4.校验销售数据-按照添加人是当前人筛选数据明细-上述签单实收金额应不变

            JSONObject afterCreatorDataDetail1 = salesDataTools.creatorDataDetail(TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime(), xmAppApi.getLoginInfo().getAdminId(), "DAY", "NEW_MEMBER_COUNT_DESC");
            BigDecimal afterCreatorDataDetailActualAmount1 = new BigDecimal(afterCreatorDataDetail1.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
            Assert.assertEquals(afterCreatorDataDetailActualAmount1, creatorDataDetailActualAmount, "退单订单之后，销售数据明细筛选添加人是当前人的签单实收金额不应有变动");


            //5.校验销售数据-按照跟进销售为无筛选数据明细-上述签单实收金额应不变
            JSONObject afterSalesDataDetail1 = salesDataTools.salesDataDetail(TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime(), "-1", "DAY", "NEW_MEMBER_COUNT_DESC");
            BigDecimal afterSalesDataDetailActualAmount1 = new BigDecimal(afterSalesDataDetail1.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
            Assert.assertEquals(afterSalesDataDetailActualAmount1, salesDataDetailActualAmount, "退单订单之后，销售数据明细筛选跟进销售为无的签单实收金额不应有变动");


            //作废退单订单，为了下述流程可以作废签单订单
            //校验是否可以作废退单订单
            boolean checkDiscardRefundVoucherResult = orderTools.checkDiscardVoucher(refundOrderGetDetailId).getBoolean("success");

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

            if (checkDiscardRefundVoucherResult == true) {
                //作废订单
                JSONObject refundDiscardResult = orderTools.discard(refundOrderGetDetailId, "重复录入", "已作废退单订单" + RandomStringUtil.randomString(10));

            }


            //③作废签单--校验签单实收金额减少

            //校验是否可以作废签单订单
            boolean checkDiscardSignVoucherResult = orderTools.checkDiscardVoucher(getDetailId).getBoolean("success");

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

            if (checkDiscardSignVoucherResult == true) {

                //作废签单订单
                JSONObject discardResult = orderTools.discard(getDetailId, "重复录入", "已作废签单订单" + RandomStringUtil.randomString(10));

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

                //校验：
                //1.校验作废签单订单之后销售数据-数据分析汇总的签单实收金额是否减少
                JSONObject afterAnalysis = salesDataTools.centerData("DAY", TimeUtils.getTodayEndTime(), TimeUtils.getTodayTime());
                BigDecimal afterActualAmount = new BigDecimal(afterAnalysis.getJSONObject("result").getString("actualAmount"));//签单实收金额
                Assert.assertEquals(afterActualAmount, actualAmount.subtract(BigDecimal.valueOf(paidAmount)), "作废签单订单之后，销售数据数据分析的签单实收金额未减少对应的签单实收金额");


                //2.校验销售数据-趋势图的签单实收金额是否减少
                JSONObject afterTrendResult = salesDataTools.trend("DAY", "SIGN_ORDER_ACTUAL_AMOUNT", TimeUtils.getTodayEndTime(), TimeUtils.getTodayTime());
                BigDecimal afterValue = new BigDecimal(afterTrendResult.getJSONArray("result").getJSONObject(0).getJSONArray("items").getJSONObject(0).getString("value"));
                Assert.assertEquals(afterValue, actualAmount.subtract(BigDecimal.valueOf(paidAmount)), "作废签单订单之后，销售数据趋势图的签单实收金额未减少对应的签单实收金额");


                //3.校验销售数据-按照来源为无筛选数据明细-上述签单实收金额是否减少
                JSONObject afterResourceDataDetail = salesDataTools.resourceDataDetail(TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime(), "-1", "DAY", "NEW_MEMBER_COUNT_DESC");
                BigDecimal afterResourceDataDetailActualAmount = new BigDecimal(afterResourceDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
                Assert.assertEquals(afterResourceDataDetailActualAmount, afterResourceDataDetailActualAmount1.subtract(BigDecimal.valueOf(paidAmount)), "作废签单订单之后，销售数据明细来源为无的签单实收金额未减少对应的签单实收金额");


                //4.校验销售数据-按照添加人是当前人筛选数据明细-上述签单实收金额是否减少

                JSONObject afterCreatorDataDetail = salesDataTools.creatorDataDetail(TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime(), xmAppApi.getLoginInfo().getAdminId(), "DAY", "NEW_MEMBER_COUNT_DESC");
                BigDecimal afterCreatorDataDetailActualAmount = new BigDecimal(afterCreatorDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
                Assert.assertEquals(afterCreatorDataDetailActualAmount, afterCreatorDataDetailActualAmount1.subtract(BigDecimal.valueOf(paidAmount)), "作废签单订单之后，销售数据明细筛选添加人是当前人的签单实收金额未减少对应的签单实收金额");


                //5.校验销售数据-按照跟进销售为无筛选数据明细-上述签单实收金额是否减少
                JSONObject afterSalesDataDetail = salesDataTools.salesDataDetail(TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime(), "-1", "DAY", "NEW_MEMBER_COUNT_DESC");
                BigDecimal afterSalesDataDetailActualAmount = new BigDecimal(afterSalesDataDetail.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("actualAmount"));
                Assert.assertEquals(afterSalesDataDetailActualAmount, afterSalesDataDetailActualAmount1.subtract(BigDecimal.valueOf(paidAmount)), "作废签单订单之后，销售数据明细筛选跟进销售为无的签单实收金额未减少对应的签单实收金额");

            }
        }
    }
}
