package com.xxfc.platform.order.rest;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.common.context.BaseContextHandler;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.rest.CommonBaseController;
import com.github.wxiaoqi.security.common.util.ClientUtil;
import com.github.wxiaoqi.security.common.util.Query;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.github.wxiaoqi.security.common.vo.PageParam;
import com.xxfc.platform.order.biz.BaseOrderBiz;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.entity.BaseOrder;
import com.xxfc.platform.order.pojo.order.CancelOrderDTO;
import com.xxfc.platform.order.pojo.order.OrderPageVO;
import com.xxfc.platform.order.pojo.pay.RentVehicleOrderPayVO;
import com.xxfc.platform.universal.constant.enumerate.PayChannelEnum;
import com.xxfc.platform.universal.feign.ThirdFeign;
import com.xxfc.platform.universal.vo.OrderPayVo;
import com.xxfc.platform.universal.vo.OrderRefundVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_TRUE;

@Controller
@RequestMapping("baseOrder")
@Api(value="订单",tags={"订单"})
@Slf4j
public class BaseOrderController extends CommonBaseController {

    @Autowired
    BaseOrderBiz baseOrderBiz;

    @Autowired
    ThirdFeign thirdFeign;

    @Autowired
    UserFeign userFeign;

    @Value("${gateway.host}")
    String host;

    @Value("${gateway.order}")
    String order;

    String notifyUrl = "/baseOrder/app/unauth/notifyUrl";

    public static final Integer STATUS_SUCCESS = 1;

    @RequestMapping(value = "/page",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "订单列表")
    @IgnoreClientToken
    public ObjectRestResponse<PageDataVO<OrderPageVO>> list(QueryOrderDTO dto){
        //查询列表数据
        if(StringUtils.isBlank(BaseContextHandler.getUserID())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }
        dto.setCrtUser(Integer.valueOf(BaseContextHandler.getUserID()));
        Query query = new Query(dto);
        return new ObjectRestResponse<>().data(PageDataVO.pageInfo(query, () -> baseOrderBiz.pageByParm(query.getSuper())));
    }

    @RequestMapping(value = "/list",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "订单列表")
    @IgnoreClientToken
    public ObjectRestResponse<PageDataVO<OrderPageVO>> getOrderList(QueryOrderDTO dto){
        Query query = new Query(dto);
        return new ObjectRestResponse<>().data(PageDataVO.pageInfo(query, () -> baseOrderBiz.selectListAll()));
    }

    @RequestMapping(value = "/selectByUser",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "订单列表")
    @IgnoreClientToken
    public ObjectRestResponse<PageDataVO<OrderPageVO>> selectByUser(QueryOrderList dto){
        Query query = new Query(dto);
        return new ObjectRestResponse<>().data(PageDataVO.pageInfo(query, () -> baseOrderBiz.listOrder(query.getSuper())));
    }


//    @RequestMapping(value = "/company/page",method = RequestMethod.GET)
//    @ResponseBody
//    @ApiOperation(value = "结合后台人员所属公司查询订单列表")
//    @IgnoreClientToken
//    public ObjectRestResponse<PageDataVO<OrderPageVO>> companyList(QueryOrderDTO dto){
//        //查询列表数据
//        if(StringUtils.isBlank(BaseContextHandler.getUserID())) {
//            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
//        }
//        dto.setCrtCompanyId(userFeign.userinfoByToken(BaseContextHandler.getToken()).getData().getCompanyId());
//        Query query = new Query(dto);
//        return new ObjectRestResponse<>().data(PageDataVO.pageInfo(query, () -> baseOrderBiz.pageByParm(query.getSuper())));
//    }

    @ApiOperation("订单详情")
    @RequestMapping(value = "/{no}",method = RequestMethod.GET)
    @IgnoreClientToken
    @ResponseBody
    public ObjectRestResponse<OrderPageVO> get(@PathVariable String no){
        //查询列表数据
        if(StringUtils.isBlank(BaseContextHandler.getUserID())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }

        Query query = initQuery(no);
        PageDataVO<OrderPageVO> page = PageDataVO.pageInfo(query, () -> baseOrderBiz.pageByParm(query.getSuper()));
        if(page.getData().isEmpty()) {
            throw new BaseException(ResultCode.NOTEXIST_CODE);
        }
        return new ObjectRestResponse<>().data(page.getData().get(0));
    }

    @ApiOperation("结合后台人员所属公司查询订单详情")
    @RequestMapping(value = "/company/{no}",method = RequestMethod.GET)
    @IgnoreClientToken
    @ResponseBody
    public ObjectRestResponse<OrderPageVO> companyGet(@PathVariable String no){
        //查询列表数据
        if(StringUtils.isBlank(BaseContextHandler.getUserID())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }

        Query query = initCompanyQuery(no);
        PageDataVO<OrderPageVO> page = PageDataVO.pageInfo(query, () -> baseOrderBiz.pageByParm(query.getSuper()));
        if(page.getData().isEmpty()) {
            throw new BaseException(ResultCode.NOTEXIST_CODE);
        }
        return new ObjectRestResponse<>().data(page.getData().get(0));
    }

//    @ApiOperation("根据订单详情处理信息")
//    @RequestMapping(value = "/handle/{no}",method = RequestMethod.GET)
//    @IgnoreClientToken
//    @ResponseBody
//    public ObjectRestResponse<OrderPageVO> get(@PathVariable String no){
//        //查询列表数据
//        if(StringUtils.isBlank(BaseContextHandler.getUserID())) {
//            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
//        }
//        Query query = initQuery(no);
//        PageDataVO<OrderPageVO> page = PageDataVO.pageInfo(query, () -> baseOrderBiz.pageByParm(query.getSuper()));
//        if(page.getData().isEmpty()) {
//            throw new BaseException(ResultCode.NOTEXIST_CODE);
//        }
//        return new ObjectRestResponse<>().data(page.getData().get(0));
//    }

