package com.ruoyi.bar;

import com.ruoyi.bar.domain.RedeemOrderVO;
import com.ruoyi.bar.domain.WyFavoriteBeer;
import com.ruoyi.bar.domain.WyFavoriteBrewery;
import com.ruoyi.bar.service.IWyFavoriteService;
import com.ruoyi.brewery.domain.*;
import com.ruoyi.brewery.service.*;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.WyBarUser;
import com.ruoyi.common.core.domain.entity.WyBeerReviewScore;
import com.ruoyi.common.core.domain.model.BarLoginUser;
import com.ruoyi.common.core.domain.model.FavoriteBeerVO;
import com.ruoyi.common.core.domain.model.FavoriteBreweryVO;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.BeerRatingUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.vo.WyActivityVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.DoubleFunction;
import java.util.function.ToDoubleFunction;

@Api(tags = "品牌方信息管理")
@RestController
@RequestMapping("/bar/brewery")
public class BarBreweryController extends BarBaseController {

    @Resource
    private IWyBreweryService wyBreweryService;

    @Resource
    private IWyActivityService wyActivityService;
    @Resource
    private IWyBeerService wyBeerService;
    @Resource
    private IWyGoodsService wyGoodsService;
    @Resource
    private IWyBeerReviewService wyBeerReviewService;
    @Resource
    private IWyFavoriteService wyFavoriteService;
    @Resource
    private IWyRedeemOrderService wyRedeemOrderService;
    @Autowired
    private TokenService tokenService;

    /**
     * 品牌方列表
     *
     * @return 品牌方列表
     */
    @ApiOperation("品牌方列表")
    @GetMapping("/getBreweries")
    public TableDataInfo getBreweries(@RequestParam(name = "search", required = false) String searchText) {
        final WyBrewery wyBrewery = new WyBrewery();
        wyBrewery.setAuthorized(1);
        if (searchText != null) {
            if (searchText.trim().length() < 2) {
                throw new IllegalArgumentException("搜索内容长度不能少于2个字符");
            }
            wyBrewery.setBrandName(searchText);
        }
        startPage();
        final List<WyBrewery> wyBreweries = wyBreweryService.selectWyBreweryList(wyBrewery);
        return getDataTable(wyBreweries);
    }

    /**
     * 获取品牌方详细信息
     */
    @ApiOperation(value = "获取品牌方详细信息", notes = "获取品牌方详细信息")
    @GetMapping(value = "/getBreweryInfo/{id}")
    public AjaxResult getBreweryInfo(@PathVariable("id") Long id) {
        return success(wyBreweryService.selectWyBreweryById(id));
    }

    @ApiOperation("品牌方活动列表")
    @GetMapping("/getActivities")
    public TableDataInfo getActivities(HttpServletRequest request, @RequestParam(name = "orderBy", required = false) String orderBy) {
        //TODO 如果门店没有登录，展示全国性得活动，如果登录了，获取地理位置信心，查看当地品牌方发布得活动
        //TODO 登陆的同时也获取了位置信息，会只显示本地的活动+范围是全国的活动。
        //TODO 用户上来之后是有四个状态，游客 无token信息，点击登录以后  已登录有token信息，但是未认证。最后认证中，最后是审核认证通过状态。
        //获取登录用户
      // BarLoginUser loginUser = SecurityUtils.getBarLoginUser();  认证用户无意义
        final WyActivity activity = new WyActivity();
        activity.setActivityStatus(1);
        if (orderBy != null) {
            if ("popularity".equals(orderBy) || "create_time".equals(orderBy)) {
                HashMap<String, Object> orderMap = new HashMap<>();
                orderMap.put("orderByColumn", orderBy);
                orderMap.put("isAsc", "desc");
                activity.setParams(orderMap);
            }
        }
        //判断用户是否登录 临时
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (loginUser == null) {
            activity.setCity("全国");
            activity.setActivityType(2);
            startPage();
            List<WyActivity>  wyActivities = wyActivityService.selectWyActivityListWithBeer(activity);
            return getDataTable(wyActivities);
        }else {
            //登录用户
            startPage();
            final List<WyActivity> wyActivities = wyActivityService.selectWyActivityListWithBeerAndBar(activity, loginUser.getUser().getUserId());
            return getDataTable(wyActivities);
        }


        //门店未登录，显示全国的招募活动
        /*if (loginUser == null){
            activity.setCity("全国");
            activity.setActivityType(2);
            startPage();
            final List<WyActivity> wyActivities = wyActivityService.selectWyActivityListWithBeer(activity);
            return getDataTable(wyActivities);
        }else{
            startPage();
            final List<WyActivity> wyActivities = wyActivityService.selectWyActivityListWithBeerAndBar(activity, loginUser.getUser().getUserId());
            return getDataTable(wyActivities);
        }*/
    }

