package com.younike.system.task;

import com.alibaba.fastjson.JSON;
import com.younike.common.utils.id.IDGenerate;
import com.younike.system.domain.Order;
import com.younike.system.domain.ProfitSharingRecord;
import com.younike.system.domain.vo.OrderPaymentVO;
import com.younike.system.service.IOrderService;
import com.younike.system.service.IProfitSharingRecordService;
import com.younike.wxpay.params.ProfitSharingParams;
import com.younike.wxpay.params.Receiver;
import com.younike.wxpay.responses.ProfitSharingResponse;
import com.younike.wxpay.responses.QuerySharingResponse;
import com.younike.wxpay.service.impl.ProfitSharingServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 微信分账相关任务
 *
 * @author chenpengfei
 */
@Component("wxProfitSharingTask")
@Log4j2
public class ProfitSharingTask {

    /**
     * 分账完成
     */
    public static final String FINISHED = "FINISHED";
    public static final String MERCHANT_ID = "MERCHANT_ID";
    public static final String PLATFORM_DESCRIPTION = "平台抽成";
    public static final String RECOMMENDER_DESCRIPTION = "推广抽成";

    @Autowired
    private ProfitSharingServiceImpl profitSharingService;

    @Autowired
    private IProfitSharingRecordService profitSharingRecordService;

    @Autowired
    private IOrderService orderService;

    /**
     * 执行分账
     *
     * 执行时间：每天凌晨1点
     * 执行条件：7天前已完成订单未结算订单
     */
    public void profitSharing(){
        LocalDate today = LocalDate.now();
//        Date settleDate = Date.from(today.minusDays(7).atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date settleDate = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
        log.info("结算截止时间 " + DateUtils.formatDate(settleDate, "yyyy-MM-dd HH:mm:ss"));
        // 查询7天前未执行结算操作的订单列表
        List<OrderPaymentVO> orders = orderService.selectPreProfitSharingOrders(settleDate);

        for (OrderPaymentVO order : orders) {
            BigDecimal totalAmount = order.getTotalAmount();
            BigDecimal shopAmount = order.getShopAmount();
            BigDecimal recommenderAmount = order.getRecommenderAmount();
            BigDecimal addAmount = order.getAddAmount() == null ? BigDecimal.ZERO : order.getAddAmount();
            BigDecimal addShopAmount = order.getAddShopAmount() == null ? BigDecimal.ZERO : order.getAddShopAmount();
            BigDecimal addRecommenderAmount = order.getAddRecommenderAmount() == null ? BigDecimal.ZERO : order.getAddRecommenderAmount();
            BigDecimal platformAmount;
            List<Receiver> receivers = new ArrayList<>();
            if (order.getMerchantNo() == null) {
                log.error("商户No 不能为空！" + JSON.toJSONString(order));
                continue;
            }
            if (shopAmount == null) {
                log.error("店铺可得 不能为空！" + JSON.toJSONString(order));
                continue;
            }
            if (totalAmount == null) {
                log.error("实付金额 不能为空！" + JSON.toJSONString(order));
                continue;
            }
            if (order.getTransactionId() == null) {
                log.error("微信订单号 不能为空");
                continue;
            }
            if (recommenderAmount == null) {
                platformAmount = totalAmount.subtract(shopAmount).subtract(addAmount);
            } else {
                platformAmount = totalAmount.subtract(shopAmount).subtract(recommenderAmount).subtract(addAmount);
                recommenderAmount = recommenderAmount.subtract(addRecommenderAmount);
            }

            Receiver platform = Receiver.builder()
                    .type(MERCHANT_ID)
                    .account(order.getMerchantNo())
                    .amount(platformAmount.multiply(BigDecimal.valueOf(100)).intValue())
                    .description(PLATFORM_DESCRIPTION)
                    .build();
            receivers.add(platform);
            if (recommenderAmount != null) {
                Receiver recommender = Receiver.builder()
                        .type(MERCHANT_ID)
                        .account(order.getAgentWxAccount())
                        .amount(recommenderAmount.multiply(BigDecimal.valueOf(100)).intValue())
                        .description(RECOMMENDER_DESCRIPTION)
                        .build();
                receivers.add(recommender);
            }
            ProfitSharingParams params = ProfitSharingParams.builder()
                    .sub_mchid(order.getMerchantNo())
                    .transaction_id(order.getTransactionId())
                    .out_trade_no(IDGenerate.nextId())
                    .receivers(receivers)
                    .unfreeze_unsplit(true)
                    .build();
            // 执行原订单金额分账
            executeProfitSharing(params, order.getOrderId());

           if (order.getAddAmount() != null || order.getMaintenanceAmount() != null) {
               // 存在追加服务分账 or 存在维修费用服务分账
               params.setTransaction_id(order.getAddTransactionId() != null ? order.getAddTransactionId() : order.getManTransactionId());
               params.setOut_trade_no(IDGenerate.nextId());
               totalAmount = order.getAddAmount() != null ? order.getAddAmount() : order.getMaintenanceAmount();
               if (order.getAddRecommenderAmount() == null) {
                   platformAmount = totalAmount.subtract(order.getAddShopAmount());
               } else {
                   platformAmount = totalAmount.subtract(order.getAddShopAmount()).subtract(order.getAddRecommenderAmount());
               }
               params.getReceivers().get(0).setAmount(platformAmount.multiply(BigDecimal.valueOf(100)).intValue());
               if (params.getReceivers().size() == 2) {
                   params.getReceivers().get(1).setAmount(order.getAddRecommenderAmount().multiply(BigDecimal.valueOf(100)).intValue());
               }
               // 执行追加服务/维修费分账
               executeProfitSharing(params, order.getOrderId());
           }
        }
    }

