package com.fs.app.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.fs.app.annotation.Login;
import com.fs.common.annotation.Log;
import com.fs.common.annotation.RepeatSubmit;

import com.fs.common.config.FSSysConfig;
import com.fs.common.core.domain.R;
import com.fs.common.enums.BusinessType;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.*;
import com.fs.common.utils.ip.IpUtils;
import com.fs.huifuPay.domain.HuiFuCreateOrder;
import com.fs.huifuPay.domain.HuifuCreateOrderResult;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.pay.pay.config.PayConfig;
import com.fs.pay.pay.domain.CreateWxOrderResult;
import com.fs.pay.pay.domain.OrderResult;
import com.fs.pay.pay.dto.OrderQueryDTO;
import com.fs.pay.pay.dto.WxJspayDTO;
import com.fs.pay.pay.service.PayService;
import com.fs.pay.pay.service.impl.PayApiServiceImpl;
import com.fs.pay.service.dto.PayQueryDTO;
import com.fs.store.domain.*;
import com.fs.system.domain.SysConfig;
import com.fs.wx.miniapp.config.WxMaConfiguration;
import com.fs.wx.miniapp.config.WxMaProperties;
import com.fs.wx.pay.config.WxPayProperties;
import com.fs.erp.service.IErpOrderService;
import com.fs.store.config.StoreConfig;

import com.fs.store.dto.FsStoreOrderComputeDTO;
import com.fs.store.enums.OrderInfoEnum;
import com.fs.store.mapper.FsStorePaymentMapper;
import com.fs.store.param.*;
import com.fs.store.service.*;
import com.fs.store.vo.FsMyStoreOrderListQueryVO;
import com.fs.store.vo.FsStoreOrderItemVO;
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 com.fs.system.service.ISysConfigService;
import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.EntPayService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Synchronized;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.catalina.servlets.DefaultServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;




@Api("商城接口")
@RestController
@RequestMapping(value="/app/storeOrder")
public class StoreOrderController extends  AppBaseController {

    Logger logger= LoggerFactory.getLogger(getClass());
    @Autowired
    private WxPayProperties wxPayProperties;

    @Autowired
    private WxMaProperties properties;

    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private IFsStoreOrderService orderService;
    @Autowired
    private FsStorePaymentMapper fsStorePaymentMapper;

    @Autowired
    private IFsStoreOrderItemService itemService;

    @Autowired
    private IFsUserService userService;

    @Autowired
    private IFsPrescribeService prescribeService;
    @Autowired
    private IPayService payService;
    @Autowired
    private FSSysConfig sysConfig;
    @Autowired
    private IErpOrderService erpOrderService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IFsStoreAfterSalesService afterSalesService;
    @Autowired
    private IFsStoreProductPackageService productPackageService;
    @Autowired
    PayService ybPayService;
    @Autowired
    private HuiFuService huiFuService;


    @Login
    @ApiOperation("获取我的订单列表")
    @GetMapping("/getMyStoreOrderList")
        public R getMyStoreOrderList(FsMyStoreOrderQueryParam param, HttpServletRequest request){
        PageHelper.startPage(param.getPage(), param.getPageSize());
        param.setUserId(Long.parseLong(getUserId()));
        List<FsMyStoreOrderListQueryVO> list=orderService.selectFsMyStoreOrderListVO(param);
        PageInfo<FsMyStoreOrderListQueryVO> listPageInfo=new PageInfo<>(list);
        return R.ok().put("data",listPageInfo);
    }

    @Login
    @ApiOperation("获取销售公司订单列表")
    @GetMapping("/getCompanyStoreOrderList")
    public R getCompanyStoreOrderList(FsMyStoreOrderQueryParam param, HttpServletRequest request){
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<FsMyStoreOrderListQueryVO> list=orderService.selectFsCompanyStoreOrderListVO(param);
        PageInfo<FsMyStoreOrderListQueryVO> listPageInfo=new PageInfo<>(list);
        return R.ok().put("data",listPageInfo);
    }

