package com.fs.store.service.impl;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.annotation.DataScope;
import com.fs.common.config.FSConfig;
import com.fs.common.config.FSSysConfig;
import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.R;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.IPUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.company.domain.CompanyUser;
import com.fs.company.service.ICompanyService;
import com.fs.company.service.ICompanyUserService;
import com.fs.huifuPay.domain.HuiFuCreateOrder;
import com.fs.huifuPay.domain.HuifuCreateOrderResult;
import com.fs.huifuPay.dto.*;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.store.constants.StoreConstants;
import com.fs.store.service.IFsStoreOrderService;
import com.fs.tzBank.TzBankService;
import com.fs.pay.pay.domain.CreateWxOrderResult;
import com.fs.pay.pay.dto.WxJspayDTO;
import com.fs.pay.pay.service.PayService;
import com.fs.store.domain.FsPayConfig;
import com.fs.store.domain.TzConfigInfoDTO;
import com.fs.store.param.FsStoreStatisticsParam;
import com.fs.store.service.IFsCouponScheduleService;
import com.fs.store.vo.FsStorePaymentStatisticsVO;
import com.fs.system.service.ISysConfigService;
import com.fs.tzBank.utils.TzConfigUtils;
import com.fs.wx.miniapp.config.WxMaProperties;
import com.fs.wx.pay.config.WxPayProperties;
import com.fs.store.domain.FsUser;
import com.fs.store.param.FsStorePaymentPayParam;
import com.fs.store.param.FsStorePaymentParam;
import com.fs.store.service.IFsUserService;
import com.fs.store.vo.FsStorePaymentVO;
import com.fs.pay.service.IPayService;
import com.fs.pay.service.dto.CreatePayDTO;
import com.fs.pay.service.dto.PayDTO;
import com.fs.pay.service.dto.TradeOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.store.mapper.FsStorePaymentMapper;
import com.fs.store.domain.FsStorePayment;
import com.fs.store.service.IFsStorePaymentService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 支付明细Service业务层处理
 *
 * @author fs
 * @date 2022-06-20
 */
@Service
public class FsStorePaymentServiceImpl implements IFsStorePaymentService
{
    protected final Logger logger = LoggerFactory.getLogger(BaseController.class);
    @Autowired
    private WxMaProperties properties;
    @Autowired
    private WxPayProperties wxPayProperties;
    @Autowired
    private IPayService payService;
    @Autowired
    private FSSysConfig sysConfig;
    @Autowired
    private FsStorePaymentMapper fsStorePaymentMapper;
    @Autowired
    private IFsUserService userService;

    @Autowired
    private ICompanyUserService companyUserService;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    PayService ybPayService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    HuiFuService huiFuService;
    @Autowired
    IFsCouponScheduleService fsCouponScheduleService;
    @Autowired
    TzBankService tzBankService;

    @Autowired
    private IFsStoreOrderService orderService;

    /**
     * 查询支付明细
     *
     * @param paymentId 支付明细ID
     * @return 支付明细
     */
    @Override
    public FsStorePayment selectFsStorePaymentById(Long paymentId)
    {
        return fsStorePaymentMapper.selectFsStorePaymentById(paymentId);
    }

    /**
     * 查询支付明细列表
     *
     * @param fsStorePayment 支付明细
     * @return 支付明细
     */
    @Override
    public List<FsStorePayment> selectFsStorePaymentList(FsStorePayment fsStorePayment)
    {
        return fsStorePaymentMapper.selectFsStorePaymentList(fsStorePayment);
    }

    /**
     * 新增支付明细
     *
     * @param fsStorePayment 支付明细
     * @return 结果
     */
    @Override
    public int insertFsStorePayment(FsStorePayment fsStorePayment)
    {
        fsStorePayment.setCreateTime(DateUtils.getNowDate());
        return fsStorePaymentMapper.insertFsStorePayment(fsStorePayment);
    }

