package com.bohuikeji.delivery.backstage.controller.api.rental;

import cn.hutool.json.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bohuikeji.delivery.backstage.constants.WxAppEm;
import com.bohuikeji.delivery.backstage.constants.huLaLaConst;
import com.bohuikeji.delivery.backstage.entity.*;
import com.bohuikeji.delivery.backstage.entity.rental.TRentalCarOrder;
import com.bohuikeji.delivery.backstage.entity.rental.TRentalPay;
import com.bohuikeji.delivery.backstage.entity.third.OrderDetailDO;
import com.bohuikeji.delivery.backstage.entity.wx.TWxUser;
import com.bohuikeji.delivery.backstage.pay.AliPay;
import com.bohuikeji.delivery.backstage.pay.KuaiShouPay;
import com.bohuikeji.delivery.backstage.service.*;
import com.bohuikeji.delivery.backstage.util.capacity.HllUtils;
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.back.DataPage;
import com.bohuikeji.frame.module.admin.utils.NumberUtils;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Api(tags = {"租车服务相关接口"})
@RestController
@Slf4j
@RequestMapping("/api/rental")
@RequiredArgsConstructor
public class RentalCarOrderApi extends ApiController {

    final ITRentalCarOrderService rentalCarOrderService;
    final ITCustomerService customerService;
    final ITRentalPayService rentalPayService;
    final ITRefundService refundService;
    final IWxUserService wxUserService;
    final RedisUtil redisUtil;