    /**
     * 执行分账
     *
     * @param params 分账参数
     * @param orderId 订单ID
     */
    private void executeProfitSharing(ProfitSharingParams params, Long orderId){
        ProfitSharingResponse response = profitSharingService.profitSharing(params);
        ProfitSharingRecord record = new ProfitSharingRecord();
        record.setOutOrderNo(params.getOut_trade_no());
        record.setOrderId(orderId);
        record.setSubMchid(params.getSub_mchid());
        record.setTransactionId(params.getTransaction_id());

        // 分账方
        List<Receiver> receivers = params.getReceivers();
        // 平台
        record.setPlatformAccount(receivers.get(0).getAccount());
        record.setPlatformAmount(receivers.get(0).getAmount());
        // 推荐人
        if (receivers.size() == 2) {
            record.setAgentAccount(receivers.get(1).getAccount());
            record.setAgentAmount(receivers.get(1).getAmount());
        }
        // 是否分账结束
        if (FINISHED.equals(response.getState())) {
            record.setStatus(1);
            // 分账成功，将订单结算状态修改为已结算
            Order order = new Order();
            order.setOrderId(orderId);
            order.setIsSettle(1);
            orderService.updateOrder(order);
        } else {
            record.setStatus(0);
        }
        record.setResult(JSON.toJSONString(response));
        // 插入分账记录
        profitSharingRecordService.insertProfitSharingRecord(record);
    }

    /**
     * 查询微信分账结果
     *
     * 执行时间：每天凌晨3点
     * 执行条件：分账记录中未完成的分账记录
     */
    public void queryProfitSharing(){
        ProfitSharingRecord profitSharingRecord = new ProfitSharingRecord();
        profitSharingRecord.setStatus(0);
        List<ProfitSharingRecord> profitSharingRecords = profitSharingRecordService.selectProfitSharingRecordList(profitSharingRecord);
        for (ProfitSharingRecord record : profitSharingRecords) {
            QuerySharingResponse response = profitSharingService.querySharing(record.getOutOrderNo(), record.getTransactionId(), record.getSubMchid());
            if (FINISHED.equals(response.getState())) {
                record.setStatus(1);
                record.setQueryResult(JSON.toJSONString(response));
                profitSharingRecordService.updateProfitSharingRecord(record);
            } else {
                // 分账异常
                log.error("分账异常,异常分账 " + record.getId());
            }
        }
    }
}
