package com.xiaomai.cases.lunar.training;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaomai.basetest.BaseTestImpl;
import com.xiaomai.cases.lunar.minMemberCard.MinCardTools;
import com.xiaomai.cases.lunar.order.OrderCTools;
import com.xiaomai.cases.lunar.user.UserTools;
import com.xiaomai.cases.polar.finance.order.OrderTools;
import com.xiaomai.cases.polar.memberCard.CardTools;
import com.xiaomai.client.DataUserInfo;
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.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @BelongsProject: xm-sportstest
 * @BelongsPackage: com.xiaomai.cases.lunar.training
 * @Author: yff
 * @CreateTime: 2024-07-31  14:55
 * @Description: 使用储值卡购买存量的训练营
 * @Version: 1.0
 */
public class TestPurchaseCampByDeposit extends BaseTestImpl {
    @Resource(name = "trainingCTools")
    TrainingCTools trainTools;

    @Resource(name = "userTools")
    UserTools userTools;

    OrderCTools orderCTools = new OrderCTools();

    @Resource(name = "orderTools")
    OrderTools orderTools;

    @Resource(name = "cardTools")
    CardTools cardTools;
    @Resource(name = "minCardTools")
    MinCardTools minCardTools;

    DataUserInfo info = new DataUserInfo();

    String depositCardId;

    String depositBenefitId;

    private String  signOrderDepositOrderId = "";
    private String orderId = "";

    @BeforeMethod
    @Override
    public void beforeTest() {
        setTestInfo(ApiModule.Lunar_Training, "API_purchaseCamp", LoginAccount.GYM_MINIAPPC, Terminal.minApp, "yff");
        super.beforeTest();
    }

