package com.ruoyi.web.controller.api;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.annotation.RateLimiter;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ApiResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.common.weiXin.WeiXinParamConfig;
import com.ruoyi.common.weiXin.WeiXinUtils;
import com.ruoyi.common.weiXin.domain.WxMessageDataDto;
import com.ruoyi.mall.domain.*;
import com.ruoyi.mall.domain.vo.GoodsProductVO;
import com.ruoyi.mall.domain.vo.MallOrderGoodsVO;
import com.ruoyi.mall.mapper.MallCombineGoodsMapper;
import com.ruoyi.mall.mapper.MallGoodsProductMapper;
import com.ruoyi.mall.mapper.MallOrderOrderMapper;
import com.ruoyi.mall.service.*;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * 小程序新
 *
 * @author chang
 * @date 2021-11-25
 */
@RestController
@RequestMapping("/api/xcx")
@ApiOperation("小程序新")
public class ApiXcxNewController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private IMallCombineGoodsService mallCombineGoodsService;
    @Resource
    private IMallCombineOrderLinkService mallCombineOrderLinkService;
    @Resource
    private IMallConfigService mallConfigService;
    @Resource
    private IMallOrderOrderService mallOrderOrderService;
    @Resource
    private IMallSalesmanAchievementService mallSalesmanAchievementService;
    @Resource
    private IMallMemberUserService mallMemberUserService;
    @Resource
    private IMallSalesmanService mallSalesmanService;
    @Resource
    private IMallShopShopService mallShopShopService;
    @Resource
    private IMallGoodsGoodsService mallGoodsGoodsService;
    @Resource
    private IMallGoodsProductService mallGoodsProductService;
    @Resource
    private IMallMeetAddressService mallMeetAddressService;
    @Resource
    private IMallCouponService mallCouponService;
    @Resource
    private IMallMemberIntegralService mallMemberIntegralService;


    /**
     * 关于我们详情
     *
     * @return ok
     */
    @GetMapping("/getAboutUsInfo")
    public ApiResult getAboutUsInfo(@RequestParam Map<String, Object> params) {
        try {
            return ApiResult.ok().put("data", mallConfigService.selectMallConfigByIdentifying("aboutUs"));
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("关于我们详情异常");
        }

    }

    /**
     * 业务员管理-收益统计
     *
     * @param params salesmanId 业务员ID
     *               deliveryType 配送方式：0-快递，1-自提
     *               timeBegin 开始时间
     *               timeEnd  结束时间
     * @return ok
     */
    @GetMapping("/getSalesmanRevenueStatistics")
    public ApiResult getSalesmanRevenueStatistics(@RequestParam Map<String, Object> params) {
        if (!params.containsKey("salesmanId") || StringUtils.isBlank(params.get("salesmanId").toString())) {
            return ApiResult.error("业务员请先登录");
        }
        try {
            return ApiResult.ok().put("data", mallSalesmanAchievementService.getSalesmanRevenueStatistics(params));
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("业务员管理-收益统计异常");
        }

    }

    /**
     * 业务员管理-订单列表
     *
     * @param pageNum  页码
     * @param pageSize 每页数据量
     * @param params   salesmanId 业务员ID
     *                 status 订单状态0=待支付,1=待发货,2=待收货,3=待评论,4=已完成,5=退货中,6=退款成功,7=换货中,8=已取消,10-待拼团
     *                 deliveryType 配送方式：0-快递，1-自提
     *                 searchValue 搜索词
     *                 timeBegin 开始时间
     *                 timeEnd  结束时间
     * @return ok
     */
    @GetMapping("/getSalesmanStatisticsOrderList")
    public ApiResult getSalesmanStatisticsOrderList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                                    @RequestParam(value = "pageSize", defaultValue = "100", required = false) Integer pageSize,
                                                    @RequestParam Map<String, Object> params) {

        try {
            PageHelper.startPage(pageNum, pageSize);
            List<Map<String, Object>> list = mallSalesmanAchievementService.getSalesmanStatisticsOrderList(params);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo(list);
            return ApiResult.ok().put("data", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("业务员管理-订单列表异常");
        }
    }

    /**
     * 业务员管理-业绩排行榜
     *
     * @param params   sortType 0-总单数排名，1-总金额排名，2-提成排名
     * @return ok
     */
    @GetMapping("/getSalesmanStatisticsRankingList")
    public ApiResult getSalesmanStatisticsRankingList(@RequestParam Map<String, Object> params) {

        try {
            List<Map<String, Object>> list = mallSalesmanAchievementService.getSalesmanStatisticsRankingList(params);
            return ApiResult.ok().put("data", list);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("业务员管理-业绩排行榜异常");
        }
    }

    /**
     * 我的业务员信息
     *
     * @param params   userId 用户ID
     * @return ok
     */
    @GetMapping("/getMySalesmanInfo")
    public ApiResult getMySalesmanInfo(@RequestParam Map<String, Object> params) {
        if (!params.containsKey("userId") || StringUtils.isBlank(params.get("userId").toString())) {
            return ApiResult.error("请先登录");
        }
        try {
            long userId = Long.parseLong(params.get("userId").toString());
            MallMemberUser mallMemberUser = mallMemberUserService.selectMallMemberUserById(userId);

            MallSalesman mallSalesman = new MallSalesman();
            if (mallMemberUser != null && mallMemberUser.getSalesmanId() != null) {
                mallSalesman = mallSalesmanService.selectMallSalesmanById(mallMemberUser.getSalesmanId());
            }
            return ApiResult.ok().put("data", mallSalesman);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("我的业务员信息异常");
        }

    }

    /**
     * 自提点信息
     *
     * @param params   userId 用户ID
     *                 shopId 商家ID
     * @return ok
     */
    @GetMapping("/getSelfPickupInfo")
    public ApiResult getSelfPickupInfo(@RequestParam Map<String, Object> params) {
        if (!params.containsKey("userId") || StringUtils.isBlank(params.get("userId").toString())) {
            return ApiResult.error("请先登录");
        }
        if (!params.containsKey("shopId") || StringUtils.isBlank(params.get("shopId").toString())) {
            return ApiResult.error("请先选择自提点");
        }
        try {
            long userId = Long.parseLong(params.get("userId").toString());
            long shopId = Long.parseLong(params.get("shopId").toString());
            MallShopShop mallShopShop = mallShopShopService.selectMallShopShopByShopId(shopId);
            return ApiResult.ok().put("data", mallShopShop);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("自提点信息异常");
        }

    }

    /**
     * 距离最近的店铺
     *
     * @return ok
     */
    @GetMapping("/getShopNearestDistance")
    public ApiResult getShopNearestDistance() {
        try {
            List<Map<String, Object>> list = mallShopShopService.queryShopList();
            return ApiResult.ok().put("data", list);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("距离最近的店铺异常");
        }
    }

    /**
     * 查询商品规格
     *
     * @param params   goodsId 商品ID
     * @return ok
     */
    @GetMapping("/getGoodsProductList")
    public ApiResult getGoodsProductList(@RequestParam Map<String, Object> params) {
        if (!params.containsKey("goodsId") || StringUtils.isBlank(params.get("goodsId").toString())) {
            return ApiResult.error("请先选择商品");
        }
        try {
            long goodsId = Long.parseLong(params.get("goodsId").toString());
            MallGoodsProduct mallGoodsProduct = new MallGoodsProduct();
            mallGoodsProduct.setGoodsId(goodsId);
            return ApiResult.ok().put("data", mallGoodsProductService.selectMallGoodProByParams(mallGoodsProduct));
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("查询商品规格异常");
        }
    }

    /**
     * 业务员查询所有商品
     *
     * @param pageNum  页码
     * @param pageSize 每页数据量
     * @param params   sort 排序：0-默认排序，1-价格从高到低，2-价格从低到高，3-提成从高到低，4-提成从低到高
     * @return ok
     */
    @GetMapping("/getSalesmanAllGoodsList")
    public ApiResult getSalesmanAllGoodsList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                             @RequestParam(value = "pageSize", defaultValue = "100", required = false) Integer pageSize,
                                             @RequestParam Map<String, Object> params) {
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<Map<String, Object>> list = mallGoodsGoodsService.getSalesmanAllGoodsList(params);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo(list);
            return ApiResult.ok().put("data", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("业务员查询所有商品异常");
        }
    }

    /**
     * 查询接货地址
     *
     * @param params   areaId 区县ID
     * @return ok
     */
    @GetMapping("/getMeetAddressList")
    public ApiResult getMeetAddressList(@RequestParam Map<String, Object> params) {
        try {
            List<Map<String, Object>> list = mallMeetAddressService.getMeetAddressList(params);
            return ApiResult.ok().put("data", list);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("查询接货地址异常");
        }
    }

    /**
     * 商城设置信息详情
     *
     * @param params   identifying 设置标识
     * @return ok
     */
    @GetMapping("/getShopConfigInfo")
    public ApiResult getShopConfigInfo(@RequestParam Map<String, Object> params) {
        if (!params.containsKey("identifying") || StringUtils.isBlank(params.get("identifying").toString())) {
            return ApiResult.error("缺少identifying");
        }
        try {
            return ApiResult.ok().put("data", mallConfigService.selectMallConfigByIdentifying(params.get("identifying").toString()));
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("商城设置信息详情异常");
        }
    }

    /**
     * 业务员查询名下客户
     *
     * @param pageNum  页码
     * @param pageSize 每页数据量
     * @param params   salesmanId 业务员ID
     * @return ok
     */
    @GetMapping("/getSalesmanUserList")
    public ApiResult getSalesmanUserList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                             @RequestParam(value = "pageSize", defaultValue = "100", required = false) Integer pageSize,
                                             @RequestParam Map<String, Object> params) {
        if (!params.containsKey("salesmanId") || StringUtils.isBlank(params.get("salesmanId").toString())) {
            return ApiResult.error("缺少salesmanId 业务员ID");
        }
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<Map<String, Object>> list = mallMemberUserService.getSalesmanUserList(params);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo(list);
            return ApiResult.ok().put("data", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("业务员查询名下客户异常");
        }
    }

    /**
     * 用户总积分
     *
     * @param params   userId 用户ID
     * @return ok
     */
    @GetMapping("/getUserAllIntegral")
    public ApiResult getUserAllIntegral(@RequestParam Map<String, Object> params) {
        if (!params.containsKey("userId") || StringUtils.isBlank(params.get("userId").toString())) {
            return ApiResult.error("缺少userId 用户ID");
        }
        try {
            HashMap<String, Object> map = new HashMap<>();

            Map<String, Object> stringObjectMap = mallCouponService.userIntegral(params);
            BigDecimal userAllIntegral = new BigDecimal(stringObjectMap.get("userCanIntegral").toString());

            map.put("allIntegral", userAllIntegral);
            return ApiResult.ok().put("data", map);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("用户总积分异常");
        }
    }

    /**
     * 用户积分列表
     *
     * @param pageNum  页码
     * @param pageSize 每页数据量
     * @param params   userId 用户ID
     * @return ok
     */
    @GetMapping("/getUserIntegralList")
    public ApiResult getUserIntegralList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                         @RequestParam(value = "pageSize", defaultValue = "100", required = false) Integer pageSize,
                                         @RequestParam Map<String, Object> params) {
        if (!params.containsKey("userId") || StringUtils.isBlank(params.get("userId").toString())) {
            return ApiResult.error("缺少用户ID 用户ID");
        }
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<Map<String, Object>> list = mallMemberUserService.getUserIntegralList(params);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo(list);
            return ApiResult.ok().put("data", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("用户积分列表异常");
        }
    }

    /**
     * 兑换优惠券列表
     *
     * @param pageNum  页码
     * @param pageSize 每页数据量
     * @param params   userId 用户ID
     * @return ok
     */
    @GetMapping("/exchangeCouponList")
    public ApiResult exchangeCouponList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                                         @RequestParam(value = "pageSize", defaultValue = "100", required = false) Integer pageSize,
                                         @RequestParam Map<String, Object> params) {
        if (!params.containsKey("userId") || StringUtils.isBlank(params.get("userId").toString())) {
            return ApiResult.error("请先登录");
        }
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<Map<String, Object>> list = mallCouponService.exchangeCouponList(params);
            PageInfo<Map<String, Object>> pageInfo = new PageInfo(list);
            return ApiResult.ok().put("data", pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("用户积分列表异常");
        }
    }

    /**
     * 兑换优惠券
     *
     * @param params   userId 用户ID
     * @param params   couponId 优惠券ID
     * @return ok
     */
    @RepeatSubmit
    @RateLimiter(key = "API_exchangeCoupons", time = 5, count = 50)
    @PostMapping("/exchangeCoupons")
    public ApiResult exchangeCoupons(@RequestBody Map<String, Object> params){
        if (!params.containsKey("userId") || StringUtils.isBlank(params.get("userId").toString())) {
            return ApiResult.error("请先登录");
        }
        if (!params.containsKey("couponId") || StringUtils.isBlank(params.get("couponId").toString())) {
            return ApiResult.error("请选择优惠券");
        }
        try{

            // 用户id
            Long userId = MapUtils.getLong(params, "userId");
            // 优惠券id
            Long couponId = MapUtils.getLong(params, "couponId");



            MallCoupon coupon = mallCouponService.selectMallCouponById(couponId);
            if(coupon == null) {
                return ApiResult.ok("优惠券已失效");
            }

            Map<String, Object> map = mallMemberUserService.checkUserCoupon(userId,couponId.toString());
            if (map != null && "0".equals(coupon.getType())) {
                return ApiResult.ok("已领取,不能重复领取");
            }

            // 兑换所需积分大于0
            if (coupon.getIntegral().compareTo(new BigDecimal(0)) > 0 && "1".equals(coupon.getType())) {
                HashMap<String, Object> mapUser = new HashMap<>();
                mapUser.put("userId", params.get("userId").toString());
                Map<String, Object> stringObjectMap = mallCouponService.userIntegral(mapUser);
                BigDecimal userAllIntegral = new BigDecimal(stringObjectMap.get("userCanIntegral").toString());
                if (userAllIntegral.compareTo(coupon.getIntegral()) < 1) {
                    return ApiResult.ok("积分不足");
                }
            }

            // 用户优惠券
            MallMemberCoupon memberCoupon = new MallMemberCoupon();
            memberCoupon.setUserId(userId);
            memberCoupon.setCouponId(couponId);
            memberCoupon.setName(coupon.getName());
            memberCoupon.setEnoughPrice(coupon.getEnoughPrice());
            memberCoupon.setPrice(coupon.getPrice());
            memberCoupon.setType(Integer.parseInt(coupon.getType()));
            memberCoupon.setCreateAt(DateUtils.getTime());
            memberCoupon.setIsUsed("0");
            mallMemberUserService.insertUserCoupon(memberCoupon);

            // 积分兑换记录
            MallMemberIntegral mallMemberIntegral = new MallMemberIntegral();
            mallMemberIntegral.setUserId(userId);
            mallMemberIntegral.setIntegral(coupon.getIntegral());
            mallMemberIntegral.setMark(4);
            mallMemberIntegral.setType(1);
            mallMemberIntegral.setSendType(0);
            mallMemberIntegral.setSendId(userId);
            mallMemberIntegral.setResId(couponId);
            mallMemberIntegralService.insertMallMemberIntegral(mallMemberIntegral);

            return ApiResult.ok("兑换成功");

        }catch (Exception e){
            return ApiResult.error("兑换优惠券异常");
        }
    }

    @Resource
    private RedisCache redisCache;

    /**
     * 获取access_token
     */
    @GetMapping("/getAccessToken")
    public String getAccessToken() {
        JSONObject jsonObject = new JSONObject();
        String accessToken = "";
        String redisKey = "xcx:access_token";
        try {
            String url = "https://api.weixin.qq.com/cgi-bin/token";
            String result = HttpUtils.sendGet(url, "" +
                    "grant_type=client_credential&" +
                    "appid=" + "wxbf6a9f26e8bd909b" + "&" +
                    "secret=" + "588008f64be11993ecceebd7b80eff6b");
            jsonObject = JSONObject.parseObject(result);
            // 有效期(s)
            Integer expiresIn = 0;
            if (ObjectUtils.isNotEmpty(jsonObject)) {
                accessToken = jsonObject.getString("access_token");
                expiresIn = jsonObject.getInteger("expires_in");
            }
            if (StringUtils.isBlank(accessToken)){
                logger.error("小程序获取access_token失败 -> {"+DateUtils.getTime()+": "+jsonObject+"}");
            }else {
                redisCache.setCacheObject(redisKey, accessToken, expiresIn, SECONDS);
            }
        } catch (Exception e) {
            logger.error("小程序获取access_token异常 -> {"+DateUtils.getTime()+": "+e.getMessage()+"}");
        }
        return accessToken;
    }

    /**
     * 小程序上架审核隐藏商品
     *
     * @param params   showStatus 小程序上架审核状态：0-未审核，1-审核中
     * @return ok
     */
    @GetMapping("/xcxReviewHiddenProducts")
    public ApiResult xcxReviewHiddenProducts(@RequestParam Map<String, Object> params) {
        if (!params.containsKey("showStatus") || StringUtils.isBlank(params.get("showStatus").toString())) {
            return ApiResult.error("缺少小程序上架审核状态showStatus");
        }
        try {
            mallGoodsGoodsService.updateXcxReviewHidden(params);
            return ApiResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResult.error("小程序上架审核隐藏商品异常");
        }
    }

}
