package com.xiaomai.cases.polar.finance.salary;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaomai.basetest.BaseTestImpl;
import com.xiaomai.cases.polar.finance.revenueAndExpenditure.RevenueAndExpenditureTools;
import com.xiaomai.cases.polar.setting.pay.PayTools;
import com.xiaomai.enums.ApiModule;
import com.xiaomai.enums.LoginAccount;
import com.xiaomai.enums.RequestType;
import com.xiaomai.enums.Terminal;
import com.xiaomai.utils.TimeUtils;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @BelongsProject: xm-sportstest
 * @BelongsPackage: com.xiaomai.cases.polar.finance.salary
 * @Author: xuyamei
 * @CreateTime: 2024-11-08  10:26
 * @Description: 新增、更新、删除工资结算单
 * @Version: 1.0
 */
public class TestSettleSubmitOrUpdateOrDelete extends BaseTestImpl {
    SalaryTools salaryTools = new SalaryTools();
    PayTools payTools = new PayTools();
    RevenueAndExpenditureTools revenueAndExpenditureTools = new RevenueAndExpenditureTools();
    private String id; // 结算单id
    private String settleDetailId = ""; // 员工结算明细id
    private String payWay; // 员工结算明细id
    @BeforeMethod
    @Override
    public void beforeTest(){
        setTestInfo(ApiModule.Polar_Salary,"API_settle_submit", LoginAccount.GYM_PROD, Terminal.B,"xym");
        super.beforeTest();
    }

    @Test
    public void testSettleSubmit() throws InterruptedException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("brandId",xmAppApi.getLoginInfo().getBrandId());
        jsonObject.put("studioId",xmAppApi.getLoginInfo().getStudioId());
        jsonObject.put("operatorId",xmAppApi.getLoginInfo().getAdminId());
        jsonObject.put("startDate", TimeUtils.getBeforeDayDate(1)); // 结算开始时间
        jsonObject.put("payDate", TimeUtils.getTodayTime()); // 发薪日期
        jsonObject.put("endDate", TimeUtils.getTodayEndTime(-1)); //结算结束时间
        JSONArray adminIds = new JSONArray();
        adminIds.add(xmAppApi.getLoginInfo().getAdminId());
        jsonObject.put("adminIds",adminIds);


        // 查询开启的发薪方式
        JSONArray payList = payTools.getList().getJSONArray("result");
        for (int i = 0; i < payList.size(); i++){
            if (!payList.getJSONObject(i).getString("code").equals("6")){
                payWay = payList.getJSONObject(i).getString("code");
                break;
            }
        }
        jsonObject.put("payWay",payWay);

        xmAppApi.doRequest(RequestType.JSON,params,jsonObject.toJSONString(),headers).assetsSuccess(true);
        Thread.sleep(8000);

        String searchContext = "{\"brandId\":\""+xmAppApi.getLoginInfo().getBrandId()+"\",\"studioId\":\""+xmAppApi.getLoginInfo().getStudioId()+"\",\"current\":0,\"size\":20,\"startOfPayDate\":"+TimeUtils.getTodayTime()+",\"endOfPayDate\":"+TimeUtils.getTodayEndTime()+",\"startOfCreated\":"+TimeUtils.getTodayTime()+",\"endOfCreated\":"+TimeUtils.getTodayEndTime()+",\"settleStateList\":[\"FINISHED\"],\"operatorId\":\""+xmAppApi.getLoginInfo().getAdminId()+"\"}";

