package com.pcloud.book.advertising.biz.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.pcloud.book.advertising.biz.AdvertisingCpaPaySyncRecordBiz;
import com.pcloud.book.advertising.check.QiLiShuSheApiHandler;
import com.pcloud.book.advertising.biz.AdvertisingCpaPaySettingBiz;
import com.pcloud.book.advertising.dao.BmOptionDao;
import com.pcloud.book.advertising.dao.BmRegisterDao;
import com.pcloud.book.advertising.dao.BmRegisterItemDao;
import com.pcloud.book.advertising.entity.AdvertisingBmRegister;
import com.pcloud.book.advertising.entity.AdvertisingCpaPaySetting;
import com.pcloud.book.advertising.entity.AdvertisingCpaPaySyncRecord;
import com.pcloud.book.advertising.entity.AdvertisingCpaProductPackage;
import com.pcloud.book.advertising.dao.AdvertisingCpaProductPackageDao;
import com.pcloud.book.advertising.biz.AdvertisingCpaProductPackageBiz;
import com.pcloud.book.advertising.enums.ApiActionCodeEnum;
import com.pcloud.book.advertising.enums.PayStatusThirdSyncEnum;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.NumberUtil;
import com.pcloud.exercisebook.dto.RefundExerciseBookDTO;
import com.pcloud.facade.tradecenter.dto.ExerciseBookPayDTO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * (AdvertisingCpaProductPackage)表服务实现类
 *
 * @author makejava
 * @since 2022-11-29 18:12:15
 */
@Slf4j
@Service("advertisingCpaProductPackageBiz")
public class AdvertisingCpaProductPackageBizImpl implements AdvertisingCpaProductPackageBiz {

    private static final Logger LOGGER = LoggerFactory.getLogger(AdvertisingCpaProductPackageBizImpl.class);

    @Autowired
    private AdvertisingCpaProductPackageDao advertisingCpaProductPackageDao;
    @Autowired
    private BmRegisterDao bmRegisterDao;
    @Autowired
    private AdvertisingCpaPaySettingBiz cpaPaySettingBiz;
    @Autowired
    private BmOptionDao bmOptionDao;
    @Autowired
    private BmRegisterItemDao bmRegisterItemDao;
    @Autowired
    private AdvertisingCpaPaySyncRecordBiz cpaPaySyncRecordBiz;

    @Override
    @ParamLog("通过ID查询单条数据")
    public AdvertisingCpaProductPackage getById(Long id) {
        return advertisingCpaProductPackageDao.getById(id);
    }

    @Override
    @ParamLog("查询多条数据")
    public PageBeanNew getList(Integer currentPage, Integer numPerPage) {
        PageBeanNew pageBeanNew = advertisingCpaProductPackageDao.listPageNew(new PageParam(currentPage, numPerPage), null, "getList");
        List recordList = pageBeanNew.getRecordList();
        if (ListUtils.isEmpty(recordList)){
            return pageBeanNew;
        }
        // 加载其它数据
        
        return pageBeanNew;
    }

    @Override
    @ParamLog("新增")
    public Long insert(AdvertisingCpaProductPackage advertisingCpaProductPackage) {
        advertisingCpaProductPackageDao.insert(advertisingCpaProductPackage);
        return advertisingCpaProductPackage.getId();
    }

    @Override
    @ParamLog("修改")
    public void update(AdvertisingCpaProductPackage advertisingCpaProductPackage) {
        if(advertisingCpaProductPackage == null || !NumberUtil.isNumber(advertisingCpaProductPackage.getId())){
            throw BizException.PARAM_IS_NULL;
        }
        advertisingCpaProductPackageDao.update(advertisingCpaProductPackage);
    }

    @Override
    @ParamLog("删除")
    public void deleteById(Long id) {
        advertisingCpaProductPackageDao.deleteById(id);
    }

    @Override
    public Map<String, AdvertisingCpaProductPackage> mapAll () {
        return Optional.ofNullable(advertisingCpaProductPackageDao.listBy(null))
                .orElse(CollUtil.toList())
                .stream().collect(Collectors.toMap(x -> x.getProductPackageId(), Function.identity()));
    }