    /**
     * 查询我关注的品牌方的营销活动列表
     */
    @ApiOperation(value = "查询我关注的品牌方的营销活动列表", notes = "查询我关注的品牌方的营销活动列表")
    @GetMapping("/getFavoriteActivities")
    public TableDataInfo getFavoriteActivities(@RequestParam(name = "orderBy", required = false) String orderBy) {
        BarLoginUser loginUser = SecurityUtils.getBarLoginUser();
        if (loginUser == null) {
            throw new IllegalArgumentException("未登录");
        }
        WyFavoriteBrewery favoriteBrewery = new WyFavoriteBrewery();
        favoriteBrewery.setUserId(loginUser.getUser().getUserId());
        List<WyFavoriteBrewery> list = wyFavoriteService.selectWyFavoriteBreweryList(favoriteBrewery);
        if (list.isEmpty()) {
            throw new IllegalArgumentException("未关注任何品牌方");
        }
        //获取收藏的品牌方id数组
        List<Long> breweryIds = new ArrayList<>();
        list.forEach(item -> breweryIds.add(item.getBreweryId()));
        WyActivityFavorite wyActivity = new WyActivityFavorite();
        wyActivity.setActivityStatus(1);
        wyActivity.setBreweryIds(breweryIds.toArray(new Long[0]));
        if (orderBy != null) {
            if (orderBy.equals("popularity") || orderBy.equals("create_time")) {
                HashMap<String, Object> orderMap = new HashMap<>();
                orderMap.put("orderByColumn", orderBy);
                orderMap.put("isAsc", "desc");
                wyActivity.setParams(orderMap);
            }
        }
        startPage();
        final List<WyActivity> wyActivities = wyActivityService.selectFavoritedWyActivityList(wyActivity);
        return getDataTable(wyActivities);
    }

    @ApiOperation("单个品牌方活动列表")
    @GetMapping("/getBreweryActivities/{id}")
    public TableDataInfo getBreweryActivities(@PathVariable("id") Long id) {
        final WyActivity activity = new WyActivity();
        activity.setActivityStatus(1);
        activity.setBreweryId(id);
        startPage();
        final List<WyActivity> wyActivities = wyActivityService.selectWyActivityListWithBeer(activity);
        return getDataTable(wyActivities);
    }

    /**
     * 获取营销活动详细信息
     */
    @ApiOperation("获取营销活动详细信息")
    @GetMapping(value = "/getActivityInfo/{id}")
    public AjaxResult getActivityInfo(@PathVariable("id") Long id) {
        return success(wyActivityService.selectWyActivityById(id));
    }

    @ApiOperation("品牌方酒款列表")
    @GetMapping("/getBeerList")
    public TableDataInfo getBeerList(@RequestParam(name = "search", required = false) String searchText) {
        final WyBeer beer = new WyBeer();
        if (searchText != null) {
            if (searchText.trim().length() < 2) {
                throw new IllegalArgumentException("搜索内容长度不能少于2个字符");
            }
            beer.setBeerName(searchText);
        }
        beer.setOnSale(1);
        startPage();
        final List<WyBeer> wyBeers = wyBeerService.selectWyBeerList(beer);
        return getDataTable(wyBeers);
    }