    private Query initQuery(String no) {
        QueryOrderDetailDTO qodd = new QueryOrderDetailDTO();
        qodd.setCrtUser(Integer.valueOf(BaseContextHandler.getUserID()));
        qodd.setNo(no);
        qodd.setLimit(1);
        qodd.setPage(1);
        Query query = new Query(qodd);
        return query;
    }

    private Query initCompanyQuery(String no) {
        QueryOrderDetailDTO qodd = new QueryOrderDetailDTO();
        //查询公司id
        UserDTO userDto = userFeign.userinfoByToken(BaseContextHandler.getToken()).getData();
        qodd.setCrtCompanyId(userDto.getCompanyId());
        qodd.setNo(no);
        qodd.setLimit(1);
        qodd.setPage(1);
        Query query = new Query(qodd);
        return query;
    }

    @RequestMapping(value = "/pay",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "订单支付")
    @IgnoreClientToken
    public ObjectRestResponse pay(@RequestBody RentVehicleOrderPayVO vo){
        //查询列表数据
        if(StringUtils.isBlank(BaseContextHandler.getUserID())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }

        OrderPayVo orderPayVo = BeanUtil.toBean(vo, OrderPayVo.class);

        BaseOrder baseOrder = baseOrderBiz.selectOne(new BaseOrder(){{
            setNo(vo.getOrderNo());
        }});

        if(null == baseOrder || !OrderStatusEnum.ORDER_UNPAY.getCode().equals(baseOrder.getStatus())) {
            throw new BaseException("订单不可支付", ResultCode.EXCEPTION_CODE);
        }

        orderPayVo.setAmount(baseOrder.getRealAmount().multiply(new BigDecimal("100")).intValue());
        orderPayVo.setBody(baseOrder.getName());
        orderPayVo.setBuyerIp(StringUtils.defaultIfBlank(request.getHeader("userHost"), ClientUtil.getClientIp(request)));
        orderPayVo.setChannel(PayChannelEnum.ORDER_CRT.getCode());
        orderPayVo.setNotifyUrl(host+ order+ notifyUrl+ "?orderNo="+ baseOrder.getNo());
        orderPayVo.setSubject(baseOrder.getName());
        orderPayVo.setUserId(baseOrder.getUserId());
        ObjectRestResponse response = BeanUtil.toBean(thirdFeign.wx(orderPayVo), ObjectRestResponse.class);
        return response;
    }

    @RequestMapping(value = "/cancel/{no}",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "取消订单")
    @IgnoreClientToken
    public ObjectRestResponse cancel(@PathVariable String no, @RequestBody CancelOrderDTO cancelOrderDto){
        //查询列表数据
        if(StringUtils.isBlank(BaseContextHandler.getUserID())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }
        BaseOrder dbBaseOrder = baseOrderBiz.selectOne(new BaseOrder(){{
            setNo(no);
        }});
        if(null == dbBaseOrder || !BaseContextHandler.getUserID().equals(dbBaseOrder.getUserId().toString())) {
            throw new BaseException(ResultCode.NOTEXIST_CODE);
        }
        dbBaseOrder.setCancelReason(cancelOrderDto.getCancelReason());
        baseOrderBiz.cancel(dbBaseOrder);
        return ObjectRestResponse.succ();
    }

    @RequestMapping(value = "/app/unauth/notifyUrl",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "订单支付回调")
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse notifyUrl(NotifyUrlDTO dto){
        //判断是否成功，并且订单是未支付状态，则添加支付编号和修改状态
        if(StrUtil.isNotBlank(dto.getOrderNo())){
            BaseOrder baseOrder = baseOrderBiz.selectOne(new BaseOrder(){{
                setNo(dto.getOrderNo());
            }});

            if(OrderStatusEnum.ORDER_UNPAY.getCode().equals(baseOrder.getStatus())) {
                BaseOrder updateOrder = new BaseOrder(){{
                    setNo(dto.getOrderNo());
                    setStatus(OrderStatusEnum.ORDER_TOSTART.getCode());
                    setOutTradeNo(dto.getTradeNo());
                    setHasPay(SYS_TRUE);
                    setPayTime(System.currentTimeMillis());
                }};
                baseOrderBiz.updateSelectiveById(updateOrder);
            }else {
                log.error(" exception notifyUrl : " + JSONUtil.toJsonStr(dto));
            }
        }else {
            log.error(" exception notifyUrl : " + JSONUtil.toJsonStr(dto));
        }
        return new ObjectRestResponse().rel(true);
    }

    /**
     * 订单查询类
     */
    @Data
    public class QueryOrderDTO extends PageParam {
        @ApiModelProperty(hidden = false)
        private Integer crtUser;

        @ApiModelProperty(hidden = false)
        private Integer crtCompanyId;

        @ApiModelProperty(value = "订单状态\n" +
                "0--删除\n" +
                "1--创建订单\n" +
                "2--取消\n" +
                "3--待付款\n" +
                "4--待出行\n" +
                "5--出行中（进行中）\n" +
                "6--已完成")
        private Integer status;

    }

    /**
     * 订单查询类
     */
    @Data
    public class QueryOrderDetailDTO extends QueryOrderDTO {
        private String no;
    }

    @Data
    public class QueryOrderList extends QueryOrderDetailDTO {

       private Long startTime;

       private Long endTime;

       private Integer startCompanyId;
    }

    @Data
    public class NotifyUrlDTO{
        //订单号
        @ApiModelProperty(value = "订单号")
        private String orderNo;

        //订单号
        @ApiModelProperty(value = "支付订单（流水）号")
        private String tradeNo;
    }
}