    public void handlerCreateProductPackage(ExerciseBookPayDTO payDTO) {
        if (StrUtil.isBlank(payDTO.getSnapshotParam())) {
            log.warn("无法同步订单信息到第三方；payDTO：{}", JSONUtil.toJsonStr(payDTO));
            return;
        }
        String msg = "【起礼科技】支付调用开始";
        AdvertisingCpaPaySyncRecord cpaPaySyncRecord = initCpaPaySyncRecord(payDTO.getOrderMainNum(), ApiActionCodeEnum.PAY.name(), msg);
        // 拿到用户的注册信息
        AdvertisingBmRegister bmRegister = bmRegisterDao.getById(payDTO.getBuyId());
        // 配置的支付权益信息
        AdvertisingCpaPaySetting cpaPaySetting = cpaPaySettingBiz.getById(bmRegister.getCpaPaySettingId());
        if (cpaPaySetting == null) {
            msg = "cpaPaySetting 为空，无法同步订单数据；";
            log.warn("{}payDTO：{}", msg, JSONUtil.toJsonStr(payDTO));
            cpaPaySyncMsgRecord(cpaPaySyncRecord, msg);
            return;
        }
        // 根据 权益包id 拿到第三方接口
        AdvertisingCpaProductPackage cpaProductPackage = advertisingCpaProductPackageDao.getByProductPackageId(cpaPaySetting.getProductPackageId());
        if (cpaProductPackage == null) {
            msg = "cpaProductPackage 为空，无法同步订单数据；";
            log.warn("{}payDTO：{}", msg, JSONUtil.toJsonStr(payDTO));
            cpaPaySyncMsgRecord(cpaPaySyncRecord, msg);
            return;
        }
        // 拿到用户手机
        /*Long mobilePhoneOptionId = bmOptionDao.getMobilePhoneOptionIdByCPA(bmRegister.getCpaId());
        String mobile = bmRegisterItemDao.getRegisterOptionValue(payDTO.getWechatUserId(), bmRegister.getId(), mobilePhoneOptionId);*/
        if (StrUtil.isBlank(payDTO.getPhoneNumber())) {
            msg = "未找到手机号，无法同步订单数据；";
            log.warn("{}payDTO：{}", msg, JSONUtil.toJsonStr(payDTO));
            cpaPaySyncMsgRecord(cpaPaySyncRecord, msg);
            return;
        }
        // 请求参数
        HashMap<String, Object> bodyMap = new HashMap<String, Object>() {{
            put("productPackageId", cpaProductPackage.getProductPackageId());
            put("mobile", payDTO.getPhoneNumber());
            put("orderId", payDTO.getOrderMainNum());
            put("payPrice", payDTO.getMoney().multiply(BigDecimal.valueOf(100)).intValue());
        }};
        QiLiShuSheApiHandler apiHandler = new QiLiShuSheApiHandler(cpaProductPackage.getAppId(), cpaProductPackage.getAppSecret(), cpaProductPackage.getApiDomain());
        QiLiShuSheApiHandler.ApiRequestResult apiRequestResult = apiHandler.post(cpaProductPackage.getApiMethodCreate(), bodyMap);
        // 更新第三方同步记录
        AdvertisingBmRegister updateRegister = new AdvertisingBmRegister();
        updateRegister.setId(bmRegister.getId());
        updateRegister.setPayStatusThird(apiRequestResult.getRunSuccess() ? PayStatusThirdSyncEnum.PAY_SYNC_SUCCESS.status : PayStatusThirdSyncEnum.PAY_SYNC_FAIL.status);
        bmRegisterDao.update(updateRegister);
        // 调用第三方记录
        cpaPaySyncApiRecord(apiRequestResult, cpaPaySyncRecord);
    }

    @Override
    public void handlerRefundProductPackage(RefundExerciseBookDTO refundDTO) {
        String msg = "【起礼科技】退款调用开始";
        AdvertisingCpaPaySyncRecord cpaPaySyncRecord = initCpaPaySyncRecord(refundDTO.getOrderMainNum(), ApiActionCodeEnum.REFUND.name(), msg);
        // 拿到用户的注册信息
        AdvertisingBmRegister bmRegister = bmRegisterDao.getById(refundDTO.getBuyId());
        // 配置的支付权益信息
        AdvertisingCpaPaySetting cpaPaySetting = cpaPaySettingBiz.getById(bmRegister.getCpaPaySettingId());
        if (cpaPaySetting == null) {
            msg = "cpaPaySetting 为空，无法同步退款订单数据；";
            log.warn("{}refundDTO：{}", msg, JSONUtil.toJsonStr(refundDTO));
            cpaPaySyncMsgRecord(cpaPaySyncRecord, msg);
            return;
        }
        // 根据 权益包id 拿到第三方接口
        AdvertisingCpaProductPackage cpaProductPackage = advertisingCpaProductPackageDao.getByProductPackageId(cpaPaySetting.getProductPackageId());
        if (cpaProductPackage == null) {
            msg = "cpaProductPackage 为空，无法同步退款订单数据；";
            log.warn("{}refundDTO：{}", msg, JSONUtil.toJsonStr(refundDTO));
            cpaPaySyncMsgRecord(cpaPaySyncRecord, msg);
            return;
        }
        // 拿到用户手机
        Long mobilePhoneOptionId = bmOptionDao.getMobilePhoneOptionIdByCPA(bmRegister.getCpaId());
        String mobile = bmRegisterItemDao.getRegisterOptionValue(refundDTO.getWechatUserId(), bmRegister.getId(), mobilePhoneOptionId);
        if (StrUtil.isBlank(mobile)) {
            msg = "未找到手机号，无法同步退款订单数据；";
            log.warn("{}refundDTO：{}", msg, JSONUtil.toJsonStr(refundDTO));
            cpaPaySyncMsgRecord(cpaPaySyncRecord, msg);
            return;
        }

        // 请求参数
        HashMap<String, Object> bodyMap = new HashMap<String, Object>() {{
            put("productPackageId", cpaProductPackage.getProductPackageId());
            put("mobile", mobile);
            put("orderId", refundDTO.getOrderMainNum());
            put("refundPrice", refundDTO.getRefundFee().multiply(BigDecimal.valueOf(100)).intValue());
        }};
        QiLiShuSheApiHandler apiHandler = new QiLiShuSheApiHandler(cpaProductPackage.getAppId(), cpaProductPackage.getAppSecret(), cpaProductPackage.getApiDomain());
        QiLiShuSheApiHandler.ApiRequestResult apiRequestResult = apiHandler.post(cpaProductPackage.getApiMethodRefund(), bodyMap);
        // 更新第三方同步记录
        AdvertisingBmRegister updateRegister = new AdvertisingBmRegister();
        updateRegister.setId(bmRegister.getId());
        updateRegister.setPayStatusThird(apiRequestResult.getRunSuccess() ? PayStatusThirdSyncEnum.REFUND_SYNC_SUCCESS.status : PayStatusThirdSyncEnum.REFUND_SYNC_FAIL.status);
        bmRegisterDao.update(updateRegister);
        // 调用第三方记录
        cpaPaySyncApiRecord(apiRequestResult, cpaPaySyncRecord);
    }