    @ApiOperation("单个品牌方酒款列表")
    @GetMapping("/getBreweryBeerList/{id}")
    public TableDataInfo getBreweryBeerList(@PathVariable("id") Long id) {
        final WyBeer beer = new WyBeer();
        beer.setOnSale(1);
        beer.setBreweryId(id);
        startPage();
        final List<WyBeer> wyBeers = wyBeerService.selectWyBeerList(beer);
        return getDataTable(wyBeers);
    }

    /**
     * 获取营销活动详细信息
     */
    @ApiOperation("获取酒款详细信息")
    @GetMapping(value = "/getBeerInfo/{id}")
    public AjaxResult getBeerInfo(@PathVariable("id") Long id) {
        return success(wyBeerService.selectWyBeerById(id));
    }

    @ApiOperation("全部品牌方兑换商品列表")
    @GetMapping("/getGoodsList")
    public TableDataInfo getGoodsList() {
        final WyGoods wyGoods = new WyGoods();
        wyGoods.setOnSale(1);
        startPage();
        final List<WyGoods> wyBeers = wyGoodsService.selectWyGoodsList(wyGoods);
        return getDataTable(wyBeers);
    }

    @ApiOperation("单个品牌方兑换商品列表")
    @GetMapping("/getBreweryGoodsList/{id}")
    public TableDataInfo getBreweryGoodsList(@PathVariable("id") Long id) {
        final WyGoods wyGoods = new WyGoods();
        wyGoods.setOnSale(1);
        wyGoods.setBreweryId(id);
        startPage();
        final List<WyGoods> wyBeers = wyGoodsService.selectWyGoodsList(wyGoods);
        return getDataTable(wyBeers);
    }

    /**
     * 获取营销活动详细信息
     */
    @ApiOperation("获取兑换商品详细信息")
    @GetMapping(value = "/getGoodsInfo/{id}")
    public AjaxResult getGoodsInfo(@PathVariable("id") Long id) {
        return success(wyGoodsService.selectWyGoodsById(id));
    }

    @ApiOperation("酒评列表")
    @GetMapping("/getReviewList")
    public TableDataInfo getReviewList(@RequestParam(value = "beerId", required = false) Long beerId) {
        BarLoginUser loginUser = SecurityUtils.getBarLoginUser();
        final WyBeerReview wyBeerReview = new WyBeerReview();
        if (beerId != null) {
            wyBeerReview.setBeerId(beerId);
        }
        startPage();
        if (loginUser == null) {
            final List<WyBeerReview> wyBeerReviews = wyBeerReviewService.selectWyBeerReviewList(wyBeerReview);
            return getDataTable(wyBeerReviews);
        }else {
            final List<WyBeerReview> wyBeerReviews = wyBeerReviewService.selectWyBeerReviewListWithLike(wyBeerReview,loginUser.getUser().getUserId());
            return getDataTable(wyBeerReviews);
        }
    }

    /**
     * 获取酒评详细信息
     */
    @ApiOperation("获取酒评详细信息")
    @GetMapping(value = "/getReviewInfo/{id}")
    public AjaxResult getReviewInfo(@PathVariable("id") Long id) {
        return success(wyBeerReviewService.selectWyBeerReviewById(id));
    }