    /**
     * 修改支付明细
     *
     * @param fsStorePayment 支付明细
     * @return 结果
     */
    @Override
    public int updateFsStorePayment(FsStorePayment fsStorePayment)
    {
        return fsStorePaymentMapper.updateFsStorePayment(fsStorePayment);
    }

    /**
     * 批量删除支付明细
     *
     * @param paymentIds 需要删除的支付明细ID
     * @return 结果
     */
    @Override
    public int deleteFsStorePaymentByIds(Long[] paymentIds)
    {
        return fsStorePaymentMapper.deleteFsStorePaymentByIds(paymentIds);
    }

    /**
     * 删除支付明细信息
     *
     * @param paymentId 支付明细ID
     * @return 结果
     */
    @Override
    public int deleteFsStorePaymentById(Long paymentId)
    {
        return fsStorePaymentMapper.deleteFsStorePaymentById(paymentId);
    }

    @Override
    @Transactional
    public R payment(FsStorePaymentPayParam payment) {
        if(payment.getPayMoney().compareTo(new BigDecimal(0.0))<1){
            return R.error("支付金额必须大于0");
        }
        // //获取OPENID
        // final WxMaService wxService = WxMaConfiguration.getMaService(properties.getConfigs().get(0).getAppid());
        String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
        // WxMaJscode2SessionResult session = null;
        // try {
        //     session = wxService.getUserService().getSessionInfo(payment.getCode());
        // } catch (WxErrorException e) {
        //     e.printStackTrace();
        // }
        CompanyUser companyUser=companyUserService.selectCompanyUserById(payment.getCompanyUserId());
        FsUser user=userService.selectFsUserById(payment.getUserId());
        // if(user==null){
        //     //写入
        //     user=new FsUser();
        //     user.setPhone("");
        //     user.setUsername("");
        //     user.setNickname("微信用户");
        //     user.setStatus(1);
        //     user.setOpenId(session.getOpenid());
        //     user.setLastIp(IpUtil.getRequestIp());
        //     user.setIsWeixinAuth(0);
        //     userService.insertFsUser(user);
        // }

        String json = configService.selectConfigByKey("store.pay");
        FsPayConfig fsPayConfig = JSON.parseObject(json, FsPayConfig.class);
        FsStorePayment storePayment=new FsStorePayment();
        storePayment.setCompanyId(payment.getCompanyId());
        storePayment.setCompanyUserId(payment.getCompanyUserId());
        storePayment.setStatus(0);
        storePayment.setPayMode(fsPayConfig.getType());
        storePayment.setPayCode(orderSn);
        storePayment.setPayMoney(payment.getPayMoney());
        storePayment.setCreateTime(new Date());
        storePayment.setPayTypeCode("weixin");
        storePayment.setBusinessType(1);
        storePayment.setRemark(payment.getRemark());
        storePayment.setOpenId(user.getMaOpenId());
        storePayment.setUserId(user.getUserId());
        if(companyUser==null){
            return R.error("销售帐号不存在");
        }
        storePayment.setDeptId(companyUser.getDeptId());
        //易宝支付
        fsStorePaymentMapper.insertFsStorePayment(storePayment);
        if (fsPayConfig.getType().equals("hf")){
            HuiFuCreateOrder o = new HuiFuCreateOrder();
            o.setTradeType("T_MINIAPP");
            o.setOpenid(user.getMaOpenId());
            o.setReqSeqId("payment-"+storePayment.getPayCode());
            o.setTransAmt(storePayment.getPayMoney().setScale(2, BigDecimal.ROUND_HALF_UP).toString());
            o.setGoodsDesc("医学管理方案服务");
            logger.info("汇付支付参数："+o);
            HuifuCreateOrderResult result = huiFuService.createOrder(o);
            //创建订单
            if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){
                FsStorePayment mt=new FsStorePayment();
                mt.setPaymentId(storePayment.getPaymentId());
                mt.setTradeNo(result.getHf_seq_id());
                fsStorePaymentMapper.updateFsStorePayment(mt);

                return R.ok().put("result",result.getPay_info());
            }
            else{
                return R.error(result.getResp_desc());
            }
        }else  if (fsPayConfig.getType().equals("yb")){
            WxJspayDTO p = new WxJspayDTO();
            // 使用setter方法为对象赋值
            p.setPayMoney(storePayment.getPayMoney().toString());
            p.setLowOrderId("payment-"+storePayment.getPayCode());
            p.setBody("医学管理方案服务");
            p.setIsMinipg("1");
            p.setReturnUrl(fsPayConfig.getYbNotifyUrl());
            p.setOpenId(user.getMaOpenId());
            p.setAttach("");
            p.setStoreid("0");
            CreateWxOrderResult wxOrder = ybPayService.createWxOrder(p);
            if(wxOrder.getStatus().equals("100")){
                FsStorePayment ment=new FsStorePayment();
                ment.setPaymentId(storePayment.getPaymentId());
                ment.setTradeNo(wxOrder.getUpOrderId());
                fsStorePaymentMapper.updateFsStorePayment(ment);
                return R.ok().put("result",wxOrder.getPay_info());
            }
            else{
                return R.error(wxOrder.getMessage());
            }
        } else if(fsPayConfig.getType().equals("tzbk")){
            TzConfigInfoDTO tzConfigInfoDTO = JSON.parseObject(json, TzConfigInfoDTO.class);

            TzPayCreateOrderReqBodyDTO reqBodyDTO = new TzPayCreateOrderReqBodyDTO();
            RequestDTO<TzPayCreateOrderReqBodyDTO> requestDTO = new RequestDTO<>();
            String payCode = storePayment.getPayCode();
            reqBodyDTO.setOrderNo(storePayment.getPayCode());
            reqBodyDTO.setOrderSource("02");
            reqBodyDTO.setTrxAmt(storePayment.getPayMoney());
            reqBodyDTO.setCurrency("CNY");
            reqBodyDTO.setTransType("2001");
            reqBodyDTO.setTradeMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());
            reqBodyDTO.setPlatMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());
            reqBodyDTO.setBusinessCstNo(user.getUserId().toString());
            reqBodyDTO.setPayNotifyUrl(tzConfigInfoDTO.getPayNotifyUrl());
            reqBodyDTO.setPayerName(user.getUsername());
            reqBodyDTO.setPayerMobileNo(user.getPhone());
            reqBodyDTO.setGoodsInfo("微信收款");
            // 不需要分账
            reqBodyDTO.setNeedLedger("00");
            reqBodyDTO.setClientIp(IPUtils.getIpAddr(ServletUtils.getRequest()));
            // 获取订单到期时间
            // 获取当前时间戳
            Instant currentTimestamp = Instant.now();
            // 增加一个小时
            Instant oneHourLater = currentTimestamp.plusSeconds(3600);

            reqBodyDTO.setExpiredTime(String.valueOf(oneHourLater.toEpochMilli()));

            requestDTO.setReqHeader(TzReqHeaderDTO.getInstance(payCode));
            requestDTO.setReqBody(reqBodyDTO);
            try {
                // 创建订单
                TzReqResultDTO<TzPayCreateOrderRspDTO> payCreateOrder = tzBankService.payCreateOrder(requestDTO);
                // 获得小程序请求码
                if("00000000".equals(payCreateOrder.getRetCode())){
                    TzPayCreateOrderRspDTO body = payCreateOrder.getBody();

                    RequestDTO<TzMiniProgramCodeReqDTO> reqDTORequestDTO = new RequestDTO<>();
                    TzMiniProgramCodeReqDTO tzMiniProgramCodeReqDTO = new TzMiniProgramCodeReqDTO();
                    tzMiniProgramCodeReqDTO.setOrderNo(body.getOrderFlowNo());
                    tzMiniProgramCodeReqDTO.setPlatMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());
                    tzMiniProgramCodeReqDTO.setBusinessCstNo(user.getUserId().toString());
                    reqDTORequestDTO.setReqHeader(TzReqHeaderDTO.getInstance(payCode));
                    reqDTORequestDTO.setReqBody(tzMiniProgramCodeReqDTO);
                    TzReqResultDTO<TzMiniProgramCodeRespDTO> miniProgramCode = tzBankService.miniProgramCode(reqDTORequestDTO);
                    if("00000000".equals(miniProgramCode.getRetCode())){
                        FsStorePayment ment=new FsStorePayment();
                        ment.setPaymentId(storePayment.getPaymentId());
                        ment.setTradeNo(body.getOrderFlowNo());
                        fsStorePaymentMapper.updateFsStorePayment(ment);
                        TzMiniProgramCodeRespDTO result = miniProgramCode.getBody();
                        result.setPayCode(payCode);
                        return R.ok().put("result",result);
                    } else {
                        return R.error(miniProgramCode.getRetMsg());
                    }
                } else {
                    return R.error(payCreateOrder.getRetMsg());
                }
            } catch (Exception e) {
                logger.error("系统异常",e);
                return R.error("系统异常，请联系管理员!");
            }
