package com.fs.store.controller;

import com.fs.FSAdminApplication;
import com.fs.common.core.domain.R;
import com.fs.common.exception.CustomException;
import com.fs.huifuPay.dto.*;
import com.fs.store.domain.FsCouponSchedule;
import com.fs.store.domain.FsMiniprogramSubNotifyTask;
import com.fs.store.domain.FsStorePayment;
import com.fs.store.domain.TzConfigInfoDTO;
import com.fs.store.enums.IcgProcessStatusEnum;
import com.fs.store.mapper.FsMiniprogramSubNotifyTaskMapper;
import com.fs.store.service.IFsCouponScheduleService;
import com.fs.store.service.IFsStorePaymentService;
import com.fs.task.ExpressTask;
import com.fs.task.MiniProgramSubTask;
import com.fs.task.StoreTask;
import com.fs.tzBank.TzBankService;
import com.fs.tzBank.utils.TzConfigUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.context.junit4.SpringRunner;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = FSAdminApplication.class)
@RequiredArgsConstructor
@Slf4j
public class FsStorePaymentControllerTest {

    @Autowired
    private FsStorePaymentController fsStorePaymentController;

    @Autowired
    private IFsCouponScheduleService fsCouponScheduleService;

    @Autowired
    IFsStorePaymentService fsStorePaymentService;

    @Test
    public void testTestPaymentSync() {
        fsStorePaymentService.paymentSync();
    }

    @Autowired
    private MiniProgramSubTask miniProgramSubTask;
    @Test
    public void returnPayStatus() throws Exception {

        Authentication authentication = new UsernamePasswordAuthenticationToken(
                "admin",
                "sadmin#258",
                Collections.singletonList(new SimpleGrantedAuthority("ADMIN"))
        );

        // Set the Authentication in the SecurityContext
        SecurityContextHolder.getContext().setAuthentication(authentication);


        FsStorePayment fsStorePayment = new FsStorePayment();
        fsStorePayment.setPaymentId(01L);
        fsStorePayment.setStatus(1);
        fsStorePayment.setOrderId(1899279950347763712L);
        fsStorePayment.setPayTypeCode("weixin");
        fsStorePayment.setPayMoney(new BigDecimal("0.01"));
        fsStorePayment.setPayTime(new Date());
        fsStorePayment.setTradeNo("002900TOP3B250311101453P779ac1369bc00000");
        fsStorePayment.setUserId(520391L);
        fsStorePayment.setOpenId("obmfC6y5ZOuvq9b4UlL7GUayuYQE");
        fsStorePayment.setCompanyId(12L);
        fsStorePayment.setCompanyUserId(42L);
        fsStorePayment.setDeptId(144L);
        fsStorePayment.setBankSerialNo("1899279950347763712L");
        fsStorePayment.setPayMode("hf");
        R r = fsStorePaymentController.returnPayStatus(fsStorePayment);
    }

    @Test
    public void test() throws Exception {
        FsCouponSchedule fsCouponSchedule = new FsCouponSchedule();
        fsCouponSchedule.setOrderId(1899279950347763712L);
        fsCouponSchedule.setSetmealId(1800L);
        fsCouponSchedule.setSetmealTitle("甘草干姜汤（北京同仁堂）1盒");
        fsCouponSchedule.setMonth(4L);
        fsCouponSchedule.setCount(0L);
        fsCouponSchedule.setStatus(IcgProcessStatusEnum.PENDING.getCode());
        fsCouponSchedule.setOrderTime(LocalDateTime.now());
        fsCouponSchedule.setUserId(520391L);
        // 如果上次发送时间为空，那么预计发送时间等于=下单时间+1月
        fsCouponSchedule.setSendTime(fsCouponSchedule.getOrderTime().plusMonths(1L));
        fsCouponSchedule.setRetryCount(0);

        fsCouponScheduleService.insertFsCouponSchedule(fsCouponSchedule);
    }

    @Autowired
    private TzBankService tzBankService;