    @ApiOperation("酒评评分列表")
    @GetMapping("/getReviewScoreList")
    public AjaxResult getReviewScoreList(@RequestParam(value = "beerId") Long beerId) {
        final WyBeerReviewScore wyBeerReviewScore = wyBeerReviewService.selectWyBeerReviewScoreList(beerId);
        if (wyBeerReviewScore == null) {
            final WyBeerReviewScore score = new WyBeerReviewScore();
            score.setBeerId(beerId);
            score.setAvgAromaRating(0.0);
            score.setAvgTasteRating(0.0);
            score.setAvgColorRating(0.0);
            score.setAvgOverallRating(0.0);
            return success(score);
        }
        final List<WyBeerReviewScore> wyBeerReviewScores = wyBeerReviewService.selectWyBeerReviewScoreAll();
        final double aromaAverage = getAverageScore(wyBeerReviewScores,"aroma",wyBeerReviewScore.getAvgAromaRating(),wyBeerReviewScore.getReviewCount());
        final double tasteAverage = getAverageScore(wyBeerReviewScores,"taste",wyBeerReviewScore.getAvgTasteRating(),wyBeerReviewScore.getReviewCount());
        final double colorAverage = getAverageScore(wyBeerReviewScores,"color",wyBeerReviewScore.getAvgColorRating(),wyBeerReviewScore.getReviewCount());
        final double overallAverage = getAverageScore(wyBeerReviewScores,"overall",wyBeerReviewScore.getAvgOverallRating(),wyBeerReviewScore.getReviewCount());
        final WyBeerReviewScore score = new WyBeerReviewScore();
        score.setAvgAromaRating(aromaAverage);
        score.setAvgTasteRating(tasteAverage);
        score.setAvgColorRating(colorAverage);
        score.setAvgOverallRating(overallAverage);
        score.setBeerId(beerId);
        return success(score);
    }

    private static double getAverageScore(List<WyBeerReviewScore> wyBeerReviewScores,String type,double avg,int count) {
        ToDoubleFunction<WyBeerReviewScore> rating = null;
        if (type.equals("aroma")) {
             rating = WyBeerReviewScore::getAvgAromaRating;
        }else if (type.equals("taste")) {
            rating = WyBeerReviewScore::getAvgTasteRating;
        }else if (type.equals("color")) {
            rating = WyBeerReviewScore::getAvgColorRating;
        }else if (type.equals("overall")) {
            rating = WyBeerReviewScore::getAvgOverallRating;
        }else{
            throw new IllegalArgumentException("type参数错误");
        }
        final double average = wyBeerReviewScores.stream().mapToDouble(rating).average().orElse(0.0); // 如果列表为空，返回NaN;
        final double averageReviewCount = wyBeerReviewScores.stream().mapToDouble(WyBeerReviewScore::getReviewCount).average().orElse(0.0); // 如果列表为空，返回NaN;
        final double v = BeerRatingUtils.calculateBayesianScore(averageReviewCount, average,
                avg * count,
                count);
        return Math.round(v * 10.0) / 10.0;
    }

    //以下接口需登录后才能访问

    /**
     * 获取我发布的酒评详细信息
     */
    @ApiOperation("获取我发布的酒评详细信息")
    @GetMapping(value = "/getMyReviewInfo/{beerId}")
    public AjaxResult getMyReviewInfo(@PathVariable("beerId") Long beerId) {
        BarLoginUser loginUser = SecurityUtils.getBarLoginUser();
        if (loginUser == null) {
            return error("未登录，请先登录！");
        }
        WyBarUser user = loginUser.getUser();
        return success(wyBeerReviewService.selectWyBeerReviewByBeerIdAndCustomerId(beerId, user.getUserId()));
    }

