package com.heyu.api.controller.mm;


import cn.felord.payment.wechat.enumeration.DetailStatus;
import com.alibaba.fastjson.JSON;
import com.heyu.api.alibaba.request.mm.order.ProfitSharingDTO;
import com.heyu.api.alibaba.request.mm.order.resp.VvAdminAgreeDrawRequest;
import com.heyu.api.alibaba.request.mm.order.resp.VvAdminRejectDrawRequest;
import com.heyu.api.common.annotation.Describe;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.dao.vv.VvBuyerDao;
import com.heyu.api.data.dao.vv.VvPromoterTradeOrderAwardDao;
import com.heyu.api.data.dao.vv.VvPromoterTradeOrderLineAwardDao;
import com.heyu.api.data.dao.vv.VvTradeOrderDao;
import com.heyu.api.data.entity.vv.VvBuyerEntity;
import com.heyu.api.data.entity.vv.VvPromoterTradeOrderAwardEntity;
import com.heyu.api.data.entity.vv.VvPromoterTradeOrderLineAwardEntity;
import com.heyu.api.data.entity.vv.VvTradeOrderEntity;
import com.heyu.api.data.enums.ActionEnums;
import com.heyu.api.data.enums.AwardStatusEnums;
import com.heyu.api.data.service.impl.AbstractDrawAction;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.SanUtils;
import com.heyu.api.jsapi.JsapiPrepay;
import com.heyu.api.jsapi.dto.profit.sharing.OrderReceiverDetail;
import com.heyu.api.jsapi.dto.profit.sharing.OrdersEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/mm/draw")
public class AdminDrawController {


    @Autowired
    private VvPromoterTradeOrderAwardDao vvPromoterTradeOrderAwardDao;


    @Autowired
    private VvBuyerDao vvBuyerDao;


    @Autowired
    private VvPromoterTradeOrderLineAwardDao vvPromoterTradeOrderLineAwardDao;


    @Autowired
    private JsapiPrepay jsapiPrepay;

    @Autowired
    private VvTradeOrderDao vvTradeOrderDao;