    @Login
    @ApiOperation("获取我的订单详情")
    @GetMapping("/getMyStoreOrderById")
    public R getMyStoreOrderById(@RequestParam("orderId") Long orderId, HttpServletRequest request){
        FsStoreOrder order=orderService.selectFsStoreOrderById(orderId);
        order.setUserPhone(ParseUtils.parsePhone(order.getUserPhone()));
        order.setUserAddress(ParseUtils.parseIdCard(order.getUserAddress()));
        List<FsStoreOrderItemVO> list=itemService.selectFsStoreOrderItemListByOrderId(orderId);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(order.getCreateTime());
        String json=configService.selectConfigByKey("store.config");
        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
        calendar.add(Calendar.MINUTE,config.getUnPayTime());
        SimpleDateFormat format = new   SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String payLimitTime = format.format(calendar.getTime() );
        FsPrescribe prescribe=null;
        if(order.getPrescribeId()!=null){
            prescribe=prescribeService.selectFsPrescribeById(order.getPrescribeId());
        }
        //处理是否可以申请售后
        Integer isAfterSales=0;
        if(order.getStatus().equals(OrderInfoEnum.STATUS_3.getValue())) {
            //已完成订单
            isAfterSales=1;
            if (order.getFinishTime() != null) {
                if (config.getStoreAfterSalesDay() != null && config.getStoreAfterSalesDay() > 0) {
                    //判断完成时间是否超过指定时间
                    Calendar calendarAfterSales = new GregorianCalendar();
                    calendarAfterSales.setTime(order.getFinishTime());
                    calendarAfterSales.add(calendarAfterSales.DATE, config.getStoreAfterSalesDay()); //把日期往后增加一天,整数  往后推,负数往前移动
                    if (calendarAfterSales.getTime().getTime() < new Date().getTime()) {
                        isAfterSales = 0;
                    }
                }
            }
        }
        else if(order.getStatus()==1||order.getStatus()==2){
            isAfterSales=1;
        }
        return R.ok().put("isAfterSales",isAfterSales).put("order",order).put("items",list).put("payLimitTime",payLimitTime).put("prescribe",prescribe);
    }

    @Login
    @ApiOperation("获取订单")
    @GetMapping("/getStoreOrderById")
    public R getStoreOrderById(@RequestParam("orderId") Long orderId, HttpServletRequest request){
        FsStoreOrder order=orderService.selectFsStoreOrderById(orderId);

        order.setUserPhone(ParseUtils.parsePhone(order.getUserPhone()));
        order.setUserAddress(ParseUtils.parseIdCard(order.getUserAddress()));

        String json=configService.selectConfigByKey("store.config");
        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(order.getCreateTime());
        calendar.add(Calendar.MINUTE,config.getUnPayTime());
        SimpleDateFormat format = new   SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String payLimitTime = format.format(calendar.getTime() );
        FsStoreProductPackage productPackage=null;
        if(order.getIsPackage()!=null&&order.getIsPackage()==1){
            productPackage= productPackageService.selectFsStoreProductPackageById(order.getPackageId());
        }
        return R.ok().put("order",order).put("productPackage",productPackage).put("payLimitTime",payLimitTime);
    }


    @Login
    @ApiOperation("确认订单")
    @PostMapping("/confirm")
    public R confirm(@Validated @RequestBody FsStoreConfirmOrderParam param, HttpServletRequest request){
        return orderService.confirmOrder(Long.parseLong(getUserId()),param);
    }
    @Login
    @ApiOperation("计算订单金额")
    @PostMapping("/computed")
    public R computed(@Validated @RequestBody FsStoreOrderComputedParam param, HttpServletRequest request){
        FsStoreOrderComputeDTO dto=orderService.computedOrder(Long.parseLong(getUserId()),param);
        return R.ok().put("data",dto);
    }

