package com.jeequan.jeepay.mgr.ctrl.bill;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.CheckChannelBill;
import com.jeequan.jeepay.db.entity.CheckDiff;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.db.entity.RefundOrder;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.service.PayOrderProcessService;
import com.jeequan.jeepay.service.impl.CheckDiffService;
import com.jeequan.jeepay.service.impl.PayOrderService;
import com.jeequan.jeepay.service.impl.RefundOrderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 账单差异管理类
 *
 * @author zx
 *
 * @date 2021-06-07 07:15
 */
@RestController
@RequestMapping("/api/check/diff")
public class CheckDiffController extends CommonCtrl {

    @Autowired private CheckDiffService checkDiffService;
    @Autowired private PayOrderService payOrderService;
    @Autowired private RefundOrderService refundOrderService;
    @Autowired private PayOrderProcessService payOrderProcessService;

    /**
     * @author: zx
     * @describe: 列表
     */
    @PreAuthorize("hasAuthority('ENT_CHECK_DIFF_LIST')")
    @GetMapping
    public ApiRes list() {
        CheckDiff checkDiff = getObject(CheckDiff.class);

        // 时间范围条件
        Date[] dateRange = checkDiff.buildQueryDateRange();

        IPage<CheckDiff> pages = checkDiffService.page(getIPage(true), CheckDiff.gw()
                .eq(StringUtils.isNotBlank(checkDiff.getBatchNo()), CheckDiff::getBatchNo, checkDiff.getBatchNo())
                .eq(StringUtils.isNotBlank(checkDiff.getIfCode()), CheckDiff::getIfCode, checkDiff.getIfCode())
                .eq(StringUtils.isNotBlank(checkDiff.getBillType()), CheckDiff::getBillType, checkDiff.getBillType())
                .eq(StringUtils.isNotBlank(checkDiff.getDiffType()), CheckDiff::getDiffType, checkDiff.getDiffType())
                .eq(checkDiff.getHandleState() != null, CheckDiff::getHandleState, checkDiff.getHandleState())
                .eq(StringUtils.isNotBlank(checkDiff.getOrderId()), CheckDiff::getOrderId, checkDiff.getOrderId())
                .eq(StringUtils.isNotBlank(checkDiff.getMchNo()), CheckDiff::getMchNo, checkDiff.getMchNo())
                .ge(dateRange[0] != null, CheckDiff::getBillDate, dateRange[0])
                .le(dateRange[1] != null, CheckDiff::getBillDate, dateRange[1])
                .orderByDesc(CheckDiff::getCreatedAt)
        );

        // 查询支付订单 退款订单，是否有需要补单操作的
        List<CheckDiff> checkDiffs = pages.getRecords();
        if(CollUtil.isNotEmpty(checkDiffs)) {
            List<String> payOrderIdList = pages.getRecords().stream()
                    .filter(item -> item.getDiffType().equals(CheckDiff.DIFF_TYPE_CHANNEL) && item.getBillType().equals(CheckChannelBill.BILL_TYPE_PAY))
                    .map(CheckDiff::getOrderId).collect(Collectors.toList());
            List<PayOrder> payOrderList = null;
            if (CollUtil.isNotEmpty(payOrderIdList)) {
                payOrderList = payOrderService.list(PayOrder.gw().in(PayOrder::getPayOrderId, payOrderIdList).ne(PayOrder::getState, PayOrder.STATE_SUCCESS));
            }

            List<String> refundOrderIdList = checkDiffs.stream()
                    .filter(item -> item.getDiffType().equals(CheckDiff.DIFF_TYPE_CHANNEL) && item.getBillType().equals(CheckChannelBill.BILL_TYPE_REFUND))
                    .map(CheckDiff::getOrderId).collect(Collectors.toList());
            List<RefundOrder> refundOrderList = null;
            if (CollUtil.isNotEmpty(refundOrderIdList)) {
                refundOrderList = refundOrderService.list(RefundOrder.gw().in(RefundOrder::getRefundOrderId, refundOrderIdList).ne(RefundOrder::getState, RefundOrder.STATE_SUCCESS));
            }

            for (CheckDiff checkDiff1: checkDiffs) {
                if (CollUtil.isNotEmpty(payOrderList)) {
                    for (PayOrder payOrder: payOrderList) {
                        if (checkDiff1.getOrderId().equals(payOrder.getPayOrderId()) && (payOrder.getState() == PayOrder.STATE_ING || payOrder.getState() == PayOrder.STATE_CLOSED)) {
                            checkDiff1.addExt("isNeedReissue", 1);
                        }
                    }
                }

                if (CollUtil.isNotEmpty(refundOrderList)) {
                    for (RefundOrder refundOrder: refundOrderList) {
                        if (checkDiff1.getOrderId().equals(refundOrder.getRefundOrderId()) && (refundOrder.getState() == RefundOrder.STATE_ING || refundOrder.getState() == RefundOrder.STATE_CLOSED)) {
                            checkDiff1.addExt("isNeedReissue", 1);
                        }
                    }
                }
            }
        }

        setIfName(pages.getRecords());

        return ApiRes.page(pages);
    }