    private void cpaPaySyncMsgRecord(AdvertisingCpaPaySyncRecord cpaPaySyncRecord, String msg) {
        cpaPaySyncRecord.setUpdateTime(new Date());
        cpaPaySyncRecord.setMsg(msg);
        cpaPaySyncRecordBiz.update(cpaPaySyncRecord);
    }

    private AdvertisingCpaPaySyncRecord initCpaPaySyncRecord(String orderMainNum, String name, String msg) {
        AdvertisingCpaPaySyncRecord cpaPaySyncRecord = new AdvertisingCpaPaySyncRecord();
        cpaPaySyncRecord.setOrderNum(orderMainNum);
        cpaPaySyncRecord.setActionCode(name);
        cpaPaySyncRecord.setCreateTime(new Date());
        cpaPaySyncRecord.setUpdateTime(new Date());
        cpaPaySyncRecord.setMsg(msg);
        cpaPaySyncRecordBiz.insert(cpaPaySyncRecord);
        return cpaPaySyncRecord;
    }

    private void cpaPaySyncApiRecord(QiLiShuSheApiHandler.ApiRequestResult apiRequestResult, AdvertisingCpaPaySyncRecord cpaPaySyncRecord) {
        cpaPaySyncRecord.setApiUrl(apiRequestResult.getApiUrl());
        cpaPaySyncRecord.setApiBody(apiRequestResult.getApiBody());
        cpaPaySyncRecord.setApiResult(apiRequestResult.getApiResult());
        cpaPaySyncRecord.setUpdateTime(new Date());
        cpaPaySyncRecordBiz.update(cpaPaySyncRecord);
    }


    public void testQiLiOrder() {
        String productPackageId = "6368e407e6850b26cb86a7d9";

        // 根据 权益包id 拿到第三方接口
        AdvertisingCpaProductPackage cpaProductPackage = advertisingCpaProductPackageDao.getByProductPackageId(productPackageId);
        if (cpaProductPackage == null) {
            log.warn("cpaProductPackage 为空，无法同步订单数据；payDTO：{}", productPackageId);
            return;
        }

        // 请求参数
        HashMap<String, Object> bodyMap = new HashMap<String, Object>() {{
            put("productPackageId", productPackageId);
            put("mobile", "18616941348");
            put("orderId", "2022113010001");
            put("payPrice", 1);
        }};
        QiLiShuSheApiHandler apiHandler = new QiLiShuSheApiHandler(cpaProductPackage.getAppId(), cpaProductPackage.getAppSecret(), cpaProductPackage.getApiDomain());
        apiHandler.post(cpaProductPackage.getApiMethodCreate(), bodyMap);
    }

    public void testQiLiRefundOrder() {
        String productPackageId = "6368e407e6850b26cb86a7d9";

        // 根据 权益包id 拿到第三方接口
        AdvertisingCpaProductPackage cpaProductPackage = advertisingCpaProductPackageDao.getByProductPackageId(productPackageId);
        if (cpaProductPackage == null) {
            log.warn("cpaProductPackage 为空，无法同步订单数据；payDTO：{}", productPackageId);
            return;
        }

        // 请求参数
        HashMap<String, Object> bodyMap = new HashMap<String, Object>() {{
            put("productPackageId", productPackageId);
            put("mobile", "18616941345");
            put("orderId", "100000");
            put("refundPrice", 1);
        }};
        QiLiShuSheApiHandler apiHandler = new QiLiShuSheApiHandler(cpaProductPackage.getAppId(), cpaProductPackage.getAppSecret(), cpaProductPackage.getApiDomain());
        apiHandler.post(cpaProductPackage.getApiMethodRefund(), bodyMap);
    }
}