    @Test(description = "使用储值卡抵扣购买存量的训练营")
    public void testPurchaseCampByDeposit() {

        //注意：储值卡用的是存量的：存量储值卡充0赠1000   训练营用的是存量的：杭州自动化测试训练营B：999.99元

        //购买充0送1000的储值卡
        //获取的微信用户
        String memberId = userTools.getMemberInfo().getString("memberId");

        //切换B端
        info.setTerminal(Terminal.B);
        info.setLoginUser(LoginAccount.GYM_PROD);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //购买储值卡
        //查询存量储值卡
        //查询启用中的储值卡，获取储值卡id
        JSONObject deposit = cardTools.tenantMemberCardCommonSearch("DEPOSIT_CARD", "存量储值卡充0赠1000", info);
        String cardId = deposit.getJSONArray("result").getJSONObject(0).getString("id");
        String latestSnapshotId = XMJSONPath.readPath(cardTools.fetchDetailById(cardId, info), "$.result.latestSnapshotId");

        //购买1张储值卡
        signOrderDepositOrderId = cardTools.signOrderDeposit(cardId,latestSnapshotId,memberId,"0.00","1000.00",info);//购买储值卡订单ID

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

        //获取C端第1张可使用的储值卡
        JSONObject depositCard = minCardTools.listUserUsableDepositCard(memberId, "SINGLE_PAY_RESERVE");

        depositCardId = depositCard.getJSONObject("result").getJSONArray("applicableList").getJSONObject(0).getString("id");
        depositBenefitId = depositCard.getJSONObject("result").getJSONArray("applicableList").getJSONObject(0).getJSONObject("depositBenefit").getString("id");
        BigDecimal leftBalance = new BigDecimal(depositCard.getJSONObject("result").getJSONArray("applicableList").getJSONObject(0).getJSONObject("depositBenefit").getString("leftBalance"));//储值卡可用金额


        // 获取存量训练营活动

        String id = trainTools.getAppliableCampList("杭州自动化测试训练营B").getJSONObject(0).getString("id");
        BigDecimal price = new BigDecimal(trainTools.getAppliableCampList("杭州自动化测试训练营B").getJSONObject(0).getString("price"));


        JSONObject body = new JSONObject();
        body.put("campId", id);
        body.put("memberId", memberId);
        body.put("memo", "");
        body.put("receivableAmount", "0.00");
        body.put("studioId", xmAppApi.getLoginInfo().getStudioId());
        body.put("objectId", RandomStringUtil.randomString(16));
        body.put("depositCardId", depositCardId);
        body.put("depositAmount", price);
        xmAppApi.doRequest(RequestType.JSON, params, body.toString(), headers).assetsSuccess(true);

        orderId = xmAppApi.getBodyInJSON().getString("result");

        // check 1:订单详情
        JSONArray voucherItems = orderCTools.getDetail(orderId).getJSONObject("result").getJSONArray("voucherItems");
        String[] keys = new String[]{"skuId", "skuType"};
        String[] expect = new String[]{id, "TRAINING_CAMP"};
        for (int i = 0; i < keys.length; i++) {
            Assert.assertTrue(voucherItems.getJSONObject(0).getString(keys[i]).equals(expect[i]));
        }

        // check 2：查询我的训练营列表
        JSONArray listMyTrainingCamp = trainTools.listMyTrainingCamp(memberId);
        keys = new String[]{"tradeOrderId", "accountType"};
        expect = new String[]{orderId, "TRAINING"};
        // 生成训练营账户的id
        String accountId = "";
        for (int i = 0; i < listMyTrainingCamp.size(); i++) {
            if (listMyTrainingCamp.getJSONObject(i).getString("tenantMemberCardId").equals(id)) {
                for (int j = 0; j < keys.length; j++) {
                    Assert.assertTrue(listMyTrainingCamp.getJSONObject(i).getString(keys[j]).equals(expect[j]));
                    accountId = listMyTrainingCamp.getJSONObject(i).getString("id");
                }
            }
        }


        // check 3：获取我的训练营详情 以及和购买的训练营内容是否一致
        JSONObject findMyTrainingCampDetailById = trainTools.findMyTrainingCampDetailById(accountId);
        JSONObject findDetailById = trainTools.findDetailById(id, memberId);
        keys = new String[]{"id", "studioId", "title", "courseId", "openStartDate", "openEndDate", "totalClassHour", "price", "trainerIds"};
        for (int i = 0; i < keys.length; i++) {
            Assert.assertTrue(findMyTrainingCampDetailById.getJSONObject("trainingCampInfo").getString(keys[i]).equals(findDetailById.getString(keys[i])));
        }


        // check 3.2：验证我的训练营订单id
        Assert.assertTrue(findMyTrainingCampDetailById.getString("tradeOrderId").equals(orderId));

        //切换B端
        info.setTerminal(Terminal.B);
        info.setLoginUser(LoginAccount.GYM_PROD);

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

        //check 4：校验储值卡消耗列表增加签单类型的消耗记录，以及签单消耗记录的剩余金额=储值卡剩余金额-购买的训练营金额
        JSONObject consumeRecord = minCardTools.fetchPageOfConsumeRecord(depositCardId, depositBenefitId, info);
        String consumeType = consumeRecord.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("consumeType");
        BigDecimal leftUsableGiveBalance = new BigDecimal(consumeRecord.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("leftGiveBalance"));//可用赠送金额--注意：校验这个只适用于购买为0，使用赠送金额购买训练营的情况，所以只检验了赠送金额

        Assert.assertEquals(consumeType, "DEPOSIT_SIGN_ORDER", "使用储值卡签单训练营，消耗记录非签单类型");
        Assert.assertEquals(leftUsableGiveBalance.equals(leftBalance.subtract(price.setScale(2, RoundingMode.HALF_UP))), true, "使用储值卡签单训练营，签单消耗记录的剩余金额非扣除购买训练营使用的储值卡金额后的剩余金额");

    }

    @Test(description = "作废使用储值卡购买的训练营订单数据，为了下次再购买", priority = 2)
    public void delOrderData() {
        DataUserInfo dataUserInfo = new DataUserInfo();
        dataUserInfo.setTerminal(Terminal.B);
        dataUserInfo.setLoginUser(LoginAccount.GYM_PROD);
        orderTools.discard(orderId, "重复录入", "作废使用储值卡购买的训练营订单", dataUserInfo);
        try{
            Thread.sleep(3000);
        }catch (InterruptedException e){
           throw new RuntimeException(e);
        }

    }

    @Test(description = "作废购买储值卡订单数据", priority = 3)
    public void delsignOrderDepositOrderData() {
        DataUserInfo dataUserInfo = new DataUserInfo();
        dataUserInfo.setTerminal(Terminal.B);
        dataUserInfo.setLoginUser(LoginAccount.GYM_PROD);
        orderTools.discard(signOrderDepositOrderId, "重复录入", "作废购买储值卡订单", dataUserInfo);


    }
}