package com.ff.weijinxiao.controller;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ff.weijinxiao.domain.*;
import com.ff.weijinxiao.jwt.JwtHelper;
import com.ff.weijinxiao.service.*;
import com.ff.weijinxiao.util.JsonTool;
import com.ff.weijinxiao.util.ResultTool;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 会员订单接口
 */
@RestController
@RequestMapping("api/memberOrder")
@Api(value = "会员订单controller", tags = {"会员订单接口"})
@Slf4j
public class MemberOrderController {

    @Resource
    private MemberOrderService memberOrderService;

    @Resource
    private CUserService cUserService;

    @Resource
    private WxPayService wxPayService;

    @Value("${wechat.pay.callback}")
    private String payCallBack;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private MemberPackageService memberPackageService;

    public UserInfo getUserInfoByToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isBlank(token)) {
            return null;
        }
        String openId = JwtHelper.parseToken(token);
        if (StringUtils.isBlank(openId)) {
            return null;
        }

        CUser cUser = cUserService.findByOpenId(openId);
        if (null == cUser) {
            return null;
        }
        return cUser.getUserInfo();
    }

    @PostMapping("/update")
    @ApiOperation(value = "更新会员订单信息", notes = "更新会员订单信息")
    public Map<String, Object> updateMemberOrder(@RequestBody MemberOrder memberOrder, HttpServletRequest request) {
        try {
            memberOrderService.saveMemberOrder(memberOrder);
            return ResultTool.genSuccessResult("修改成功");
        } catch (Exception e) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_2, "修改失败:" + e.getMessage());
        }
    }

    @PostMapping("/create")
    @ApiOperation(value = "创建会员订单信息", notes = "创建会员订单信息")
    public Map<String, Object> saveMemberOrder(@RequestBody MemberOrder memberOrder, HttpServletRequest request) {
        try {
            UserInfo userInfo = getUserInfoByToken(request);
            memberOrderService.saveMemberOrder(memberOrder);
            return ResultTool.genSuccessResult("创建成功");
        } catch (Exception e) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_2, "创建失败:" + e.getMessage());
        }
    }


    @PostMapping("/delete")
    @ApiOperation(value = "删除会员订单信息", notes = "删除会员订单信息")
    public Map<String, Object> deleteMemberOrder(@ApiParam(required = true, value = "会员订单id") @RequestBody String jsonId) {
        Integer id = JsonTool.parseJsonIdStr(jsonId);
        if (id < 0) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "id参数错误");
        }
        MemberOrder memberOrder = memberOrderService.findById(id);
        if (null == memberOrder) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "会员订单不存在");
        }
        memberOrder.setIsDelete(1);
        memberOrderService.saveMemberOrder(memberOrder);
        return ResultTool.genSuccessResult("删除成功");
    }

    @GetMapping("/findbyid")
    @ApiOperation(value = "根据id查询会员订单信息", notes = "根据id查询会员订单信息")
    public Map<String, Object> findById(@ApiParam(required = true, value = "会员订单id") @RequestParam String id,
                                        HttpServletRequest request) {

        Map<String, Object> result = new HashMap<>();
        try {
            MemberOrder memberOrder = memberOrderService.findById(Integer.valueOf(id));
            if (null != memberOrder) {
                result.put("data", memberOrder);
                result.put("message", "查询成功");
                result.put("code", ResultTool.SuccessCode);
            } else {
                result.put("message", "查询失败，没有结果");
                result.put("code", ResultTool.ErrorCode_1);
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.put("message", "查询失败" + e.getMessage());
            result.put("code", ResultTool.ErrorCode_2);
        }

        return result;
    }


    @GetMapping("/list")
    @ApiOperation(value = "查询会员订单列表", notes = "查询会员订单列表")
    public Map<String, Object> findList(@ApiParam(required = false, value = "会员订单名字") @RequestParam(required = false) String phone,
                                        HttpServletRequest request) {

        Map<String, Object> result = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        param.put("GT_id", 0);
        if (null != phone && phone.length() > 0) {
            param.put("LIKE_phone", phone);
        }
        List<MemberOrder> list = memberOrderService.findList(param);
        if (null != list && list.size() > 0) {
            result.put("data", list);
            result.put("total", list.size());
            result.put("message", "查询成功");
            result.put("code", 10000);
        } else {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "没有查询到数据");
        }

        return result;
    }

    @GetMapping("/listpage")
    @ApiOperation(value = "查询会员订单分页列表", notes = "查询会员订单分页列表")
    public Map<String, Object> findListPage(@ApiParam(required = false, value = "会员订单电话") @RequestParam(required = false) String phone,
                                            @ApiParam(required = false, value = "页码 1开始") @RequestParam(required = false) Integer pageNo,
                                            @ApiParam(required = false, value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize) {

        Map<String, Object> result = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        if (null == pageNo) {
            pageNo = 1;
        } else if (pageNo < 1) {
            pageNo = 1;
        }
        if (null == pageSize) {
            pageSize = 10;
        }
        param.put("GT_id", 0);
        if (null != phone && phone.length() > 0) {
            param.put("LIKE_phone", phone);
        }
        Page<MemberOrder> list = memberOrderService.findPage(pageNo, pageSize, param);
        if (null != list && list.getTotalElements() > 0) {
            List<MemberOrder> data = list.getContent();
            for (MemberOrder memberOrder : data) {
                UserInfo userInfo = userInfoService.findByUid(memberOrder.getUid());
                if (null != userInfo) {
                    memberOrder.setUserName(userInfo.getWechatName());
                }
            }
            result.put("data", list);
            result.put("message", "分页查询成功");
            result.put("code", 10000);
        } else {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "没有查询到数据");
        }

        return result;
    }

    @PostMapping("/wxapi/create")
    @ApiOperation(value = "增加会员订单", notes = "增加会员订单")
    public Map<String, Object> createMemberOrder(@RequestBody MemberOrder memberOrder, HttpServletRequest httpServletRequest) {
        try {
            UserInfo userInfo = getUserInfoByToken(httpServletRequest);
            if (null != userInfo) {
                memberOrder.setUid(userInfo.getUid());
            }
            memberOrder.setPhone(userInfo.getPhone());
            memberOrder.setOrderSn(RandomUtil.randomString(20));
            MemberPackage memberPackage = memberPackageService.findById(memberOrder.getMemberPackage().getId());
            if (null == memberPackage) {
                return ResultTool.genFailResult(ResultTool.ErrorCode_1, "会员套餐选择错误");
            }
            if (memberPackage.getPackageType() == 1) {
                memberOrder.setPackageNum(memberPackage.getPackageNum());
                // == 1，年数由前端传过来
                if (memberOrder.getPackageYears() == 1) {
                    memberOrder.setAmount(memberPackage.getOneYearPrice());
                } else if (memberOrder.getPackageYears() == 2) {
                    memberOrder.setAmount(memberPackage.getTwoYearPrice());
                } else if (memberOrder.getPackageYears() == 3) {
                    memberOrder.setAmount(memberPackage.getThreeYearPrice());
                }
            } else {
                // == 2,人数前端传过来
                memberOrder.setPackageYears(1);
                memberOrder.setAmount(memberPackage.getCurrentPrice().multiply(new BigDecimal(memberOrder.getPackageNum())));
            }
            memberOrderService.saveMemberOrder(memberOrder);

            Integer orderId = memberOrder.getId();
            try {
                log.info("订单id =" + orderId);
                JSONObject detailObj = new JSONObject();
                JSONArray jsonArray = new JSONArray();
                detailObj.put("goods_detail", jsonArray);
                String openId = userInfo.getWechatOpenid();
                String wechatSn = getWechatOrderNo();
                List<String> body = new ArrayList<>(16);
                Integer totalFee = Integer.valueOf(0);

                //保存更改
                memberOrder.setWechatSn(wechatSn);
                memberOrderService.saveMemberOrder(memberOrder);


                if (null != memberPackage) {
                    body.add(memberPackage.getTitle());
                }
                //将元乘以100后取整
                if (null != memberOrder.getAmount()) {
                    totalFee = memberOrder.getAmount().multiply(new BigDecimal("100")).setScale(0).intValue();
                }

                WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
                request.setBody(body + "_");
                request.setOutTradeNo(wechatSn);
                request.setTotalFee(totalFee);
                request.setSpbillCreateIp(getRemoteIP(httpServletRequest));
                request.setDetail(detailObj.toJSONString());
                request.setNotifyUrl(payCallBack + "/wxpay/notify/order");
                request.setTradeType(WxPayConstants.TradeType.JSAPI);
                request.setOpenid(openId);
                log.info("微信创建订单参数 = {}", request.toString());
                WxPayMpOrderResult payResult = wxPayService.createOrder(request);
                log.info("微信创建订单结果 = {}", payResult.toString());
                Map<String, Object> result = new HashMap<>();
                result.put("code", 10000);
                result.put("message", "订单创建成功");
                result.put("data", payResult);
                return result;
            } catch (WxPayException e) {
                e.printStackTrace();
                return ResultTool.genFailResult(ResultTool.ErrorCode_1, e.getMessage());
            }

        } catch (Exception e) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_2, "增加会员订单失败:" + e.getMessage());
        }
    }

    @GetMapping("/wxapi/listpage")
    @ApiOperation(value = "查询会员订单分页列表", notes = "查询会员订单分页列表")
    public Map<String, Object> wxfindListPage(@ApiParam(required = false, value = "会员订单电话") @RequestParam(required = false) String phone,
                                              @ApiParam(required = false, value = "页码 1开始") @RequestParam(required = false) Integer pageNo,
                                              @ApiParam(required = false, value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize,
                                              HttpServletRequest request) {

        Map<String, Object> result = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        if (null == pageNo) {
            pageNo = 1;
        } else if (pageNo < 1) {
            pageNo = 1;
        }
        if (null == pageSize) {
            pageSize = 10;
        }
        param.put("GT_id", 0);
        if (null != phone && phone.length() > 0) {
            param.put("LIKE_phone", phone);
        }
        UserInfo userInfo = getUserInfoByToken(request);
        if (null == userInfo) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "获取失败，未注册有效账号");
        }
        param.put("EQ_uid", userInfo.getUid());
        Page<MemberOrder> list = memberOrderService.findPage(pageNo, pageSize, param);
        if (null != list && list.getTotalElements() > 0) {
            List<MemberOrder> data = list.getContent();
            for (MemberOrder memberOrder : data) {
                memberOrder.setUserName(userInfo.getWechatName());
            }
            result.put("data", list);
            result.put("message", "分页查询成功");
            result.put("code", 10000);
        } else {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "没有查询到数据");
        }

        return result;
    }

    public String getWechatOrderNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
        String format = sdf.format(new Date()) + getRandomString();
        return "2000" + format;
    }

    private String getRandomString() {
        Random random = new Random();
        String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 7; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public String getRemoteIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

}