    // http://localhost:8888/mm/draw/agree
    @Describe("同意提现")
    @RequestMapping("/agree")
    public R agree(@RequestBody VvAdminAgreeDrawRequest request) {
        List<VvPromoterTradeOrderAwardEntity>
                vvPromoterTradeOrderAwardEntityList = vvPromoterTradeOrderAwardDao.selectVvPromoterTradeOrderAwardByPromoterId(request.getPromoterTradeOrderIdList());
        for (VvPromoterTradeOrderAwardEntity vvPromoterTradeOrderAwardEntity : vvPromoterTradeOrderAwardEntityList) {
            if (AbstractDrawAction.checkFailed(vvPromoterTradeOrderAwardEntity, false, ActionEnums.Admin_Seller_Agree_Draw)) {
                return R.error("提现状态不对");
            }
        }

        List<Long> tradeOrderIdList = SanUtils.getFieldList(vvPromoterTradeOrderAwardEntityList, VvPromoterTradeOrderAwardEntity::getTradeOrderId);
        List<VvTradeOrderEntity> vvTradeOrderEntities = vvTradeOrderDao.selectVvTradeOrderByTradeOrderIds(tradeOrderIdList);
        Map<Long, VvTradeOrderEntity> vvTradeOrderEntityMap = SanUtils.groupByFiled2Map(vvTradeOrderEntities, VvTradeOrderEntity::getId);

        List<Long> buyerIdList = SanUtils.getFieldList(vvPromoterTradeOrderAwardEntityList, VvPromoterTradeOrderAwardEntity::getPromoterBuyerId);
        List<VvBuyerEntity> vvBuyerEntities = vvBuyerDao.selectVvBuyerByIdList(buyerIdList);
        Map<Long, VvBuyerEntity> vvBuyerEntityMap = SanUtils.groupByFiled2Map(vvBuyerEntities, VvBuyerEntity::getId);

        Map<Long, String> oldIdStatusMap = SanUtils.groupByFiledFiled2Map(vvPromoterTradeOrderAwardEntityList, VvPromoterTradeOrderAwardEntity::getId, VvPromoterTradeOrderAwardEntity::getStatus);

        for (VvPromoterTradeOrderAwardEntity vvPromoterTradeOrderAwardEntity : vvPromoterTradeOrderAwardEntityList) {
            vvPromoterTradeOrderAwardEntity.setStatus(AwardStatusEnums.seller_agree_draw.getStatus());
            vvPromoterTradeOrderAwardEntity.setGmtAgree(new Date());
            vvPromoterTradeOrderAwardDao.updateVvPromoterTradeOrderAwardById(vvPromoterTradeOrderAwardEntity);
        }

        List<VvPromoterTradeOrderLineAwardEntity> vvPromoterTradeOrderLineAwardEntities = vvPromoterTradeOrderLineAwardDao
                .selectVvPromoterTradeOrderLineAwardByPromoterIdList(request.getPromoterTradeOrderIdList());

        for (VvPromoterTradeOrderLineAwardEntity vvPromoterTradeOrderLineAwardEntity : vvPromoterTradeOrderLineAwardEntities) {
            vvPromoterTradeOrderLineAwardEntity.setStatus(AwardStatusEnums.seller_agree_draw.getStatus());
            vvPromoterTradeOrderLineAwardEntity.setGmtAgree(new Date());
            vvPromoterTradeOrderLineAwardDao.updateVvPromoterTradeOrderLineAwardById(vvPromoterTradeOrderLineAwardEntity);
        }

        Map<Long, List<VvPromoterTradeOrderLineAwardEntity>> vvPromoterTradeOrderLineAwardEntityMap =
                SanUtils.groupByFiled2MapList(vvPromoterTradeOrderLineAwardEntities, VvPromoterTradeOrderLineAwardEntity::getPromoterTradeOrderAwardId);

        Map<Long, List<VvPromoterTradeOrderAwardEntity>> vvPromoterTradeOrderAwardMap =
                SanUtils.groupByFiled2MapList(vvPromoterTradeOrderAwardEntityList, VvPromoterTradeOrderAwardEntity::getTradeOrderId);

        Map<Long, VvPromoterTradeOrderAwardEntity> vvPromoterTradeOrderAwardMapping =
                SanUtils.groupByFiled2Map(vvPromoterTradeOrderAwardEntityList, VvPromoterTradeOrderAwardEntity::getId);


        for (Map.Entry<Long, List<VvPromoterTradeOrderAwardEntity>> entry : vvPromoterTradeOrderAwardMap.entrySet()) {
            List<VvPromoterTradeOrderAwardEntity> vvPromoterTradeOrderAwardEntities = entry.getValue();
            VvTradeOrderEntity vvTradeOrderEntity = vvTradeOrderEntityMap.get(entry.getKey());
            List<ProfitSharingDTO> profitSharingDTOList = new ArrayList<>();
            for (VvPromoterTradeOrderAwardEntity vvPromoterTradeOrderAwardEntity : vvPromoterTradeOrderAwardEntities) {
                ProfitSharingDTO profitSharingDTO = new ProfitSharingDTO();
                VvBuyerEntity vvBuyerEntity = vvBuyerEntityMap.get(vvPromoterTradeOrderAwardEntity.getPromoterBuyerId());
                profitSharingDTO.setAwardAmount(vvPromoterTradeOrderAwardEntity.getAwardAmount());
                profitSharingDTO.setOpenid(vvBuyerEntity.getOpenid());
                profitSharingDTO.setBuyerName(vvBuyerEntity.getBuyerName());
                profitSharingDTO.setPromoterTradeOrderAwardId(vvPromoterTradeOrderAwardEntity.getId());
                profitSharingDTOList.add(profitSharingDTO);
            }

            /***
             * https://pay.weixin.qq.com/doc/v3/merchant/4012525210
             */
            OrdersEntity ordersEntity = jsapiPrepay.profitSharing(
                    vvTradeOrderEntity.getTransactionId(),
                    ApiConstants.PS + vvTradeOrderEntity.getId(),
                    profitSharingDTOList
            );
            log.info("AdminDrawController agreee :{}", JSON.toJSONString(ordersEntity));
            Map<String, ProfitSharingDTO> profitSharingDTOMap = SanUtils.groupByFiled2Map(profitSharingDTOList, ProfitSharingDTO::getOpenid);
            if (ordersEntity != null) {
                List<OrderReceiverDetail> orderReceiverDetails = ordersEntity.receivers;
                for (OrderReceiverDetail orderReceiverDetail : orderReceiverDetails) {
                    ProfitSharingDTO profitSharingDTO = profitSharingDTOMap.get(orderReceiverDetail.account);
                    VvPromoterTradeOrderAwardEntity vvPromoterTradeOrderAwardEntity = vvPromoterTradeOrderAwardMapping.get(profitSharingDTO.getPromoterTradeOrderAwardId());
                    vvPromoterTradeOrderAwardEntity.setProfitSharingResult(JSON.toJSONString(ordersEntity));
                    String status = AwardStatusEnums.draw_pending.getStatus();
                    DetailStatus detailStatus = orderReceiverDetail.result;
                    if (detailStatus == DetailStatus.SUCCESS) {
                        status = AwardStatusEnums.draw_success.getStatus();
                        vvPromoterTradeOrderAwardEntity.setGmtDrawSuccess(new Date());


                    } else if (detailStatus == DetailStatus.FAIL) {
                        status = AwardStatusEnums.draw_failed.getStatus();
                        vvPromoterTradeOrderAwardEntity.setProfitSharingFailReason(orderReceiverDetail.failReason + "");
                        vvPromoterTradeOrderAwardEntity.setGmtDrawFailed(new Date());
                    }
                    vvPromoterTradeOrderAwardEntity.setStatus(status);
                    vvPromoterTradeOrderLineAwardEntityMap.get(profitSharingDTO.getPromoterTradeOrderAwardId());

                    String oldStatus = oldIdStatusMap.get(vvPromoterTradeOrderAwardEntity.getId());

                    if (AwardStatusEnums.draw_failed.getStatus().equals(status)) {
                        if (AwardStatusEnums.arrive.getStatus().equals(oldStatus)) {
                            vvBuyerDao.updateVvBuyerByIdPromoterDrawCashFailedAmountPromoterArriveAccountAmount(
                                    vvPromoterTradeOrderAwardEntity.getAwardAmount()
                                    , vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                                    vvPromoterTradeOrderAwardEntity.getId());

                        } else if (AwardStatusEnums.apply_draw.getStatus().equals(oldStatus)) {
                            vvBuyerDao.updateVvBuyerByIdPromoterDrawCashFailedAmountPromoterApplyDrawCashAmount(
                                    vvPromoterTradeOrderAwardEntity.getAwardAmount()
                                    , vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                                    vvPromoterTradeOrderAwardEntity.getId());
                        }
                    } else if (AwardStatusEnums.draw_success.getStatus().equals(status)) {
                        if (AwardStatusEnums.arrive.getStatus().equals(oldStatus)) {
                            vvBuyerDao.updateVvBuyerByIdPromoterDrawCashSuccessAmountPromoterArriveAccountAmount(
                                    vvPromoterTradeOrderAwardEntity.getAwardAmount()
                                    , vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                                    vvPromoterTradeOrderAwardEntity.getId());
                        } else if (AwardStatusEnums.apply_draw.getStatus().equals(oldStatus)) {
                            vvBuyerDao.updateVvBuyerByIdPromoterDrawCashSuccessAmountPromoterApplyDrawCashAmount(
                                    vvPromoterTradeOrderAwardEntity.getAwardAmount()
                                    , vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                                    vvPromoterTradeOrderAwardEntity.getId());
                        }
                    }

                    List<VvPromoterTradeOrderLineAwardEntity> vvPromoterTradeOrderLineAwardEntityList =
                            vvPromoterTradeOrderLineAwardEntityMap.get(profitSharingDTO.getPromoterTradeOrderAwardId());
                    for (VvPromoterTradeOrderLineAwardEntity vvPromoterTradeOrderLineAwardEntity : vvPromoterTradeOrderLineAwardEntityList) {
                        vvPromoterTradeOrderLineAwardEntity.setStatus(status);
                        if (AwardStatusEnums.draw_failed.getStatus().equals(status)) {
                            vvPromoterTradeOrderLineAwardEntity.setGmtDrawSuccess(new Date());
                        } else if (AwardStatusEnums.draw_success.getStatus().equals(status)) {
                            vvPromoterTradeOrderLineAwardEntity.setGmtDrawFailed(new Date());
                        }

                        vvPromoterTradeOrderLineAwardDao.updateVvPromoterTradeOrderLineAwardById(vvPromoterTradeOrderLineAwardEntity);
                    }
                }
            }
        }
        return R.ok();
    }


