package com.jsowell.api.uniapp.customer;

import com.alibaba.fastjson2.JSON;
import com.jsowell.adapay.dto.BalancePaymentRequestDTO;
import com.jsowell.adapay.service.AdapayService;
import com.jsowell.common.annotation.Anonymous;
import com.jsowell.common.core.controller.BaseController;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.response.RestApiResponse;
import com.jsowell.common.util.DateUtils;
import com.jsowell.pile.domain.AdapayMemberAccount;
import com.jsowell.pile.domain.MemberPlateNumberRelation;
import com.jsowell.pile.domain.OrderBasicInfo;
import com.jsowell.pile.domain.ykcCommond.ReservationChargingCommand;
import com.jsowell.pile.dto.ApplyRefundDTO;
import com.jsowell.pile.dto.CarVinDTO;
import com.jsowell.pile.dto.QueryOrderDTO;
import com.jsowell.pile.dto.SettleOrderReportDTO;
import com.jsowell.pile.service.*;
import com.jsowell.pile.service.programlogic.AbstractProgramLogic;
import com.jsowell.pile.service.programlogic.ProgramLogicFactory;
import com.jsowell.pile.vo.uniapp.customer.MemberBalanceVO;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.service.OrderService;
import com.jsowell.service.TempService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 用于临时接口
 */
@Anonymous
@RestController
@RequestMapping("/temp")
public class TempController extends BaseController {

    @Autowired
    private TempService tempService;

    @Autowired
    private OrderBasicInfoService orderBasicInfoService;

    @Autowired
    private MemberPlateNumberRelationService memberPlateNumberRelationService;

    @Autowired
    private AdapayMemberAccountService adapayMemberAccountService;

    @Autowired
    private AdapayService adapayMemberService;

    @Autowired
    private MemberBasicInfoService memberBasicInfoService;

    @Autowired
    private PileStationInfoService pileStationInfoService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private SettleOrderReportService settleOrderReportService;

    @Autowired
    private PileMerchantInfoService pileMerchantInfoService;

    @Autowired
    private PileRemoteService pileRemoteService;

    /**
     * 预约充电测试
     * http://localhost:8080/temp/reservedChargingTest
     */
    @PostMapping("reservedChargingTest")
    public RestApiResponse<?> reservedChargingTest(@RequestBody ReservationChargingCommand command) {
        logger.info("发送预约充电指令, command:{}", JSON.toJSONString(command));
        RestApiResponse<?> response = null;
        try {
            // 发送预约充电指令
            pileRemoteService.reservationCharging(command);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_SUCCESS);
        } catch (BusinessException e) {
            logger.warn("预约充电测试warn", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("预约充电测试error", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_FAILED);
        }

        return response;
    }