        // check 1：获取结算单列表
        JSONArray search = salaryTools.searchSettle(searchContext);
        String[] resultKey = {"startDate","endDate","payDate","payWay","state"};
        String[] resultValue = {String.valueOf(TimeUtils.getBeforeDayDate(1)),String.valueOf(TimeUtils.getTodayEndTime(-1)),String.valueOf(TimeUtils.getTodayTime()),payWay,"FINISHED"};
        if (search.size()==0){
            return;
        }
        id = search.getJSONObject(0).getString("id");  // 获取结算记录id
        for (int i = 0; i < resultKey.length; i++){
            if (resultKey[i].equals("endDate")){
                Assert.assertEquals(dateFormat(search.getJSONObject(0).getLong(resultKey[i])),dateFormat(Long.parseLong(resultValue[i])));
            }else{
                Assert.assertEquals(search.getJSONObject(0).getString(resultKey[i]),resultValue[i],"结算单数据与实际数据不符合"+resultKey[i]+":"+resultValue[i]);

            }

        }

        // check 2：获取结算单详情
        JSONObject fetchRecordById = salaryTools.fetchRecordById(id);
        for (int i = 0; i < resultKey.length; i++){
            if (resultKey[i].equals("endDate")){
                Assert.assertEquals(dateFormat(fetchRecordById.getLong(resultKey[i])),dateFormat(Long.parseLong(resultValue[i])));
            }else{
                Assert.assertEquals(fetchRecordById.getString(resultKey[i]),resultValue[i],"结算单详情数据与实际数据不符合"+resultKey[i]+":"+resultValue[i]);

            }
        }
        Assert.assertTrue(fetchRecordById.getDouble("amount")>0,"结算单详情中结算金额小于0");
        Assert.assertTrue(fetchRecordById.getJSONArray("settleAdminIds").getString(0).equals(xmAppApi.getLoginInfo().getAdminId()),"结算单详情中结算金额小于0");

        // check 3：获取结算单结算明细
        JSONArray fetchSettleResult = salaryTools.fetchSettleResult(id);
        boolean flag = false;
        for (int i = 0; i < fetchSettleResult.size(); i++){
            if (fetchSettleResult.getJSONObject(i).getString("adminId").equals(xmAppApi.getLoginInfo().getAdminId())){
                flag = true;
                settleDetailId = fetchSettleResult.getJSONObject(i).getString("id");
                Assert.assertTrue(fetchSettleResult.getJSONObject(i).getDouble("totalAmount")>0,"结算单结算明细中结算金额小于0");
                Assert.assertTrue(fetchSettleResult.getJSONObject(i).getJSONObject("coachPay").getDouble("amount")>0,"结算单结算明细中上课绩效结算金额小于0");
                Assert.assertTrue(fetchSettleResult.getJSONObject(i).getJSONObject("salePay").getDouble("amount")>=0,"结算单结算明细中销售绩效结算金额小于0");
                break;
            }
        }
        Assert.assertTrue(flag,"结算单结算明细没有目标适用员工数据");

