/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.api.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.util.UUIDUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.app.dto.ProdCommDataDto;
import com.yami.shop.bean.app.dto.ProdCommDto;
import com.yami.shop.bean.app.dto.ProductDto;
import com.yami.shop.bean.dto.ProdByCategoryIdAndShopIdDTO;
import com.yami.shop.bean.dto.SearchProdDto;
import com.yami.shop.bean.model.ChannelProd;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.param.CategoryProductParam;
import com.yami.shop.bean.vo.SimilarProdListVo;
import com.yami.shop.bean.vo.SkuBuyTogetherOftenVo;
import com.yami.shop.bean.model.UserShopBehavior;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.R;
import com.yami.shop.security.api.model.YamiUser;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.ProdCommService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.SkuService;
import com.yami.shop.service.UserShopBehaviorService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.util.JsonUtils;
import org.apache.logging.log4j.core.util.UuidUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/prod")
@Api(tags = "商品接口")
public class ProdController {

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

    @Autowired
    private ProductService prodService;

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private SkuService skuService;

    @Autowired
    private ProdCommService prodCommService;

    @Autowired
    private UserShopBehaviorService userShopBehaviorService;


    @GetMapping("/prodInfo")
    @ApiOperation(value = "商品详情信息", notes = "根据商品ID（prodId）获取商品信息")
    @ApiImplicitParam(name = "prodId", value = "商品ID", required = true, dataType = "Long")
    public ResponseEntity<ProductDto> prodInfo(@RequestParam("prodId") Long prodId, @RequestParam("channelId") Long channelId, @RequestParam("shopId") Long shopId) {

        YamiUser user = null;
        try {
            user = SecurityUtils.getUser();
        } catch (Exception e) {
            System.out.println("订单详情：" + e.getMessage());
            logger.error("订单详情：错误信息", e);
        }
        if (user != null) {
            String userId = user.getUserId();
            if (channelId == null){
                channelId = 3L;
            }
            if (StringUtils.isNotEmpty(userId)) {
                UserShopBehavior userShopBehavior = null;
                userShopBehavior = userShopBehaviorService.findByUserIdAndProd(userId,shopId, prodId,channelId);
                if (userShopBehavior == null) {
                    int num = userShopBehaviorService.findByUserIdCount(userId);
                    if (num < 6) {
                        userShopBehavior = new UserShopBehavior();
                        userShopBehavior.setUserId(userId);
                        userShopBehavior.setShopId(shopId);
                        userShopBehavior.setChannelId(channelId);
                        userShopBehavior.setProdId(prodId);
                        userShopBehavior.setCreateTime(new Date());
                        userShopBehaviorService.save(userShopBehavior);
                    } else {
                        List<UserShopBehavior> userShopBehaviors = userShopBehaviorService.findByUserId(userId, 1, shopId,channelId);
                        if (userShopBehaviors != null && !userShopBehaviors.isEmpty()) {
                            userShopBehavior = userShopBehaviors.get(0);
                        }
                        if (userShopBehavior != null) {
                            userShopBehavior.setProdId(prodId);
                            userShopBehavior.setShopId(shopId);
                            userShopBehavior.setChannelId(channelId);
                            userShopBehavior.setCreateTime(new Date());
                            userShopBehaviorService.updateById(userShopBehavior);
                        }
                    }
                } else {
                    userShopBehavior.setCreateTime(new Date());
                    userShopBehaviorService.updateById(userShopBehavior);
                }

            }
        }

        Product product = prodService.getProductByProdId(prodId, channelId, shopId);
        if (product == null || product.getStatus() != 1) {
            throw new GlobalException("商品已下线");
        }

        List<Sku> skuList = skuService.listByProdId(prodId, channelId, shopId);
        if (ObjectUtils.isNotEmpty(skuList)) {
            // 启用的sku列表
            List<Sku> useSkuList = skuList.stream().sorted(Comparator.comparing(
                    Sku::getPrice,
                    Comparator.nullsFirst(Comparator.naturalOrder())
            )).peek((sku) -> product.setTotalStocks(product.getTotalStocks() + sku.getActualStocks())).collect(Collectors.toList());
            product.setPrice(useSkuList.get(0).getPrice());
            product.setSkuList(useSkuList);
        }

//        ProductDto productDto = mapperFacade.map(product, ProductDto.class);
        ProductDto productDto = new ProductDto();
        BeanUtils.copyProperties(product, productDto);

        return ResponseEntity.ok(productDto);
    }

    @GetMapping("/isStatus")
    @ApiOperation(value = "校验商品是否下架", notes = "根据商品ID（prodId）校验商品是否下架")
    @ApiImplicitParam(name = "prodId", value = "商品ID", required = true)
    public ResponseEntity<Boolean> isStatus(Long prodId) {
        Product product = prodService.getProductByProdId(prodId);
        if (product == null || product.getStatus() != 1) {
            return ResponseEntity.ok(false);
        }
        return ResponseEntity.ok(true);
    }

    @GetMapping("/lastedProdPage")
    @ApiOperation(value = "新品推荐", notes = "获取新品推荐商品列表")
    @ApiImplicitParams({
    })
    public ResponseEntity<IPage<ProductDto>> lastedProdPage(PageParam<ProductDto> page,
                                                            @RequestParam(value = "lat", required = false) String lat,
                                                            @RequestParam(value = "lon", required = false) String lon,
                                                            @RequestParam(value = "distance", required = false) String distance) {
        IPage<ProductDto> productDtoIPage = prodService.pageByPutawayTime(page, lat, lon, distance);
        return ResponseEntity.ok(productDtoIPage);
    }