    @Login
    @ApiOperation("创建订单")
    @PostMapping("/create")
    public R create(@Validated @RequestBody FsStoreOrderCreateParam param, HttpServletRequest request){
        String userId=getUserId();
        return orderService.createOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("支付")
    @PostMapping("/pay")
    @Transactional
    //@Synchronized
    public R pay(HttpServletRequest request, @Validated @RequestBody FsStoreOrderPayParam param)
    {
        logger.info("zzf \n【pay】:"+param.getOrderId()+"的订单支付类型为"+param.getPayType());
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if(order==null){
            return R.error("订单不存在");
        }
        if(order.getStatus()!= OrderInfoEnum.STATUS_0.getValue()){
            return R.error("订单状态不正确");
        }
        String orderId=redisCache.getCacheObject("isPaying:"+order.getId());
        if(StringUtils.isNotEmpty(orderId)&&orderId.equals(order.getId().toString())){
            return R.error("正在支付中...");
        }

        FsUser user=userService.selectFsUserById(order.getUserId());
        if(user!=null&& StringUtils.isNotEmpty(user.getMaOpenId())){
            //已改价处理
            if(order.getIsEditMoney()!=null&&order.getIsEditMoney()==1){
                //改过价不做处理
            }
            else{
                String config=configService.selectConfigByKey("store.config");
                StoreConfig storeConfig= JSONUtil.toBean(config,StoreConfig.class);
                if(param.getPayType().equals(1)){
                    order.setPayType("1");
                    order.setPayMoney(order.getPayPrice());
                    order.setPayDelivery(BigDecimal.ZERO);
                }
                else if(param.getPayType().equals(2)){
                    order.setPayType("2");
                    BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
                    order.setPayDelivery(order.getPayPrice().subtract(payMoney));
                    order.setPayMoney(payMoney);
                }
                else if(param.getPayType().equals(3)){
                    //货到付款
                    order.setPayType("3");
                    order.setPayDelivery(order.getPayPrice() );
                    order.setPayMoney(BigDecimal.ZERO);
                }
                orderService.updateFsStoreOrder(order);
            }
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
//            order.setOrderCode(orderCode);
            //易宝支付
            if(order.getPayType().equals("1")||order.getPayType().equals("2")){
                String json = configService.selectConfigByKey("store.pay");
                FsPayConfig fsPayConfig = JSON.parseObject(json, FsPayConfig.class);
                FsStorePayment storePayment=new FsStorePayment();
                storePayment.setCompanyId(order.getCompanyId());
                storePayment.setCompanyUserId(order.getCompanyUserId());
                storePayment.setPayMode(fsPayConfig.getType());
                storePayment.setStatus(0);
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(order.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("weixin");
                storePayment.setBusinessType(2);
                storePayment.setRemark("商城订单支付");
                storePayment.setOpenId(user.getRealName());
                storePayment.setUserId(user.getUserId());
                storePayment.setBusinessOrderId(order.getId().toString());
                storePayment.setOrderId(order.getId());
                fsStorePaymentMapper.insertFsStorePayment(storePayment);

//                //创建订单
//                WxJspayDTO p = new WxJspayDTO();
//                // 使用setter方法为对象赋值
//                p.setPayMoney(order.getPayMoney().toString());
//                p.setLowOrderId("store-"+payCode);
//                p.setBody("商城订单支付");
//                p.setIsMinipg("1");
//                p.setReturnUrl(PayConfig.notifyUrl);
//                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);
//                    redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
//                    return R.ok().put("payType",param.getPayType()).put("result",wxOrder.getPay_info());
//                }
//                else{
//                    return R.error(wxOrder.getMessage());
//                }
                if (fsPayConfig.getType().equals("hf")){
                    HuiFuCreateOrder o = new HuiFuCreateOrder();
                    o.setTradeType("T_MINIAPP");
                    o.setOpenid(user.getMaOpenId());
                    o.setReqSeqId("store-"+storePayment.getPayCode());
                    o.setTransAmt(storePayment.getPayMoney().toString());
                    o.setGoodsDesc("商城订单支付");
                    HuifuCreateOrderResult result = huiFuService.createOrder(o);
                    if(result.getBank_code()!=null&&result.getBank_code().equals("00000000")){
                        FsStorePayment mt=new FsStorePayment();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                        Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                        String s = (String) resultMap.get("package");
                        resultMap.put("packageValue",s);
                        return R.ok().put("payType",param.getPayType()).put("result",resultMap);
                    }
                    else{
                        return R.error(result.getResp_desc());
                    }
                }else  if (fsPayConfig.getType().equals("wx")){
                    WxPayConfig payConfig = new WxPayConfig();
                    payConfig.setAppId(fsPayConfig.getAppId());
                    payConfig.setMchId(fsPayConfig.getWxMchId());
                    payConfig.setMchKey(fsPayConfig.getWxMchKey());
                    payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                    payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                    payConfig.setKeyPath(wxPayProperties.getKeyPath());
                    payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
                    wxPayService.setConfig(payConfig);
                    WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                    orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                    orderRequest.setBody("商城订单支付");
                    orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                    orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                    //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                    orderRequest.setTradeType("JSAPI");
                    orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                    //调用统一下单接口，获取"预支付交易会话标识"
                    try {
                        WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                        return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0).put("payType",param.getPayType());
                    } catch (WxPayException e) {
                        e.printStackTrace();
                        throw new CustomException("支付失败" + e.getMessage());
                    }
                }
            }
            else if(order.getPayType().equals("3")){
                //货到付款
                orderService.payConfirm(2,order.getId(),null,null,null,null);
                return R.ok().put("payType",param.getPayType());
            }
            return R.error();
        }
        else{
            return R.error("用户OPENID不存在");
        }

    }





    @Login
    @ApiOperation("修改支付类型")
    @PostMapping("/editPayType")
    @Transactional
    public R editPayType(HttpServletRequest request, @Validated @RequestBody FsStoreOrderPayParam param) {
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if(order==null){
            return R.error("订单不存在");
        }
        if(order.getStatus()!= OrderInfoEnum.STATUS_0.getValue()){
            return R.error("订单状态不正确");
        }
        String orderId=redisCache.getCacheObject("isPaying:"+order.getId());
        if(StringUtils.isNotEmpty(orderId)&&orderId.equals(order.getId().toString())){
            return R.error("正在支付中...");
        }
        List<FsStorePayment>  payments=fsStorePaymentMapper.selectFsStorePaymentByOrder(order.getId());
        if(payments.size()>0){
            for(FsStorePayment payment : payments){
                OrderQueryDTO orderQueryDTO = new OrderQueryDTO();
                orderQueryDTO.setLowOrderId("store-"+payment.getPayCode());
                OrderResult orderResult = ybPayService.getOrder(orderQueryDTO);
                if(orderResult.getStatus()!= null&&orderResult.getStatus().equals("100")){
                    if(orderResult.getState()!=null&&orderResult.getState().equals("0")){
                        return R.error("订单已支付");
                    }

                }
            }
        }
        FsUser user=userService.selectFsUserById(order.getUserId());
        if(user!=null&& StringUtils.isNotEmpty(user.getMaOpenId())){
            //已改价处理
            if(order.getIsEditMoney()!=null&&order.getIsEditMoney()==1){
                //改过价不做处理
            }
            else{
                String config=configService.selectConfigByKey("store.config");
                StoreConfig storeConfig= JSONUtil.toBean(config,StoreConfig.class);
                if(param.getPayType().equals(1)){
                    order.setPayType("1");
                    order.setPayMoney(order.getPayPrice());
                    order.setPayDelivery(BigDecimal.ZERO);
                }
                else if(param.getPayType().equals(2)){

                    order.setPayType("2");
                    BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
                    order.setPayDelivery(order.getPayPrice().subtract(payMoney));
                    order.setPayMoney(payMoney);
                }
                else if(param.getPayType().equals(3)){
                    //货到付款
                    order.setPayType("3");
                    order.setPayDelivery(order.getPayPrice() );
                    order.setPayMoney(BigDecimal.ZERO);
                }
                orderService.updateFsStoreOrder(order);
            }
            return R.ok().put("order",order);
        }
        else{
            return R.error("用户OPENID不存在");
        }

    }


    @Login
    @ApiOperation("支付尾款")
    @PostMapping("/payRemain")
    @Transactional
    public R payRemain(HttpServletRequest request, @Validated @RequestBody FsStoreOrderPayParam param) {
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if(order==null){
            return R.error("订单不存在");
        }
        if(order.getStatus()!= OrderInfoEnum.STATUS_2.getValue()){
            return R.error("待收货订单可申请支付尾款");
        }
        if(order.getPayType().equals(1)){
            return R.error("此订单已支付");
        }
        //只有顺风才可以付尾
        if(!order.getDeliverySn().trim().equals("SF")){
            return R.error("只有顺丰物流支持尾款支付");
        }

        if(!order.getIsPayRemain().equals(0)){
            return R.error("此订单已支付");
        }
        FsUser user=userService.selectFsUserById(order.getUserId());
        if(user!=null&& StringUtils.isNotEmpty(user.getMaOpenId())){
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
            String json = configService.selectConfigByKey("store.pay");
            FsPayConfig fsPayConfig = JSON.parseObject(json, FsPayConfig.class);
            FsStorePayment storePayment=new FsStorePayment();
            storePayment.setCompanyId(order.getCompanyId());
            storePayment.setCompanyUserId(order.getCompanyUserId());
            storePayment.setStatus(0);
            storePayment.setPayMode(fsPayConfig.getType());
            storePayment.setPayCode(payCode);
            storePayment.setPayMoney(order.getPayDelivery());
            storePayment.setCreateTime(new Date());
            storePayment.setPayTypeCode("weixin");
            storePayment.setBusinessType(2);
            storePayment.setRemark("商城订单尾款支付");
            storePayment.setOpenId(user.getRealName());
            storePayment.setUserId(user.getUserId());
            storePayment.setBusinessOrderId(order.getId().toString());
            storePayment.setOrderId(order.getId());
            storePayment.setIsPayRemain(1);
            fsStorePaymentMapper.insertFsStorePayment(storePayment);

            if (fsPayConfig.getType().equals("hf")){
                HuiFuCreateOrder o = new HuiFuCreateOrder();
                o.setTradeType("T_MINIAPP");
                o.setOpenid(user.getMaOpenId());
                o.setReqSeqId("store_remain-"+storePayment.getPayCode());
                o.setTransAmt(storePayment.getPayMoney().toString());
                o.setGoodsDesc("商城订单尾款支付");
                HuifuCreateOrderResult result = huiFuService.createOrder(o);
                //创建订单
                if(result.getBank_code()!=null&&result.getBank_code().equals("00000000")){
                    FsStorePayment mt=new FsStorePayment();
                    mt.setPaymentId(storePayment.getPaymentId());
                    mt.setTradeNo(result.getHf_seq_id());
                    fsStorePaymentMapper.updateFsStorePayment(mt);
                    redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                    Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                    return R.ok().put("result",resultMap);
                }
                else{
                    return R.error(result.getResp_desc());
                }
            }else if(fsPayConfig.getType().equals("wx")) {
                WxPayConfig payConfig = new WxPayConfig();
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setKeyPath(null);
                payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
                wxPayService.setConfig(payConfig);
                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                orderRequest.setBody("商城订单支付");
                orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                orderRequest.setTradeType("JSAPI");
                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                //调用统一下单接口，获取"预支付交易会话标识"
                try {
                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                    return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0);
                } catch (WxPayException e) {
                    e.printStackTrace();
                    throw new CustomException("支付失败" + e.getMessage());
                }
            }
        }
        else{
            return R.error("用户OPENID不存在");
        }
        return R.error("无支付类型");
    }