    /**
     * 手动退款
     */
    @Test
    public void refund(){
        String[] data = new String[]{
                "1909861513640804352",
//                "1909850673067851776",
//                "1909850015832997888",
//                "1909843803510931456"
//                "1909829173233319936",
//                "1909796083228213248",
//                "1909793106169954304",
//                "1909753328464560128",
//                "1909728664442896384"
//                "851491647274359744"
//                "1909799684457627648"
//                "1909589366116712448",
//                "1909522277674778624",
//                "1909492344919425024",
//                "1909466851759357952",
//                "1909427177938485248",
//                "1909400759435264000",
//                "1909368705347747840",
//                "1909337288844771328",
//                "1909330401881489408"
        };
        TzConfigInfoDTO tzConfigInfoDTO = TzConfigUtils.getConfig();

        for (String datum : data) {
//            FsStorePayment payment = fsStorePaymentService.selectFsStorePaymentByCode(datum);
            FsStorePayment payment = new FsStorePayment();
            payment.setPayCode(datum);
            payment.setPayMoney(BigDecimal.valueOf(0.1));


            RequestDTO<TzPayRefundDTO> requestDTO = new RequestDTO<TzPayRefundDTO>();
            TzPayRefundDTO tzPayRefundDTO = new TzPayRefundDTO();
            tzPayRefundDTO.setOldPayOutOrderNo(payment.getPayCode());
            tzPayRefundDTO.setRefundOrderNo(payment.getPayCode());
            tzPayRefundDTO.setPlatMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            tzPayRefundDTO.setTrxSendTime(sdf.format(new Date()));
            tzPayRefundDTO.setRefundOrdTransAmt(payment.getPayMoney());
            tzPayRefundDTO.setNotifyURL(tzConfigInfoDTO.getRefundNotifyUrl());
            requestDTO.setReqBody(tzPayRefundDTO);
            requestDTO.setReqHeader(TzReqHeaderDTO.getInstance(payment.getPayCode()));

            TzReqResultDTO<TzRefundNotifyDTO> resultDTO;

            try {

                resultDTO = tzBankService.payRefund(requestDTO);
                TzRefundNotifyDTO body = resultDTO.getBody();
                String refundOrdStatus = body.getRefundOrdStatus();
                log.info("退款支付单号:{} 返回结果：{}",datum, resultDTO);
                if("90".equals(refundOrdStatus) || "50".equals(refundOrdStatus)) {
                    payment.setRefundMoney(payment.getRefundMoney());
                    payment.setStatus(-1);
                    payment.setRefundTime(new Date());
                    fsStorePaymentService.updateFsStorePayment(payment);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {

            }
        }
        // 退款将定时发放优惠券的状态设置为已退款
//                fsCouponScheduleService.setScheduleCouponRefund(String.valueOf(payment.getOrderId()));

    }

    @Autowired
    private StoreTask storeTask;

    @Autowired
    private ExpressTask expressTask;

    @Test
    public void deliveryOp(){
        storeTask.deliveryOp();
    }

    @Test
    public void subscribeExpress(){
        expressTask.subscribeExpress();
    }

    @Test
    public void issueCoupon() throws Exception {
        fsCouponScheduleService.issueCoupon();
    }

    @Test
    public void notifyMiniAppSub(){
        miniProgramSubTask.notifyMiniAppSub();
    }

    @Test
    public void queryOrder() throws Exception {
        String payCode = "1909873348586766336";
        FsStorePayment payment = fsStorePaymentService.selectFsStorePaymentByCode(payCode);

        RequestDTO<QueryOrderRestDTO> requestDTO = new RequestDTO<>();

        QueryOrderRestDTO queryOrderRestDTO = new QueryOrderRestDTO();
        queryOrderRestDTO.setOrderFlowNo(payment.getTradeNo());
        TzConfigInfoDTO tzConfigInfoDTO = TzConfigUtils.getConfig();

        queryOrderRestDTO.setPlatMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());

        requestDTO.setReqBody(queryOrderRestDTO);
        requestDTO.setReqHeader(TzReqHeaderDTO.getInstance(payment.getPayCode()));

        TzReqResultDTO<QueryOrderInfoDTO> resultDTO = tzBankService.payQueryOrder(requestDTO);
        log.info("查询结果: {}",resultDTO);
        String retCode = resultDTO.getRetCode();
        if(!retCode.equals("00000000")){
            log.info("台州银行支付回调查询失败{}",resultDTO);
            throw new CustomException("台州银行支付回调查询失败! msg="+resultDTO.getRetCode());
        }
        QueryOrderInfoDTO body = resultDTO.getBody();

    }
}