    @GetMapping("/moreBuyProdList")
    @ApiOperation(value = "每日疯抢", notes = "获取销量最多的商品列表")
    @ApiImplicitParams({})
    public ResponseEntity<IPage<ProductDto>> moreBuyProdList(PageParam<ProductDto> page) {
        IPage<ProductDto> productDtoIPage = prodService.moreBuyProdList(page);
        return ResponseEntity.ok(productDtoIPage);
    }

    @GetMapping("/discountProds")
    @ApiOperation(value = "根据活动id获取活动商品列表", notes = "根据活动id获取活动商品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "discountId", value = "活动id", required = true, dataType = "Long"),
    })
    public ResponseEntity<IPage<ProductDto>> getDiscountProds(
            @RequestParam(value = "discountId", required = true) Long discountId,
            PageParam<ProductDto> page) {
        IPage<ProductDto> productDtoList = prodService.pageByDiscountId(page, discountId);
        return ResponseEntity.ok(productDtoList);
    }

    @GetMapping("/prodCommData")
    @ApiOperation(value = "返回商品评论数据(好评率 好评数量 中评数 差评数)", notes = "根据商品id获取")
    public ResponseEntity<ProdCommDataDto> getProdCommData(Long prodId) {
        return ResponseEntity.ok(prodCommService.getProdCommDataByProdId(prodId));
    }


    @GetMapping("/prodCommPageByProd")
    @ApiOperation(value = "根据商品返回评论分页数据", notes = "传入商品id和页码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "prodId", value = "商品id", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "evaluate", value = "-1或null 全部，0好评 1中评 2差评 3有图", required = true, dataType = "Long"),
    })
    public ResponseEntity<IPage<ProdCommDto>> getProdCommPageByProdId(PageParam page, Long prodId, Integer evaluate) {
        return ResponseEntity.ok(prodCommService.getProdCommDtoPageByProdId(page, prodId, evaluate));
    }

    @PostMapping("/listProdByCategoryIdAndShopId")
    @ApiOperation(value = "根据分类ID、商户ID查询归属的所有商品")
    public ResponseEntity<IPage<CategoryProductParam>> listProdByCategoryIdAndShopId(@RequestBody ProdByCategoryIdAndShopIdDTO prodByCategoryIdAndShopIdDTO) {
        return ResponseEntity.ok(prodService.listProdByCategoryIdAndShopId(prodByCategoryIdAndShopIdDTO));
    }

    @GetMapping("/prodRecommended")
    @ApiOperation(value = "为你推荐", notes = "为你推荐")
    public ResponseEntity<IPage<SearchProdDto>> getProdRecommended(PageParam<SearchProdDto> page,@RequestParam("shopId") Long shopId,@RequestParam("channelId") Long channelId) {
        IPage<SearchProdDto>   searchProdDtos = page;
        List<ProductDto> productDtos = new ArrayList<>();
        YamiUser user = null;
        try {
            user = SecurityUtils.getUser();
        } catch (Exception e) {
            System.out.println("为你推荐：" + e.getMessage());
            logger.error("为你推荐：错误信息", e);
        }
        if (user != null) {
            String userId = user.getUserId();
            if (StringUtils.isNotEmpty(userId)) {
                if (channelId == null){
                    channelId = 3L;
                }
                List<UserShopBehavior> byUserId = userShopBehaviorService.findByUserId(userId, 5,shopId,channelId);
                for (UserShopBehavior userShopBehavior : byUserId) {
                    ChannelProd channelProd = userShopBehaviorService.findByProdId(userShopBehavior.getProdId(), userShopBehavior.getShopId(),channelId);
                    if (channelProd != null) {
                        BigDecimal channelProdPrice = channelProd.getChannelProdPrice();
                        if (channelProdPrice != null) {
                            BigDecimal increased = channelProdPrice.multiply(new BigDecimal("1.10"))
                                    .setScale(2, RoundingMode.HALF_UP);
                            BigDecimal decreased = channelProdPrice.multiply(new BigDecimal("0.90"))
                                    .setScale(2, RoundingMode.HALF_UP);
                            List<ProductDto> productDtoList = userShopBehaviorService.findByProdIdAndShopIdAndPrice(userShopBehavior.getProdId(), userShopBehavior.getShopId(),channelId, increased, decreased);
                            if (productDtoList != null && !productDtoList.isEmpty()) {
                                productDtos.addAll(productDtoList);
                            }
                        }
                    }

                }
            }
            if (!productDtos.isEmpty()){
                searchProdDtos =   userShopBehaviorService.findByProdAndShop(page,productDtos,userId);
            }
        }

        return ResponseEntity.ok(searchProdDtos);
    }
    /**
     * 相似商品
     */
    @GetMapping("/similarProdList")
    @ApiOperation(value = "相似商品", notes = "传入商品id")
    public R<IPage<SimilarProdListVo>> similarProdList(PageParam<Product> page, Long prodId, Long shopId, Long channelId,String userId) {
        if (channelId == null){
            channelId = 3L;
        }
        return R.SUCCESS(prodService.similarProdList(page, prodId , shopId, channelId, userId));
    }


}