    /**
     * @author: zx
     * @describe: 详情
     */
    @PreAuthorize("hasAuthority('ENT_CHECK_DIFF_VIEW')")
    @GetMapping("/{id}")
    public ApiRes detail(@PathVariable("id") Long id) {
        CheckDiff checkDiff = checkDiffService.getById(id);
        if (checkDiff == null) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }

        if (getValByte("isQueryOrderInfo") != null && getValByte("isQueryOrderInfo") == 1 && StringUtils.isNotBlank(checkDiff.getOrderId())) {
            JSONObject orderJSON = new JSONObject();

            if (StringUtils.equals(checkDiff.getBillType(), CheckChannelBill.BILL_TYPE_PAY)) {
                PayOrder payOrder = payOrderService.getById(checkDiff.getOrderId());
                if (payOrder != null) {
                    orderJSON.put("orderId", payOrder.getPayOrderId());
                    orderJSON.put("state", payOrder.getState());
                    orderJSON.put("amount", payOrder.getAmount());
                    orderJSON.put("feeAmount", payOrder.getMchFeeAmount());
                    orderJSON.put("channelOrderNo", payOrder.getChannelOrderNo());
                    orderJSON.put("successTime", payOrder.getSuccessTime());
                    checkDiff.addExt("localOrder", orderJSON);
                }
            }else if (StringUtils.equals(checkDiff.getBillType(), CheckChannelBill.BILL_TYPE_REFUND)) {
                RefundOrder refundOrder = refundOrderService.getById(checkDiff.getOrderId());
                if (refundOrder != null) {
                    orderJSON.put("orderId", refundOrder.getRefundOrderId());
                    orderJSON.put("state", refundOrder.getState());
                    orderJSON.put("amount", refundOrder.getRefundAmount());
                    orderJSON.put("channelOrderNo", refundOrder.getChannelOrderNo());
                    orderJSON.put("successTime", refundOrder.getSuccessTime());
                    checkDiff.addExt("localOrder", orderJSON);
                }
            }
        }

        return ApiRes.ok(checkDiff);
    }

    /**
     * @author: zx
     * @describe: 忽略差异
     */
    @PreAuthorize("hasAuthority('ENT_CHECK_DIFF_IGNORE')")
    @PutMapping("/ignore/{id}")
    public ApiRes ignore(@PathVariable("id") Long id) {
        String ignoreType = getValStringRequired("ignoreType"); // single-单挑忽略  filter-根据筛选条件忽略
        CheckDiff checkDiff = getObject(CheckDiff.class);

        checkDiffService.ignoreDiff(id, ignoreType, checkDiff, getCurrentUser().getSysUser());

        return ApiRes.ok();
    }

    /**
     * @author: zx
     * @describe: 差异订单 补单
     */
    @PreAuthorize("hasAuthority('ENT_CHECK_DIFF_REISSUE')")
    @PutMapping("/reissue/{id}")
    public ApiRes reissue(@PathVariable("id") Long id) {
        CheckDiff dbRecord = checkDiffService.getById(id);
        if (dbRecord == null || (CheckDiff.HANDLE_STATE_WAITING == dbRecord.getHandleState() && CheckDiff.HANDLE_STATE_HANG_UP == dbRecord.getHandleState())) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }

        checkDiffService.reissue(dbRecord, getCurrentUser().getSysUser());

        // 更新订单状态为支付中
        if (StringUtils.isNotBlank(dbRecord.getOrderId())) {
            // 支付订单
            if (StringUtils.equals(dbRecord.getBillType(), CheckChannelBill.BILL_TYPE_PAY)) {
                PayOrder dbPayOrder = payOrderService.getById(dbRecord.getOrderId());
                if (dbPayOrder != null) {
                    payOrderProcessService.confirmSuccess(dbRecord.getOrderId(), null);
                }
            }else if (StringUtils.equals(dbRecord.getBillType(), CheckChannelBill.BILL_TYPE_REFUND)) {

            }
        }

        return ApiRes.ok();
    }

}