    @Login
    @ApiOperation("亲友支付")
    @PostMapping("/otherPayment")
    @Transactional
    public R otherPayment(@Validated @RequestBody FsStoreOrderOtherPayParam param, HttpServletRequest request){
        final WxMaService wxService = WxMaConfiguration.getMaService(properties.getConfigs().get(0).getAppid());
        try {
            String ip = IpUtil.getRequestIp();
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
            FsUser user=userService.selectFsUserByMaOpenId(session.getOpenid());
            if(user==null){
                //创建
                user=new FsUser();
                user.setUsername("");
                user.setNickname("微信用户");
                user.setStatus(1);
                user.setMaOpenId(session.getOpenid());
                user.setUnionId(session.getUnionid());
                user.setIsWeixinAuth(0);
                user.setLastIp(ip);
                user.setCreateTime(new Date());
                userService.insertFsUser(user);
            }
            FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
            if(order==null){
                return R.error("订单不存在");
            }
            if(order.getStatus()!= OrderInfoEnum.STATUS_0.getValue()){
                return R.error("此订单不能支付");
            }
            if(order.getPayMoney().compareTo(new BigDecimal(0))<1){
                return R.error("此订单没有可支付的金额");
            }

            String orderId=redisCache.getCacheObject("isPaying:"+order.getId());
            if(StringUtils.isNotEmpty(orderId)&&orderId.equals(order.getId().toString())){
                return R.error("正在支付中...");
            }

            String json = configService.selectConfigByKey("store.pay");
            FsPayConfig fsPayConfig = JSON.parseObject(json, FsPayConfig.class);
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
            //易宝支付
            FsStorePayment storePayment=new FsStorePayment();
            storePayment.setCompanyId(order.getCompanyId());
            storePayment.setCompanyUserId(order.getCompanyUserId());
            storePayment.setStatus(0);
            storePayment.setPayCode(payCode);
            storePayment.setPayMode(fsPayConfig.getType());
            storePayment.setPayMoney(order.getPayMoney());
            storePayment.setCreateTime(new Date());
            storePayment.setPayTypeCode("weixin");
            storePayment.setBusinessType(2);
            storePayment.setRemark("商城订单支付");
            storePayment.setOpenId(session.getOpenid());
            storePayment.setUserId(user.getUserId());
            storePayment.setBusinessOrderId(order.getId().toString());
            storePayment.setOrderId(order.getId());
            fsStorePaymentMapper.insertFsStorePayment(storePayment);

            if (fsPayConfig.getType().equals("hf")){
                HuiFuCreateOrder o = new HuiFuCreateOrder();
                o.setTradeType("T_MINIAPP");
                o.setOpenid(user.getMaOpenId());
                o.setReqSeqId("store-"+storePayment.getPayCode());
                o.setTransAmt(storePayment.getPayMoney().toString());
                o.setGoodsDesc("商城订单支付");
                HuifuCreateOrderResult result = huiFuService.createOrder(o);
                if(result.getBank_code()!=null&&result.getBank_code().equals("00000000")){
                    FsStorePayment mt=new FsStorePayment();
                    mt.setPaymentId(storePayment.getPaymentId());
                    mt.setTradeNo(result.getHf_seq_id());
                    fsStorePaymentMapper.updateFsStorePayment(mt);
                    redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                    Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                    return R.ok().put("result",resultMap);
                }
                else{
                    return R.error(result.getResp_desc());
                }
            }else  if (fsPayConfig.getType().equals("wx")){
                //创建微信订单
                WxPayConfig payConfig = new WxPayConfig();
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setKeyPath(null);
                payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
                wxPayService.setConfig(payConfig);
                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                orderRequest.setBody("商城订单支付");
                orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                orderRequest.setTradeType("JSAPI");
                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                //调用统一下单接口，获取"预支付交易会话标识"
                try {
                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                    return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0);
                } catch (WxPayException e) {
                    e.printStackTrace();
                    throw new CustomException("支付失败" + e.getMessage());
                }
            }
        } catch (WxErrorException e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }
        return R.error("无支付类型");
    }

    @Login
    @ApiOperation("亲友支付")
    @PostMapping("/otherPaymentRemain")
    @Transactional
    public R otherPaymentRemain(@Validated @RequestBody FsStoreOrderOtherPayParam param, HttpServletRequest request){
        final WxMaService wxService = WxMaConfiguration.getMaService(properties.getConfigs().get(0).getAppid());
        try {
            String ip = IpUtil.getRequestIp();
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
            FsUser user=userService.selectFsUserByMaOpenId(session.getOpenid());
            if(user==null){
                //创建
                user=new FsUser();
                user.setUsername("");
                user.setNickname("微信用户");
                user.setStatus(1);
                user.setMaOpenId(session.getOpenid());
                user.setUnionId(session.getUnionid());
                user.setIsWeixinAuth(0);
                user.setLastIp(ip);
                user.setCreateTime(new Date());
                userService.insertFsUser(user);
            }
            FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
            if(order==null){
                return R.error("订单不存在");
            }
            if(order.getStatus()!= OrderInfoEnum.STATUS_2.getValue()){
                return R.error("待收货订单可申请支付尾款");
            }
            if(order.getPayType().equals(1)){
                return R.error("此订单已支付");
            }
            //只有顺风才可以付尾
            if(!order.getDeliverySn().trim().equals("SF")){
                return R.error("只有顺丰物流支持尾款支付");
            }

            if(!order.getIsPayRemain().equals(0)){
                return R.error("此订单已支付");
            }
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
            String json = configService.selectConfigByKey("store.pay");
            FsPayConfig fsPayConfig = JSON.parseObject(json, FsPayConfig.class);
            FsStorePayment storePayment=new FsStorePayment();
            storePayment.setCompanyId(order.getCompanyId());
            storePayment.setCompanyUserId(order.getCompanyUserId());
            storePayment.setStatus(0);
            storePayment.setPayMode(fsPayConfig.getType());
            storePayment.setPayCode(payCode);
            storePayment.setPayMoney(order.getPayDelivery());
            storePayment.setCreateTime(new Date());
            storePayment.setPayTypeCode("weixin");
            storePayment.setBusinessType(2);
            storePayment.setRemark("商城订单尾款支付");
            storePayment.setOpenId(user.getRealName());
            storePayment.setUserId(user.getUserId());
            storePayment.setBusinessOrderId(order.getId().toString());
            storePayment.setOrderId(order.getId());
            storePayment.setIsPayRemain(1);
            fsStorePaymentMapper.insertFsStorePayment(storePayment);

            if (fsPayConfig.getType().equals("hf")){
                HuiFuCreateOrder o = new HuiFuCreateOrder();
                o.setTradeType("T_MINIAPP");
                o.setOpenid(user.getMaOpenId());
                o.setReqSeqId("store-"+storePayment.getPayCode());
                o.setTransAmt(storePayment.getPayMoney().toString());
                o.setGoodsDesc("商城订单支付");
                HuifuCreateOrderResult result = huiFuService.createOrder(o);
                if(result.getBank_code()!=null&&result.getBank_code().equals("00000000")){
                    FsStorePayment mt=new FsStorePayment();
                    mt.setPaymentId(storePayment.getPaymentId());
                    mt.setTradeNo(result.getHf_seq_id());
                    fsStorePaymentMapper.updateFsStorePayment(mt);
                    redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                    Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                    return R.ok().put("result",resultMap);
                }
                else{
                    return R.error(result.getResp_desc());
                }
            }else  if (fsPayConfig.getType().equals("wx")){
                //创建微信订单
                WxPayConfig payConfig = new WxPayConfig();
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setKeyPath(null);
                payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
                wxPayService.setConfig(payConfig);
                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                orderRequest.setBody("商城订单支付");
                orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                orderRequest.setTradeType("JSAPI");
                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                //调用统一下单接口，获取"预支付交易会话标识"
                try {
                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                    return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0);
                } catch (WxPayException e) {
                    e.printStackTrace();
                    throw new CustomException("支付失败" + e.getMessage());
                }
            }
        } catch (WxErrorException e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }
        return R.error("无支付类型");
    }


    @Login
    @ApiOperation("取消订单")
    @PostMapping("/cancelOrder")
