package com.bohuikeji.delivery.backstage.controller.open;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bohuikeji.delivery.backstage.constants.KeyConst;
import com.bohuikeji.delivery.backstage.constants.WxAppEm;
import com.bohuikeji.delivery.backstage.controller.api.customer.CustomerV2Api;
import com.bohuikeji.delivery.backstage.entity.*;
import com.bohuikeji.delivery.backstage.entity.open.VoBase;
import com.bohuikeji.delivery.backstage.entity.open.vo.CourierVo;
import com.bohuikeji.delivery.backstage.entity.open.vo.OrderRecordVo;
import com.bohuikeji.delivery.backstage.entity.open.vo.PageVo;
import com.bohuikeji.delivery.backstage.entity.open.vo.OrderVo;
import com.bohuikeji.delivery.backstage.entity.vo.CourierAddressVo;
import com.bohuikeji.delivery.backstage.entity.wx.TWxUser;
import com.bohuikeji.delivery.backstage.service.*;
import com.bohuikeji.delivery.backstage.service.third.ThirdUtils;
import com.bohuikeji.frame.module.admin.base.ApiController;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.entity.sys.SysError;
import com.bohuikeji.frame.module.admin.service.ISysConfigService;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import com.bohuikeji.frame.module.admin.wxpay.WXPayUtil;
import com.bohuikeji.frame.module.admin.wxpayv3.WxPayV3Util;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 订单开放平台接口
 * @author
 */
@Api(tags = {"订单开放平台"})
@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping("/api/open/order")
public class OrderOpenApi  extends ApiController {
    final RedisUtil redisUtil;
    final ITOrderService orderService;
    final ITPayService payService;
    final ISysConfigService sysConfigService;
    final RabbitTemplate rabbitTemplate;
    final ITCourierService courierService;
    final ITOpenService openService;
    final ITCustomerTemplateService customerTemplateService;
    final ITCustomerService customerService;
    final ITCustomerWalletService customerWalletService;
    final CustomerV2Api customerV2Api;
    final ITConfigService configService;
    final ITOrderCircuService circuService;
    final ITOpenCallbackService callbackService;
    final ITCustomerWalletService walletService;
    final ITRefundService refundService;
    final ThirdUtils thirdUtils;



    /**
     * 订单计费价格估算接口
     * @param id
     * @param order
     * @return
     */
    @ApiOperation("订单计费价格估算接口")
    @PostMapping("/post/estimate")
    APIEntity estimateOrder(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id, @RequestBody TOrder order) throws Exception {
        return createOrder(id,true,order);
    }

    /**
     * 订单计费价格估算接口
     * @param id
     * @param order
     * @return
     */
   /* @ApiOperation("#######测试下单#######3")
    @PostMapping("/test/create/order")
    APIEntity testOrder(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id, Integer orderId,String cargoName) throws Exception {
        TOrder order = orderService.getById(orderId);
        return createOrder(id,false,order);
    }*/


    /**
     * 下单接口
     * 【计费规则】：如开放平台账户的CustomerId已经绑定了计费模板，则按计费模板第一条数据走，未绑定计费模板，按当地城市第一条数据走
     * @return
     */
    @ApiOperation("下单接口")
    @PostMapping("/post/create")
    APIEntity createOrder(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id, boolean isEstimate,@RequestBody TOrder order) throws Exception {
        TOpen open=openService.getById(id);
        if(open.getCustemerId()==null){
            return APIEntity.fail("该开放平台尚未绑定客户账号，请联系管理员进行绑定!");
        }
        if (order.getTest()==null){
            return APIEntity.fail("参数：test缺失！");
        }
        TCustomerWallet wallet= walletService.getOne(new QueryWrapper<TCustomerWallet>().eq("customer_id",open.getCustemerId()),false);
        if (wallet==null){
            wallet=new TCustomerWallet();
            wallet.setCustomerId(open.getCustemerId());
            wallet.setWalletPrice(new BigDecimal("0"));
            wallet.setRefuntPrice(new BigDecimal("0"));
            wallet.setFranId(1);
            wallet.setWalletState("提现");
            walletService.save(wallet);
        }
        if (wallet.getWalletPrice().compareTo(order.getOrderExpectPrice())<0){
            return APIEntity.fail("账户余额不足，无法下单").setStatus(440);
        }
        //设置下单人
        order.setPlayerId(open.getCustemerId());
        //物品重量不得最低重量5kg
        if (order.getCargoWeight()==null||order.getCargoWeight()<1){
            order.setCargoWeight(1);
        }
        //初始化物品价值
        if(StringUtils.isNotBlank(order.getWorthName())){
            int worth=0;
            try{
                worth=Integer.parseInt(order.getWorthName());
            }catch (Exception e){
                return APIEntity.fail("物品价值格式不正确，必须为：1-10000之间的整数，示例：{}");
            }
            if(worth<1||worth>10000){
                return APIEntity.fail("物品价值格式不正确，必须为：1-10000之间的整数，示例：{}");
            }
            order.setWorthName(worth+"元");
        }
        else{
            order.setWorthName("50元");
        }
        order.setOrderChannel(open.getName());
        order.setSettWay(open.getSettWay());
        //设置开放平台订单支付方式只能是钱包
        order.setType("WALLET");
        //初始化订单计费各项
        order=openService.openOrderInit(open.getCustemerId(),order);
        if(isEstimate){
            return customerV2Api.estimate(order);
        }
        log.error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@开放平台订单信息@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@：{}",order);
        return customerV2Api.insertOrderPayment(open.getCustemerId(),order,null);
    }