        // check 4：获取员工结算明细详情
        JSONObject fetchSettleResultDetailById = salaryTools.fetchSettleResultDetailById(settleDetailId);
        Assert.assertTrue(fetchSettleResultDetailById.getDouble("totalAmount")>0,"员工结算明细详情中结算金额小于0");
        Assert.assertTrue(fetchSettleResultDetailById.getString("adminId").equals(xmAppApi.getLoginInfo().getAdminId()),"员工结算明细详情中员工id不符");
        Assert.assertTrue(fetchSettleResultDetailById.getString("startDate").equals(String.valueOf(TimeUtils.getBeforeDayDate(1))),"员工结算明细详情中结算开始时间错误");
        Assert.assertEquals(dateFormat(fetchSettleResultDetailById.getLong("endDate")),dateFormat(TimeUtils.getTodayEndTime(-1)),"员工结算明细详情中结算结束时间错误");

    }

    @DataProvider
    public Object[][] dataProvider() {
        return new Object[][]{
                {1.00,1},
                {-1.00,2}
        };
    }

    @Test(priority = 1,dataProvider = "dataProvider")
    public void testUpdateSettleResult(double num,int type) throws InterruptedException {
        if (settleDetailId.equals("")){
            JSONArray fetchSettleResult = salaryTools.fetchSettleResult(id);
            for (int i = 0; i < fetchSettleResult.size(); i++){
                if (fetchSettleResult.getJSONObject(i).getString("adminId").equals(xmAppApi.getLoginInfo().getAdminId())){
                    settleDetailId = fetchSettleResult.getJSONObject(i).getString("id");
                    break;
                }
            }
        }
        JSONObject fetchSettleResultDetailById = salaryTools.fetchSettleResultDetailById(settleDetailId);
        JSONArray billItemList = fetchSettleResultDetailById.getJSONObject("settleResultInfo").getJSONArray("billItemList");
        Double beforeTotalAmount = fetchSettleResultDetailById.getDouble("totalAmount");
        int index = 0; //加或者减几次
        for (int i = 0; i < billItemList.size(); i++){
            index++;
            double amount = billItemList.getJSONObject(i).getDouble("amount")+num;
            billItemList.getJSONObject(i).put("amount",amount);
        }
        // 编辑工资明细
        salaryTools.updateSettleResult(settleDetailId,billItemList);
        Thread.sleep(1000);
        // check 1:获取结算明细详情
        double afterTotalAmount = salaryTools.fetchSettleResultDetailById(settleDetailId).getDouble("totalAmount");
        if (type==1){
            Assert.assertEquals(afterTotalAmount,beforeTotalAmount+index,"编辑工资明细后，结算金额与预期不符");
        }else {
            Assert.assertEquals(afterTotalAmount,beforeTotalAmount-index,"编辑工资明细后，结算金额与预期不符");
        }

        // check 2:获取结算单详情
        JSONObject fetchRecordById = salaryTools.fetchRecordById(id);
        Assert.assertEquals(fetchRecordById.getDouble("amount"),afterTotalAmount,"结算单详情中结算金额与预期不符");

    }


    @Test(description = "确认结算",priority = 2)
    public void testSettleConfirm() throws InterruptedException {
        // 确认结算前查询发放工资的收支明细有多少条
        JSONObject revenue = revenueAndExpenditureTools.pageNormalIncomeExpense(payWay,"EXPENSE","SALARY",xmAppApi.getLoginInfo().getStudioId());
        int beforeTotal = Integer.parseInt(revenue.getJSONObject("result").getString("total"));
        // 确认结算
        salaryTools.confirmSettle(id);
        Thread.sleep(1000);

        // check 1:结算单状态为已确认
        JSONObject fetchRecordById = salaryTools.fetchRecordById(id);
        Assert.assertEquals(fetchRecordById.getString("state"),"CONFIRMED","结算单状态与预期不符");

        //check 2: 收支明细
        revenue = revenueAndExpenditureTools.pageNormalIncomeExpense(payWay,"EXPENSE","SALARY",xmAppApi.getLoginInfo().getStudioId());
        Assert.assertEquals(Integer.parseInt(revenue.getJSONObject("result").getString("total")),beforeTotal+1,"确认结算后，发放工资的收支明细数量与预期不符");

    }

    @Test(description = "删除结算单",priority = 3)
    public void testSettleDelete() throws InterruptedException {
        // 确认结算前查询发放工资的收支明细有多少条
        JSONObject revenue = revenueAndExpenditureTools.pageNormalIncomeExpense(payWay,"EXPENSE","SALARY",xmAppApi.getLoginInfo().getStudioId());
        int beforeTotal = Integer.parseInt(revenue.getJSONObject("result").getString("total"));

        salaryTools.deleteSettle(id);
        Thread.sleep(1000);
        revenue = revenueAndExpenditureTools.pageNormalIncomeExpense(payWay,"EXPENSE","SALARY",xmAppApi.getLoginInfo().getStudioId());
        Assert.assertEquals(Integer.parseInt(revenue.getJSONObject("result").getString("total")),beforeTotal-1,"删除结算单后，发放工资的收支明细数量与预期不符");
    }




    private String dateFormat(long timestamp){
        Date date = new Date(timestamp);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(date);
        return formattedDate;
    }



}