//    @Log(title = "取消订单", businessType = BusinessType.UPDATE)
    public R cancelOrder( @Validated @RequestBody FsStoreOrderCancelParam param, HttpServletRequest request){
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if (ObjectUtil.isNull(order)) {
            throw new CustomException("订单不存在");
        }
        if (order.getStatus() !=0) {
            throw new CustomException("非法操作");
        }
        orderService.cancelOrder(param.getOrderId());

        return R.ok("操作成功");
    }
    @Login
    @ApiOperation("物流查询")
    @PostMapping("/getExpress")
    public R getExpress( @Validated @RequestBody FsStoreOrderExpressParam param, HttpServletRequest request){
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if (ObjectUtil.isNull(order)) {
            throw new CustomException("订单不存在");
        }
        if (order.getStatus() <2) {
            throw new CustomException("未发货订单不能查询");
        }
        return orderService.getExpress(order);
    }


    @Login
    @ApiOperation("确认套餐订单")
    @PostMapping("/confirmPackageOrder")
    public R confirmPackageOrder(@Validated @RequestBody FsStoreConfirmPackageIdOrderParam param, HttpServletRequest request){
        return orderService.confirmPackageOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("计算套餐订单")
    @PostMapping("/computedPackageOrder")
    public R computedPackageOrder(@Validated @RequestBody FsStoreComputedPackageIdOrderParam param, HttpServletRequest request){
        return orderService.computedPackageOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("创建订单")
    @PostMapping("/createPackageOrder")
    public R createPackageOrder(@Validated @RequestBody FsStorePackageOrderCreateParam param, HttpServletRequest request){
        return orderService.createPackageOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("完成订单")
    @PostMapping("/finishOrder")
    public R finishOrder( @Validated @RequestBody FsStoreOrderFinishParam param, HttpServletRequest request){
        return orderService.finishOrder(param.getOrderId());
    }


    @Login
    @ApiOperation("获取订单总数")
    @GetMapping("/getOrderCount")
    public R getOrderCount( HttpServletRequest request){
        Integer count0=orderService.selectFsStoreOrderCount(Long.parseLong(getUserId()),0);
        Integer count1=orderService.selectFsStoreOrderCount(Long.parseLong(getUserId()),1);
        Integer count2=orderService.selectFsStoreOrderCount(Long.parseLong(getUserId()),2);
        Integer afterSalesCount=afterSalesService.selectFsStoreAfterSalesCount(Long.parseLong(getUserId()),0);
        return R.ok().put("count0",count0).put("count1",count1).put("count2",count2).put("afterSalesCount",afterSalesCount);
    }


}