    /**
     * 查询订单详情
     * @param orderNum 订单编号
     * @return
     */
    @ApiOperation("查询订单详情")
    @GetMapping("/get/detail/number")
    APIEntity getOrder(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String orderNum){
        TOrder order=checkOpenOrderAuth(id,orderNum);
        if(order==null){
            return APIEntity.fail("没有找到该订单，订单号："+orderNum);
        }
        return APIEntity.success(VoBase.copy(order,OrderVo.class));
    }

    /**
     * 查询订单配送员信息
     * @param orderNum 订单编号
     * @return
     */
    @ApiOperation("查询订单配送员信息")
    @GetMapping("/get/detail/courier")
    APIEntity getCourier(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String orderNum){
        TOrder order=checkOpenOrderAuth(id,orderNum);
        if(order==null){
            return APIEntity.fail("没有找到该订单，订单号："+orderNum);
        }
        if("待接单".equals(order.getOrderStatus())){
            return APIEntity.fail("没有找到该订单，该订单尚未接单，暂无配送员信息");
        }
        CourierVo courierVo=null;
        if (order.getThird()){
            courierVo= thirdUtils.courierInfo(order);
            if (courierVo==null){
                return APIEntity.fail("无法找到该订单的配送员位置信息，订单号："+order.getOrderNum());
            }
        }else {
            TCourier courier=courierService.getById(order.getCourierId());
            if (courier==null){
                return APIEntity.fail("无法找打该到单的配送员位置信息，订单号："+order.getOrderNum());
            }
            courierVo= VoBase.copy(courier,CourierVo.class);
            CourierAddressVo courierAddressVo=redisUtil.get(KeyConst.REDIS_COURIER_ADDRESS+courier.getCourierId(), CourierAddressVo.class);
            if (courierAddressVo!=null){
                courierVo.setLastLocation(courierAddressVo.getAddress());
            }
        }
        return APIEntity.success(courierVo);
    }

    /*@ApiOperation("查询订单配送员信息")
    @GetMapping("/get/detail/courier")
    APIEntity getCourier(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String orderNum){
        TOrder order=checkOpenOrderAuth(id,orderNum);
        if(order==null){
            return APIEntity.fail("没有找到该订单，订单号："+orderNum);
        }
        if("待接单".equals(order.getOrderStatus())){
            return APIEntity.fail("没有找到该订单，该订单尚未接单，暂无配送员信息");
        }
        TCourier courier=courierService.getById(order.getCourierId());
        if (courier==null){
            return APIEntity.fail("无法找打该订单的配送员信息，订单状态："+order.getOrderStatus());
        }
        CourierVo courierVo=VoBase.copy(courier,CourierVo.class);
        CourierAddressVo courierAddressVo=redisUtil.get(KeyConst.REDIS_COURIER_ADDRESS+courier.getCourierId(), CourierAddressVo.class);
        if (courierAddressVo!=null){
            courierVo.setLastLocation(courierAddressVo.getAddress());
        }
        courierVo.setCourierPhone(order.getCourierPhone());
        return APIEntity.success(courierVo);
    }*/

    /**
     * 客户预取消订单
     * @param id
     * @param orderNum
     * @return
     */
    @ApiOperation("客户预取消订单")
    @GetMapping("/get/pre/cancel/number")
    APIEntity preCancel(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String orderNum){
        TOrder order=checkOpenOrderAuth(id,orderNum);
        if(order==null){
            return APIEntity.fail("没有找到该订单，订单号："+orderNum);
        }
        if ("已取消".equals(order.getOrderStatus())){
            return APIEntity.fail("该订单已经取消了");
        }
        String[] states={"已完成","派送中","待派送"};
        for (String state : states) {
            if(state.equals(order.getOrderStatus())){
                return APIEntity.fail("尊敬的客户您好，您的订单状态为"+order.getOrderStatus()+"不可以取消");
            }
        }
        return APIEntity.success(refundService.getPreCancelInfo(order));
    }


    /**
     * 取消订单
     * @param id
     * @param orderNum
     * @return
     */
    @ApiOperation("取消订单")
    @GetMapping("/get/cancel/number")
    APIEntity cancel(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String orderNum){
        TOrder order=checkOpenOrderAuth(id,orderNum);
        if(order==null){
            return APIEntity.fail("没有找到该订单，订单号："+orderNum);
        }
        if ("已取消".equals(order.getOrderStatus())){
            return APIEntity.fail("该订单已经取消了");
        }
        return customerV2Api.cancel(String.valueOf(order.getOrderId()),order.getPlayerId(),"open");
    }