    /**
     * 临时刷数据接口
     * http://localhost:8080/temp/tempUpdateVirtualAmount
     *
     * @param request
     * @return
     */
    @PostMapping("tempUpdateVirtualAmount")
    public RestApiResponse<?> tempUpdateVirtualAmount(HttpServletRequest request, @RequestBody QueryOrderDTO dto) {
        logger.info("临时刷数据接口 param:{}", dto);
        RestApiResponse<?> response = null;
        try {
            String s = tempService.tempUpdateVirtualAmount(dto);
            response = new RestApiResponse<>(s);
        } catch (BusinessException e) {
            logger.warn("临时刷数据接口 warn", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("临时刷数据接口 error", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_GET_PILE_DETAIL_ERROR);
        }
        logger.info("临时刷数据接口 result:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 临时订单退款
     * http://localhost:8080/temp/tempOrderRefund
     *
     * @return
     */
    @GetMapping("tempOrderRefund")
    public RestApiResponse<?> tempOrderRefund() {
        RestApiResponse<?> response = null;
        try {
            // orderBasicInfoService.tempOrderRefund();
            response = new RestApiResponse<>();
        } catch (BusinessException e) {
            logger.warn("临时订单退款接口 warn", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("临时订单退款接口 error", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR);
        }
        logger.info("临时刷数据接口 result:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 批量退款接口
     * http://localhost:8080/temp/batchRefund
     *
     * @param dto
     * @return
     */
    @PostMapping("/batchRefund")
    public RestApiResponse<?> batchRefund(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response = null;
        try {
            // orderBasicInfoService.batchRefund(dto);
            response = new RestApiResponse<>();
        } catch (BusinessException e) {
            logger.warn("临时订单退款接口 warn", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("临时订单退款接口 error", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR);
        }
        logger.info("临时刷数据接口 result:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 临时接口，计算站点订单报表
     * http://localhost:8080/temp/tempGenerateDailyOrderReports
     *
     * @param dto
     * @return
     */
    @PostMapping("/tempGenerateDailyOrderReports")
    public RestApiResponse<?> tempGenerateDailyOrderReports(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response = null;
        try {
            String startTime = dto.getStartTime();
            String endTime = dto.getEndTime();
            // 获取日期区间内所有日期
            List<String> dateList = DateUtils.getAllDatesInTheDateRange(startTime, endTime);

            dto.getStationIdList().parallelStream().forEach(stationId -> {
                PileStationVO stationInfo = pileStationInfoService.getStationInfo(stationId);
                for (String tradeDate : dateList) {
                    settleOrderReportService.generateDailyOrderReports(stationInfo, tradeDate);
                }
            });

            response = new RestApiResponse<>();
        } catch (BusinessException e) {
            logger.warn("临时接口计算站点订单报表 warn", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("临时接口计算站点订单报表 error", e);
            response = new RestApiResponse<>("00300003", "临时接口计算站点订单报表error");
        }
        logger.info("临时接口计算站点订单报表 result:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 临时接口测试vin查询方法
     *
     * @param dto
     * @return
     */
    @PostMapping("/tempTestVinCode")
    public RestApiResponse<?> tempTestVinCode(@RequestBody CarVinDTO dto) {
        RestApiResponse<?> response = null;
        try {
            MemberPlateNumberRelation memberPlateInfoByVinCode = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(dto.getVinCode());
            response = new RestApiResponse<>(memberPlateInfoByVinCode);
        } catch (Exception e) {
            logger.error("临时接口测试vin查询方法 error,", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR);
        }
        logger.info("临时接口测试vin查询方法 result:{}", response);
        return response;
    }

    /**
     * 交易确认接口
     * http://localhost:8080/temp/tempPaymentConfirm
     */
    @PostMapping("/tempPaymentConfirm")
    public RestApiResponse<?> tempPaymentConfirm(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response = null;
        try {
            OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
            AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(orderBasicInfo.getMerchantId());
            if (orderBasicInfo == null || adapayMemberAccount == null) {
                throw new BusinessException("", "查询信息为空");
            }
            String appId = pileMerchantInfoService.queryAppIdByMerchantId(orderBasicInfo.getMerchantId());
            orderBasicInfoService.doPaymentConfirmWithDelay(orderBasicInfo, adapayMemberAccount, appId);
        } catch (Exception e) {
            logger.error("临时接口交易确认接口 error,", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR);
        }
        logger.info("临时接口交易确认接口 result:{}", response);
        return response;
    }

    /**
     * 临时 余额支付分账
     * https://api.jsowellcloud.com/temp/doBalancePaymentTemp
     * @param dto
     * @return
     */
    @PostMapping("/doBalancePaymentTemp")
    public RestApiResponse<?> doBalancePaymentTemp(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response = null;
        try {
            OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
            if (orderBasicInfo == null) {
                throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_INFO_IS_NULL);
            }
            String merchantId = orderBasicInfo.getMerchantId();
            AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
            if (adapayMemberAccount == null) {
                throw new BusinessException("", "查询信息为空");
            }
            String appId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId);
            // orderBasicInfoService.doBalancePaymentWithDelay(orderBasicInfo, adapayMemberAccount, appId);
            tempService.doBalancePaymentTemp(orderBasicInfo, adapayMemberAccount, appId);
        } catch (Exception e) {
            logger.error("临时接口交易确认接口 error,", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR);
        }
        return response;
    }

    /**
     * 运营商分账手动接口
     * 前提条件是已经计算好订单日报了
     * http://localhost:8080/temp/orderSplittingOperations
     *
     * @return
     */
    @PostMapping("/orderSplittingOperations")
    public RestApiResponse<?> orderSplittingOperations(@RequestBody QueryOrderDTO dto) {
        logger.info("手动接口执行订单分账逻辑-param:{}", JSON.toJSONString(dto));
        RestApiResponse<?> response = null;
        try {
            String startTime = dto.getStartTime();
            String endTime = dto.getEndTime();
            // 获取日期区间内所有日期
            List<String> dateList = DateUtils.getAllDatesInTheDateRange(startTime, endTime);
            for (String tradeDate : dateList) {
                orderBasicInfoService.orderSplittingOperations(dto.getMerchantId(), tradeDate);
            }
            response = new RestApiResponse<>();
        } catch (BusinessException e) {
            logger.warn("手动接口执行订单分账逻辑-warn", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("手动接口执行订单分账逻辑-error", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR);
        }
        logger.info("手动接口执行订单分账逻辑-result:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 测试余额支付接口
     * http://localhost:8080/temp/testCreateBalancePayment
     */
    @PostMapping("/testCreateBalancePayment")
    public RestApiResponse<?> testCreateBalancePayment(@RequestBody BalancePaymentRequestDTO dto) {
        RestApiResponse<?> response = null;
        try {
            adapayMemberService.createBalancePaymentRequest(dto.getOutMemberId(), dto.getInMemberId(), dto.getTransAmt(), "测试余额支付", "测试余额支付描述", "");
            response = new RestApiResponse<>();
        } catch (BusinessException e) {
            logger.warn("测试余额支付接口warn", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("测试余额支付接口error", e);
            response = new RestApiResponse<>(ReturnCodeEnum.CODE_WEIXIN_REFUND_ERROR);
        }
        logger.info("测试余额支付接口result:{}", JSON.toJSONString(response));
        return response;
    }


    /**
     * 批量余额退款接口
     * http://localhost:8080/temp/batchWechatRefund
     * @param dto
     * @return
     */
    @PostMapping("/batchWechatRefund")
    public RestApiResponse<?> batchWechatRefund(@RequestBody ApplyRefundDTO dto) {
        logger.info("批量余额退款接口 params:{}", JSON.toJSONString(dto));
        RestApiResponse<?> response = null;
        List<String> memberIdList = dto.getMemberIdList();
        try {
            // 查询出本金金额
            List<MemberBalanceVO> memberRefundAmount = memberBasicInfoService.getMemberRefundAmount(memberIdList);
            if (CollectionUtils.isNotEmpty(memberRefundAmount)) {
                memberRefundAmount.parallelStream().forEach(memberBalanceVO -> {
                    ApplyRefundDTO refundDTO = new ApplyRefundDTO();
                    refundDTO.setMemberId(memberBalanceVO.getMemberId());
                    refundDTO.setRefundType("2");
                    refundDTO.setRefundAmount(new BigDecimal(memberBalanceVO.getPrincipalAmount()));
                    refundDTO.setWechatAppId(dto.getWechatAppId());
                    // 调用退款接口
                    String mode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId());
                    // 获取处理逻辑
                    AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode);
                    orderLogic.refundBalance(refundDTO);
                });
            }
            response = new RestApiResponse<>();
        } catch (Exception e) {
            logger.error("批量退款接口 error,", e);
            response = new RestApiResponse<>(e);
        }
        return response;
    }

    /**
     * 重试订单退款接口
     * http://localhost:8080/temp/retryRefundOrder
     */
    @PostMapping("/retryRefundOrder")
    public RestApiResponse<?> retryRefundOrder(@RequestBody ApplyRefundDTO dto) {
        RestApiResponse<?> response;
        try {
            orderBasicInfoService.retryRefundOrder(dto.getOrderCode());
            response = new RestApiResponse<>();
        } catch (BusinessException e) {
            logger.error("重试订单退款接口 error,", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("重试订单退款接口 error,", e);
            response = new RestApiResponse<>(e);
        }
        return response;
    }

    /**
     * 查询未分账订单
     * http://localhost:8080/temp/queryUndividedOrder
     */
    @PostMapping("/queryUndividedOrder")
    public RestApiResponse<?> queryUndividedOrder(@RequestBody SettleOrderReportDTO dto) {
        logger.info("查询未分账订单param:{}", JSON.toJSONString(dto));
        RestApiResponse<?> response;
        try {
            Map<String, Object> map = tempService.queryUndividedOrder(dto);
            response = new RestApiResponse<>(map);
        } catch (BusinessException e) {
            logger.error("查询未分账订单接口 error,", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("查询未分账订单接口 error,", e);
            response = new RestApiResponse<>("00300003", "查询未分账订单异常");
        }
        logger.info("查询未分账订单result:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 余额支付订单分账工具
     * 8月17号之后使用汇付余额支付的订单
     * 需要重新走一遍分账
     * https://api.jsowellcloud.com/temp/splitTheBillForOrderTemp
     */
    @PostMapping("/splitTheBillForOrderTemp")
    public RestApiResponse<?> splitTheBillForOrderTemp(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response;
        try {
            tempService.splitTheBillForOrderTemp(dto.getMerchantId(), dto.getOrderCodeList());
            response = new RestApiResponse<>();
        } catch (BusinessException e) {
            logger.error("余额支付订单分账工具 error,", e);
            response = new RestApiResponse<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("余额支付订单分账工具 error,", e);
            response = new RestApiResponse<>("00300003", "余额支付订单分账工具异常");
        }
        return response;
    }

    /**
     * 手动执行退款
     * 订单或余额
     * https://api.jsowellcloud.com/temp/adapayRefund
     */
    @PostMapping("/adapayRefund")
    public RestApiResponse<?> adapayRefund(@RequestBody ApplyRefundDTO dto) {
        orderService.adapayRefund(dto);
        return new RestApiResponse<>();
    }

    /**
     * 批量订单退款
     * 支持在线支付/余额支付
     * https://api.jsowellcloud.com/temp/batchRefundOrder
     */
    @PostMapping("/batchRefundOrder")
    public RestApiResponse<?> batchRefundOrder(@RequestBody QueryOrderDTO dto) {
        try {
            tempService.batchRefundOrder(dto.getOrderCodeList());
        } catch (Exception e) {
            logger.error("批量订单退款error", e);
        }
        return new RestApiResponse<>();
    }

    /**
     * 更新会员的余额充值记录
     */
    public RestApiResponse<?> updateMemberAdapayRecord(ApplyRefundDTO dto) {
        try {
            List<String> memberIdList = dto.getMemberIdList();
            for (String memberId : memberIdList) {
                tempService.updateMemberAdapayRecord(memberId);
            }
        } catch (Exception e) {
            logger.error("批量订单退款error", e);
        }

        return null;
    }

    /**
     * 校验未分账的支付单
     * https://localhost:8080/temp/verifyUndividedPayment
     */
    @PostMapping("/verifyUndividedPayment")
    public RestApiResponse<?> verifyUndividedPayment(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response;
        try {
            tempService.verifyUndividedPayment(dto);
            response = new RestApiResponse<>();
        } catch (Exception e) {
            logger.error("校验未分账的支付单error", e);
            response = new RestApiResponse<>();
        }
        return response;
    }

    /**
     * 根据时间范围查询支付对象列表，并查询分账情况
     */
    @PostMapping("/checkPayment")
    public RestApiResponse<?> checkPayment(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response;
        try {
            tempService.checkPayment(dto);
            response = new RestApiResponse<>();
        } catch (Exception e) {
            logger.error("校验未分账的支付单error", e);
            response = new RestApiResponse<>();
        }
        return response;
    }

    /**
     * 临时接口-重试余额支付订单退款
     * https://localhost:8080/temp/balancePaymentOrderRefundTemp
     */
    @PostMapping("/balancePaymentOrderRefundTemp")
    public RestApiResponse<?> balancePaymentOrderRefundTemp(@RequestBody QueryOrderDTO dto) {
        RestApiResponse<?> response;
        try {
            // 查询订单信息
            OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());

            // 退款
            String mode = pileMerchantInfoService.getDelayModeByMerchantId(orderBasicInfo.getMerchantId());
            AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode);
            orderLogic.refundOrder(orderBasicInfo);
            response = new RestApiResponse<>();
        } catch (Exception e) {
            logger.error("校验未分账的支付单error", e);
            response = new RestApiResponse<>();
        }
        return response;
    }
}