    /**
     * 酒款收藏/取消收藏
     */
    @ApiOperation("酒款收藏/取消收藏")
    @PostMapping("/favorBeer")
    public AjaxResult favorBeer(@Validated @RequestBody FavoriteBeerVO favor) {
        BarLoginUser loginUser = SecurityUtils.getBarLoginUser();
        validateBarAuth();
        final WyFavoriteBeer wyFavoriteBeer = wyFavoriteService.selectWyFavoriteBeerByBeerIdAndUserId(favor.getBeerId(), loginUser.getUser().getUserId());
        WyFavoriteBeer favoriteBeer = new WyFavoriteBeer();
        favoriteBeer.setBeerId(favor.getBeerId());
        favoriteBeer.setUserId(loginUser.getUser().getUserId());
        if (favor.getStatus() == 1) {
            if (wyFavoriteBeer != null)   // 该用户已点赞过该酒评
            {
                return AjaxResult.error("该用户已收藏过该酒款");
            }
            wyFavoriteService.insertWyFavoriteBeer(favoriteBeer);
            return AjaxResult.success("收藏成功");
        } else {
            if (wyFavoriteBeer == null) {
                return AjaxResult.error("该用户未收藏过该酒款");
            }
            wyFavoriteService.deleteWyFavoriteBeerByBeerIdAndUserId(favor.getBeerId(), loginUser.getUser().getUserId());
            return AjaxResult.success("取消收藏成功");
        }
    }

    /**
     * 品牌收藏/取消收藏
     */
    @ApiOperation("品牌收藏/取消收藏")
    @PostMapping("/favorBrewery")
    public AjaxResult favorBrewery(@Validated @RequestBody FavoriteBreweryVO favor) {
        BarLoginUser loginUser = SecurityUtils.getBarLoginUser();
        validateBarAuth();
        final WyFavoriteBrewery wyFavoriteBrewery = wyFavoriteService.selectWyFavoriteBreweryByBreweryIdAndUserId(favor.getBreweryId(), loginUser.getUser().getUserId());
        WyFavoriteBrewery favoriteBrewery = new WyFavoriteBrewery();
        favoriteBrewery.setBreweryId(favor.getBreweryId());
        favoriteBrewery.setUserId(loginUser.getUser().getUserId());
        if (favor.getStatus() == 1) {
            if (wyFavoriteBrewery != null)   // 该用户已收藏过该品牌
            {
                return AjaxResult.error("该用户已收藏过该品牌");
            }
            wyFavoriteService.insertWyFavoriteBrewery(favoriteBrewery);
            return AjaxResult.success("收藏成功");
        } else {
            if (wyFavoriteBrewery == null) {
                return AjaxResult.error("该用户未收藏过该品牌");
            }
            wyFavoriteService.deleteWyFavoriteBreweryByBreweryIdAndUserId(favor.getBreweryId(), loginUser.getUser().getUserId());
            return AjaxResult.success("取消收藏成功");
        }
    }

    /**
     * 创建兑换订单
     */
    @ApiOperation("创建兑换订单")
    @PostMapping("/createOrder")
    public AjaxResult createOrder(@Validated @RequestBody RedeemOrderVO redeemOrder) {
        BarLoginUser loginUser = SecurityUtils.getBarLoginUser();
        validateBarAuth();
        WyRedeemOrder wyRedeemOrder = new WyRedeemOrder();
        wyRedeemOrder.setGoodsId(redeemOrder.getGoodsId());
        wyRedeemOrder.setRedeemNum(redeemOrder.getGoodsNum());
        wyRedeemOrder.setBarId(loginUser.getUser().getBarId());
        wyRedeemOrder.setUserId(loginUser.getUser().getUserId());
        final Long orderId = wyRedeemOrderService.createWyRedeemOrder(wyRedeemOrder);
        HashMap<String, Object> map = new HashMap<>();
        map.put("orderId", orderId);
        return success(map);
    }

    /**
     * 获取兑换订单
     */
    @ApiOperation("获取兑换订单")
    @GetMapping("/orderView")
    public AjaxResult orderView(@RequestParam(value = "orderId") Long orderId) {
        BarLoginUser loginUser = SecurityUtils.getBarLoginUser();
        final WyRedeemOrder wyRedeemOrder = wyRedeemOrderService.selectWyRedeemOrderById(orderId);
        if (wyRedeemOrder == null || !Objects.equals(wyRedeemOrder.getBarId(), loginUser.getUser().getBarId())) {
            return AjaxResult.error("订单不存在或不属于该商户");
        }
        return AjaxResult.success(wyRedeemOrder);
    }
}