    /**
     * 查询我的订单列表
     * @param id 账户id
     * @param status //订单状态，可选(all，wait，run，end，fail)，默认：all
     * @param pageSize
     * @param pageNo
     * @return
     */
    @ApiOperation("查询我的订单列表")
    @GetMapping("/get/list")
    APIEntity list(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String status,Integer pageSize,Integer pageNo){
        TOpen open=openService.getCacheById(id);
        QueryWrapper<TOrder> qu=new QueryWrapper<TOrder>().eq("player_id",open.getCustemerId());
        if (StringUtils.isNotBlank(status)){
            switch (status){
                case "wait":
                    qu.eq("order_status","待接单");break;
                case "run":
                    qu.in("order_status","待支付","待取件","取件中","待派送","派送中");break;
                case "end":
                    qu.eq("order_status","已完成");break;
                case "fail":
                    qu.in("order_status","已取消","已退款","异常");break;
                default:break;
            }
        }
        //分页查询，并转换为VO
        PageVo<OrderVo> pageVo=VoBase.pageCopy(orderService.page(new Page<TOrder>(pageNo,pageSize),qu),OrderVo.class);
        return APIEntity.success(pageVo);
    }

    /**
     * 查询订单状态变更记录
     * @param id
     * @param orderNum
     * @return
     */
    @ApiOperation("查询订单状态变更记录")
    @GetMapping("/get/record")
    APIEntity orderRecord(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String orderNum){
        List<TOrderCircu> orderCircuList=circuService.list(new QueryWrapper<TOrderCircu>().eq("order_num",orderNum));
        List<OrderRecordVo> recordVos=new ArrayList<>(orderCircuList.size());
        orderCircuList.forEach(o->{
            recordVos.add(VoBase.copy(o,OrderRecordVo.class));
        });
        return APIEntity.success(recordVos);
    }

    /**
     * 查询账户余额
     * @param id
     * @return
     */
    @ApiOperation("查询账户余额")
    @GetMapping("/get/balance")
    APIEntity getWalletBalance(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id){
        TOpen open=openService.getById(id);
        TCustomerWallet customerWallet = customerWalletService.getByCustomerId(open.getCustemerId());
        if (customerWallet == null){
            return APIEntity.fail("当前账户尚未充值钱包，请充值！");
        }
        //计算钱包余额
        if (customerWallet.getWalletPrice().compareTo(new BigDecimal("6"))<0){
            return APIEntity.fail("账户余额不足，当前余额："+customerWallet.getWalletPrice());
        }
        return APIEntity.success(customerWallet.getWalletPrice());
    }

    /**
     * 绑定订单通知
     * @param id
     * @param orderNum
     * @param url
     * @return
     */
    @ApiOperation("绑定订单通知")
    @GetMapping("/get/binding")
    APIEntity orderBinding(@ApiIgnore @RequestAttribute("JwtOpenId") Integer id,String orderNum,String url){
        if(StringUtils.isBlank(url)){
            return APIEntity.fail("参数[url]为空");
        }
        TOrder order=checkOpenOrderAuth(id,orderNum);
        if(order==null){
            return APIEntity.fail("没有找到该订单，订单号："+orderNum);
        }
        try {
            url=URLDecoder.decode(url, "utf-8");
        } catch (UnsupportedEncodingException e) {
            return APIEntity.fail("url解码失败，请检查参数是否正确！");
        }
        if(!StringUtils.isURL(url)){
            return APIEntity.fail("参数[url]无法识别，请检查是否为URL格式，或确认是否已对原始链接进行UrlCode编码。");
        }
        TOpenCallback callback=callbackService.getOne(new QueryWrapper<TOpenCallback>().eq("order_num",orderNum));
        if(callback==null){
            callback=new TOpenCallback().setCallbackUrl(url).setOpenId(id).setOrderId(order.getOrderId()).setOrderNum(orderNum);
            if(callbackService.save(callback)){
                return APIEntity.success("绑定成功！");
            }
        }
        callback.setCallbackUrl(url).setOpenId(id).setOrderId(order.getOrderId()).setOrderNum(orderNum);
        if(callbackService.updateById(callback)){
            return APIEntity.success("绑定更新成功！");
        }
        return APIEntity.fail("糟糕~系统目前正在排队处理中，请您稍后再试~~");
    }


    /**
     * 检查开放平台订单范文权限，限制查询和操作自己的订单
     * @param openId 开放平台Id
     * @param orderNum 订单号
     * @return
     */
    @ApiOperation("检查开放平台订单范文权限，限制查询和操作自己的订单")
    private TOrder checkOpenOrderAuth(Integer openId,String orderNum){
        TOpen open=openService.getCacheById(openId);
        TOrder order=orderService.getByNum(orderNum);
        if(open==null||order==null){
            return null;
        }
        if(!order.getPlayerId().equals(open.getCustemerId())){
            return null;
        }
        return order;
    }
}