//            if()
//            return R.ok().put("result",wxOrder.getPay_info());

        }

        //小雨点支付
//        CreatePayDTO createPayDTO=new CreatePayDTO();
//        createPayDTO.setMerchOrderNo("payment-"+storePayment.getPayCode());
//        List<TradeOrder> orders=new ArrayList<>();
//        TradeOrder order=new TradeOrder();
//        order.setAmount(storePayment.getPayMoney().toString());
//        order.setSubMerchOrderNo("payment-"+storePayment.getPayCode());
//        order.setTradeName("超重/肥胖/气血/代谢/美乳/慢病医学管理方案服务");
//        order.setPayeeOutUserId(sysConfig.getPayPartnerId());
//        orders.add(order);
//        createPayDTO.setOrders(orders);
//        payService.createOrder(createPayDTO);
//        PayDTO payDTO=new PayDTO();
//        payDTO.setOrigMerchOrderNo("payment-"+storePayment.getPayCode());
//        payDTO.setOpenID(user.getMaOpenId());
//        payDTO.setAppID(wxPayProperties.getAppId());
//        payDTO.setPayerOutUserId(user.getUserId().toString());
//        payDTO.setPayerOutUserName(user.getNickname());
//        payDTO.setUserIp(IPUtils.getIpAddr(ServletUtils.getRequest()));
//        return R.ok().put("result",payService.payOrder(payDTO));
        return R.error("无支付类型");

    }

    @Override
    public FsStorePayment selectFsStorePaymentByCode(String payCode) {
        return fsStorePaymentMapper.selectFsStorePaymentByCode(payCode);
    }

    @Override
    public List<FsStorePaymentVO> selectFsStorePaymentListQuery(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentListQuery(fsStorePayment);
    }

    @Override
    public List<FsStorePaymentVO> exportFsStorePaymentList(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.exportFsStorePaymentList(fsStorePayment);
    }

    @Override
    @DataScope(deptAlias = "cu",userAlias = "cu")
    public List<FsStorePaymentVO> selectFsStorePaymentListQueryVO(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentListQueryVO(fsStorePayment);
    }

    @Override
    public List<FsStorePaymentVO> selectFsMyStorePaymentListQueryVO(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsMyStorePaymentListQueryVO(fsStorePayment);
    }

    @Override
    public List<FsStorePayment> selectFsStorePaymentByOrderId(Long orderId) {
        return fsStorePaymentMapper.selectFsStorePaymentByOrderId(orderId);
    }

    @Override
    public Long selectFsStorePaymentCount(int type,Long companyId) {
        return fsStorePaymentMapper.selectFsStorePaymentCount(type,companyId);
    }

    @Override
    @Transactional
    public String payConfirm(String payCode,String tradeNo,String bankTransactionId,String bankSerialNo) {
        //更新订单状态
        FsStorePayment storePayment=fsStorePaymentMapper.selectFsStorePaymentByCode(payCode);
        if(!storePayment.getStatus().equals(0)){
            return "";
        }
        storePayment.setStatus(1);
        storePayment.setPayTime(new Date());
        storePayment.setTradeNo(tradeNo);
        storePayment.setBankSerialNo(bankSerialNo);
        storePayment.setBankTransactionId(bankTransactionId);
        fsStorePaymentMapper.updateFsStorePayment(storePayment);
        //增加佣金
        if(storePayment.getCompanyId()!=null&&storePayment.getCompanyId()>0){
            companyService.addCompanyPaymentMoney(storePayment);
        }
        return "SUCCESS";
    }

    @Override
    @Transactional
    public String refund(String orderCode) {
        FsStorePayment payment=fsStorePaymentMapper.selectFsStorePaymentByCode(orderCode);
        payment.setStatus(-1);
        payment.setRefundTime(new Date());
        fsStorePaymentMapper.updateFsStorePayment(payment);
        //收款 减去所有
        if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
            companyService.subCompanyPaymentMoney(payment);
        }
        // 退款将定时发放优惠券的状态设置为已退款
        fsCouponScheduleService.setScheduleCouponRefund(orderCode);
        return "success";
    }

    @Override
    public List<JSONObject> selectFsStorePaymentCounts(Map<String, Object> toMap) {
        return fsStorePaymentMapper.selectFsStorePaymentCounts(toMap);
    }

    @Override
    public List<FsStorePaymentStatisticsVO> selectFsStorePaymentStatisticsList(FsStoreStatisticsParam param) {
        return fsStorePaymentMapper.selectFsStorePaymentStatisticsList(param);
    }

    @Override
    public List<FsStorePayment> selectFsStorePaymentByOrder(Long orderId) {
        return fsStorePaymentMapper.selectFsStorePaymentByOrder(orderId);
    }

    @Override
    public FsStorePayment selectFsStorePaymentByTradeNo(String tradeNo) {
        return fsStorePaymentMapper.selectFsStorePaymentByTradeNo(tradeNo);
    }

    @Override
    public void paymentSync() {
        List<FsStorePayment> fsStorePayments = fsStorePaymentMapper.queryPendingDelayState();
        for (FsStorePayment fsStorePayment : fsStorePayments) {
            RequestDTO<QueryOrderRestDTO> requestDTO = new RequestDTO<>();

            QueryOrderRestDTO queryOrderRestDTO = new QueryOrderRestDTO();

            queryOrderRestDTO.setOrderFlowNo(fsStorePayment.getTradeNo());
            TzConfigInfoDTO tzConfigInfoDTO = TzConfigUtils.getConfig();

            queryOrderRestDTO.setPlatMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());

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

            TzReqResultDTO<QueryOrderInfoDTO> resultDTO = null;
            try {
                resultDTO = tzBankService.payQueryOrder(requestDTO);
                String retCode = resultDTO.getRetCode();
                // 如果查询支付成功
                if(retCode.equals("00000000")){
                    QueryOrderInfoDTO body = resultDTO.getBody();
                    String status = body.getStatus();
                    Long orderId = fsStorePayment.getOrderId();
                    String payCode = fsStorePayment.getPayCode();
                    if("90".equals(status)){
                        // 如果查询支付成功 更新订单状态
                        orderService.payConfirm(1,orderId,fsStorePayment.getPayCode(),
                                fsStorePayment.getTradeNo(),body.getChlTrxId(),fsStorePayment.getTradeNo());

                    } else if("70".equals(status) || "80".equals(status)) {
                        fsStorePayment.setStatus(-2);
                        this.updateFsStorePayment(fsStorePayment);
                    }

                }
            } catch (Exception e) {
                logger.error("台州银行支付回调查询失败:",e);
            }
        }
    }
}