    @ApiOperation("客户App下单预算金额")
    @PostMapping("/place/estimate")
    public APIEntity estimate(@RequestBody @ApiParam(name="order",value="订单信息") TRentalCarOrder carOrder) {
        log.info("租车订单信息：{}",carOrder);
        try {
            carOrder = rentalCarOrderService.getCarOrderCharg(carOrder);
        }catch (Exception e){
            //log.error("下单金额计算失败，订单参数错误",e);
        }
        JSONObject json=new JSONObject();
        json.put("monSum",carOrder.getRentalExpectPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
        json.put("rentalCarInterval",carOrder.getRentalCarInterval());
        json.put("orderExpectTime",carOrder.getRentalOrderTime());
        log.info("【下单金额预估】订单：{}，返回：{}",carOrder.getRentalOrderNum(),json.toJSONString());
        return APIEntity.success(json);
    }

    @ApiOperation("租车业务获取时间数据")
    @GetMapping("/get/date/time/array")
    @ApiImplicitParams({
            @ApiImplicitParam(name="takeCarTime",value="取车时间",dataType="LocalDateTime", paramType = "query",example="2022-09-20 12:54:26",required=true),
            @ApiImplicitParam(name="stillCarTime",value="还车时间",dataType="LocalDateTime", paramType = "query",example="2022-09-26 09:30:16",required=true)})
    public APIEntity dateTineArray(String takeCarTime, String stillCarTime) {
        LocalDateTime takeTime=LocalDateTime.parse(takeCarTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime dstillTime=LocalDateTime.parse(stillCarTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return APIEntity.success(rentalCarOrderService.getDateTimeArray(takeTime,dstillTime));
    }


    /**
     * 下单APP
     * @param order
     * @return
     */
    @ApiOperation("客户下单支付接口")
    @PostMapping("/order/payment")
    @ApiImplicitParams({})
    public APIEntity insertOrderPayment(@ApiIgnore("id") @RequestAttribute("JwtUserId") Integer id, @RequestBody TRentalCarOrder carOrder, HttpServletRequest request) throws Exception {
        log.info("支付时租车订单数据：{},下单人id:{}",carOrder,id);
        if(carOrder==null){
            log.error("未找到该订单信息");
            return APIEntity.fail("未找到该订单信息！");
        }
        TCustomer customer = customerService.getById(id);
        if(customer == null){
            return APIEntity.fail("账号不存在，请重新登陆！");
        }
        if(carOrder.getStillCarTime().compareTo(carOrder.getTakeCarTime())<0){
            return APIEntity.fail().setMessage("还车时间不得小于取车时间").setStatus(416);
        }
        carOrder.setPlayerId(customer.getCustomerId());
        carOrder.setPlayerPhone(customer.getCustomerPhone());
        carOrder.setRentalOrderNum(NumberUtils.get("L"));
        carOrder = rentalCarOrderService.getCarOrderCharg(carOrder);
        //rentalCarOrderService.save(carOrder);
        redisUtil.set("carOrder:rental:num:"+carOrder.getRentalOrderNum(),carOrder,60*60*12);
        return rentalPayService.getPayAPIEntity(carOrder,request);
    }


    /**
     * 支付宝小程序授权接口
     * @param id
     * @param code
     * @return
     */
    @ApiOperation("支付宝小程序授权接口(支付宝)")
    @PostMapping("/ali/pay/grant")
    @ApiImplicitParams({
            @ApiImplicitParam(name="code",value="支付宝授权code",dataType="String", paramType = "query",example="111111",required=true)})
    public APIEntity kuaishouAuthorization(@ApiIgnore("id") @RequestAttribute("JwtUserId") Integer id, String code){
        if(wxUserService.list(new QueryWrapper<TWxUser>().eq("user_id",id).eq("wx_app_name","客户端小程序（支付宝）")).size()>0){
            return APIEntity.fail("已授权，请刷新");
        }
        String openId=null;
        TWxUser wxUser = new TWxUser();
        try {
            openId = AliPay.getUserId(code).getString("user_id");
            wxUser.setWxAppId(AliPayConfig.appID);
            wxUser.setWxAppType("ALICLIENT");
            wxUser.setWxAppName("客户端小程序（支付宝）");
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        log.info("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@openId：[{}]",openId);
        wxUser.setUserId(Long.valueOf(id));
        wxUser.setUserType(WxAppEm.WX_USER_TYPE_CUSTOMER);
        wxUser.setWxUserOpenid(openId);
        wxUserService.save(wxUser);
        return APIEntity.fail("授权成功！");
    }

    /**
     * 客户预取消订单
     * @param
     * @return
     */
    @ApiOperation("客户预取消订单")
    @GetMapping("/cancel/order")
    @ApiImplicitParams({
            @ApiImplicitParam(name="rentalId",value="订单id",dataType="Integer", paramType = "query",example="1",required=true)})
    public APIEntity cancel(@ApiIgnore("id") @RequestAttribute("JwtUserId") Integer id,String rentalId){
        log.info("订单id:{}",rentalId);
        TRentalCarOrder rentalCarOrder = rentalCarOrderService.getOne(new QueryWrapper<TRentalCarOrder>().eq("rental_id",rentalId).eq("player_id",id));
        log.info("订单信息:{}",rentalCarOrder);
        List<TRentalPay> rewardPays = rentalPayService.list(new QueryWrapper<TRentalPay>().eq("rental_id",rentalCarOrder.getRentalId()).eq("pay_status","已支付"));
        if(rewardPays.size()<1){
            rentalCarOrderService.updateById(rentalCarOrder.setRentalOrderStatus("已取消"));
            return APIEntity.success("尊敬的客户您好，您的订单已取消不可以重复取消");
        }
        TRefund refund = refundService.rentalCarCancel(rentalCarOrder,rewardPays);
        rentalCarOrderService.updateById(rentalCarOrder.setRentalOrderStatus("已取消"));
        return APIEntity.success("订单取消成功");
    }

    /**
     * 分页查询全部订单列表
     * 根据状态查询订单
     * @return
     */
    @ApiOperation("分页查询租车订单列表)")
    @GetMapping("/get/car/orderAll")
    @ApiOperationSupport(ignoreParameters = {"id","records","total","searchCount"})
    @ApiImplicitParams({
            @ApiImplicitParam(name="rentalOrderStatus",value="订单状态(全部,进行中,已完成)",dataType="String", paramType = "query")})
    public APIEntity getCarOrderAll(@RequestAttribute("JwtUserId") Integer id, DataPage page, String rentalOrderStatus){
        if (StringUtils.isBlank(rentalOrderStatus)){
            return APIEntity.fail("客户端参数为空！");
        }
        String type = null;
        page.setDesc("rental_id");
        QueryWrapper<TRentalCarOrder> queryWrapper=new QueryWrapper<TRentalCarOrder>().eq("player_id",id);
        switch (rentalOrderStatus){
            case "全部":
                ;break;
            case "进行中":
                queryWrapper.in("rental_order_status","待接单","用车中");break;
            case "已完成":
                queryWrapper.eq("rental_order_status","已完成");break;
            default:
                log.error("客户端参数错误，无法识别的参数值：[{}]",rentalOrderStatus);
                return APIEntity.fail("无法识别参数[orderStatus="+rentalOrderStatus+"]");
        }
        page = (DataPage) rentalCarOrderService.page(page,queryWrapper);

        return APIEntity.success(page);
    }

    /**
     * 根据订单id查询订单详情
     * @return
     */
    @ApiOperation("租车订单详情")
    @GetMapping("/get/car/order/info")
    //配置忽略参数
    @ApiOperationSupport(ignoreParameters = {"records","total","searchCount","id"})
    @ApiImplicitParams({
            @ApiImplicitParam(name="rentalId",value="租车订单id",dataType="Integer", paramType = "query")})
    public APIEntity<TRentalCarOrder> getCarOrderInfo(@RequestAttribute("JwtUserId") Integer id, Integer rentalId){
        TRentalCarOrder rentalCarOrder = rentalCarOrderService.getById(rentalId);
        if(rentalCarOrder==null){
            return APIEntity.fail("未找到该订单信息！");
        }
        return APIEntity.success(rentalCarOrder);
    }

    /**
     * 下单APP
     * @param order
     * @return
     */
    @ApiOperation("#############")
    @PostMapping("get/order/payment")
    @ApiImplicitParams({})
    public APIEntity getPayment(HttpServletRequest request) throws Exception {
        String str = "{\n" +
                "  \"carConfigId\": 2,\n" +
                "  \"isDriver\": true,\n" +
                "  \"isReturn\": true,\n" +
                "  \"stillAddress\": {\n" +
                "    \"adcode\": \"150104\",\n" +
                "    \"address\": \"内蒙古自治区呼和浩特市玉泉区西菜园街道三里营南巷富丽城A区\",\n" +
                "    \"area\": \"玉泉区\",\n" +
                "    \"city\": \"呼和浩特市\",\n" +
                "    \"cityId\": \"\",\n" +
                "    \"detail\": \"\",\n" +
                "    \"lat\": \"40.786888\",\n" +
                "    \"lng\": \"111.676263\",\n" +
                "    \"province\": \"内蒙古自治区\"\n" +
                "  },\n" +
                "  \"stillCarTime\": \"2022-10-14 00:00\",\n" +
                "  \"takeAddress\": {\n" +
                "    \"adcode\": \"150104\",\n" +
                "    \"address\": \"内蒙古自治区呼和浩特市玉泉区西菜园街道三里营南巷富丽城A区\",\n" +
                "    \"area\": \"玉泉区\",\n" +
                "    \"city\": \"呼和浩特市\",\n" +
                "    \"cityId\": \"\",\n" +
                "    \"detail\": \"\",\n" +
                "    \"lat\": \"40.786888\",\n" +
                "    \"lng\": \"111.676263\",\n" +
                "    \"province\": \"内蒙古自治区\"\n" +
                "  },\n" +
                "  \"takeCarTime\": \"2022-10-1 01:00\",\n" +
                "  \"type\": \"aliClient\"\n" +
                "}";
        TRentalCarOrder carOrder = JSONObject.parseObject(str,TRentalCarOrder.class);
        if(carOrder==null){
            log.error("未找到该订单信息");
            return APIEntity.fail("未找到该订单信息！");
        }

        TCustomer customer = customerService.getById(272);
        if(customer == null){
            return APIEntity.fail("账号不存在，请重新登陆！");
        }
        carOrder.setPlayerId(customer.getCustomerId());
        carOrder.setPlayerPhone(customer.getCustomerPhone());
        carOrder.setRentalOrderNum(NumberUtils.get("L"));
        carOrder = rentalCarOrderService.getCarOrderCharg(carOrder);
        //rentalCarOrderService.save(carOrder);
        redisUtil.set("carOrder:rental:num:"+carOrder.getRentalOrderNum(),carOrder,60*60*12);
        return rentalPayService.getPayAPIEntity(carOrder,request);
    }
}