    // http://localhost:8888/mm/draw/reject
    @Describe("拒绝提现")
    @RequestMapping("/reject")
    public R reject(@RequestBody VvAdminRejectDrawRequest request) {
        List<VvPromoterTradeOrderAwardEntity>
                vvPromoterTradeOrderAwardEntityList = vvPromoterTradeOrderAwardDao.selectVvPromoterTradeOrderAwardByPromoterId(request.getPromoterTradeOrderIdList());
        for (VvPromoterTradeOrderAwardEntity vvPromoterTradeOrderAwardEntity : vvPromoterTradeOrderAwardEntityList) {
            if (AbstractDrawAction.checkFailed(vvPromoterTradeOrderAwardEntity, false, ActionEnums.Admin_Seller_Reject_Draw)) {
                return R.error("提现状态不对");
            }
            String status = vvPromoterTradeOrderAwardEntity.getStatus();
            vvPromoterTradeOrderAwardEntity.setStatus(AwardStatusEnums.seller_reject_draw.getStatus());
            vvPromoterTradeOrderAwardEntity.setRejectReason(request.getReason());
            vvPromoterTradeOrderAwardEntity.setGmtReject(new Date());
            vvPromoterTradeOrderAwardDao.updateVvPromoterTradeOrderAwardById(vvPromoterTradeOrderAwardEntity);

            if (AwardStatusEnums.arrive.getStatus().equals(status)) {
                vvBuyerDao.updateVvBuyerByIdPromoterDrawCashFailedAmountPromoterArriveAccountAmount(
                        vvPromoterTradeOrderAwardEntity.getAwardAmount()
                        , vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                        vvPromoterTradeOrderAwardEntity.getId());
            } else if (AwardStatusEnums.apply_draw.getStatus().equals(status)) {
                vvBuyerDao.updateVvBuyerByIdPromoterDrawCashFailedAmountPromoterApplyDrawCashAmount(
                        vvPromoterTradeOrderAwardEntity.getAwardAmount()
                        , vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                        vvPromoterTradeOrderAwardEntity.getId());
            }
        }


        List<VvPromoterTradeOrderLineAwardEntity> vvPromoterTradeOrderLineAwardEntities = vvPromoterTradeOrderLineAwardDao
                .selectVvPromoterTradeOrderLineAwardByPromoterIdList(request.getPromoterTradeOrderIdList());
        for (VvPromoterTradeOrderLineAwardEntity vvPromoterTradeOrderLineAwardEntity : vvPromoterTradeOrderLineAwardEntities) {
            vvPromoterTradeOrderLineAwardEntity.setStatus(AwardStatusEnums.seller_reject_draw.getStatus());
            vvPromoterTradeOrderLineAwardEntity.setGmtReject(new Date());
            vvPromoterTradeOrderLineAwardEntity.setRejectReason(request.getReason());
            vvPromoterTradeOrderLineAwardDao.updateVvPromoterTradeOrderLineAwardById(vvPromoterTradeOrderLineAwardEntity);
        }
        return R.ok();
    }


}
