package shop.alien.store.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.StringUtil;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.second.SecondGoods;
import shop.alien.entity.second.vo.SecondGoodsRecommendVo;
import shop.alien.entity.store.*;
import shop.alien.entity.store.vo.StoreInfoVo;
import shop.alien.mapper.*;
import shop.alien.mapper.second.SecondGoodsMapper;
import shop.alien.mapper.second.SecondRecommendMapper;
import shop.alien.store.annotation.TrackEvent;
import shop.alien.store.config.GaoDeMapUtil;
import shop.alien.util.common.JwtUtil;
import shop.alien.util.common.ListToPage;
import shop.alien.util.type.LifeCollectIdentityQuery;
import shop.alien.util.type.TypeUtil;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 收藏
 */
@Api(tags = {"一期-收藏"})
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/collect")
@RequiredArgsConstructor
public class LifeCollectController {

    private final LifeCollectMapper lifeCollectMapper;


    private SecondRecommendMapper secondRecommendMapper;

    private final LifeUserMapper lifeUserMapper;

    private final SecondGoodsMapper secondGoodsMapper;

    private final StoreInfoMapper storeInfoMapper;

    private final GaoDeMapUtil gaoDeMapUtil;

    private final LifeCouponMapper lifeCouponMapper;

    private final StoreEvaluationMapper storeEvaluationMapper;

    private final LifeUserOrderMapper lifeUserOrderMapper;

    private final StoreImgMapper storeImgMapper;

    private final LifeGroupBuyMainMapper lifeGroupBuyMainMapper;

    private final TypeUtil typeUtil;

    @ApiOperation("收藏列表")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "分页页数", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "size", value = "分页条数", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "jingdu", value = "jingdu", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "weidu", value = "weidu", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "businessSection", value = "经营板块", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "关键词", dataType = "String", paramType = "query")
    })
    @GetMapping("selectCollectList")
    public R<IPage<StoreInfoVo>> selectCollectList(@RequestParam(defaultValue = "1") int page,
                                                   @RequestParam(defaultValue = "10") int size,
                                                   @RequestParam String userId,
                                                   @RequestParam String jingdu,
                                                   @RequestParam String weidu,
                                                   @RequestParam String businessSection,
                                                   @RequestParam String keyword
    ) {
        log.info("LifeCollectController.selectCollectList?userId={},page={},size={},jingdu={},weidu={},businessSection={},keyword={}", userId, page, size, jingdu, weidu,businessSection,keyword);
        LambdaUpdateWrapper<LifeCollect> wrapper = new LambdaUpdateWrapper<>();
        LifeCollectIdentityQuery.applyUserSide(wrapper, LifeCollectIdentityQuery.resolve(userId, typeUtil));
        wrapper.eq(LifeCollect::getDeleteFlag, 0).isNotNull(LifeCollect::getStoreId).orderByDesc(LifeCollect::getCreatedTime);
        List<LifeCollect> lifeCollectList = lifeCollectMapper.selectList(wrapper);
        List<StoreInfoVo> storeVoList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(lifeCollectList)) {
            // 获取收藏的店铺id
            List<String> ids = lifeCollectList.stream().filter(x->null != x.getStoreId()).map(LifeCollect::getStoreId).collect(Collectors.toList());
            QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("a.id", ids).eq("a.delete_flag", 0);
            // 查询店铺团购信息
/*            LambdaUpdateWrapper<LifeCoupon> quanWrapper = new LambdaUpdateWrapper<>();
            quanWrapper.in(LifeCoupon::getStoreId, ids)
                    .eq(LifeCoupon::getStatus, 1)
                    .orderByDesc(LifeCoupon::getCreatedTime);
            List<LifeCoupon> quanList = lifeCouponMapper.selectList(quanWrapper);*/
            // 八大类分类
            if (!StringUtils.isEmpty(businessSection)) {
                queryWrapper.eq("a.business_section", businessSection);
            }
            // 关键词查询
            if (!StringUtils.isEmpty(keyword)) {
                queryWrapper.like("a.store_name", keyword);
            }
            // 计算店铺平均分 和 人均花销
            Map<Object, List<Map<String, Object>>> avgScoreMap = storeEvaluationMapper.allStoreAvgScore().stream().collect(Collectors.groupingBy(o -> o.get("store_id")));
            Map<Object, List<Map<String, Object>>> avgPriceMap =  lifeUserOrderMapper.allStoreAvgPrice().stream().collect(Collectors.groupingBy(o -> o.get("store_id")));
            List<StoreInfoVo> storeInfoVoList = storeInfoMapper.getStoreInfoVoList(queryWrapper);
            lifeCollectList.forEach(a -> {
                storeInfoVoList.forEach(b -> {
                    if (a.getStoreId().equals(b.getId().toString())) {
                        // 团购券设置
                        List<Map<String, Object>> quanMapList = new ArrayList<>();
                        /*if (!quanList.isEmpty()) {
                            for (LifeCoupon quan : quanList) {
                                if (b.getId().toString().equals(quan.getStoreId())) {
                                    Map<String, Object> quanMap = new HashMap<>();
                                    quanMap.put("quanType", quan.getType());
                                    quanMap.put("name", quan.getName());
                                    quanMap.put("price", quan.getPrice());
                                    // 折扣价
                                    quanMap.put("offprice", quan.getOffprice());
                                    quanMap.put("quanId", quan.getId());
                                    quanMapList.add(quanMap);
                                }
                            }
                        }*/
                        b.setQuanList(quanMapList);
                        // 得分,人均
                        b.setAvgScore("0");
                        b.setAvgPrice("0");
                        if (avgScoreMap.containsKey(String.valueOf(b.getId()))) {
                            b.setAvgScore(String.valueOf(avgScoreMap.get(String.valueOf(b.getId())).get(0).get("avg_score")));
                        }
                        if (avgPriceMap.containsKey(String.valueOf(b.getId()))) {
                            b.setAvgPrice(String.valueOf(avgPriceMap.get(String.valueOf(b.getId())).get(0).get("avg_price")));
                        }
                        if ((jingdu != null && !jingdu.isEmpty()) && (weidu != null && !weidu.isEmpty())) {
                            String[] split = b.getStorePosition().split(",");
                            double storeDistance;
                            try {
                                storeDistance = gaoDeMapUtil.getDistance(jingdu, weidu, split[0], split[1]);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                            DecimalFormat df = new DecimalFormat("#.0");
                            b.setDistance(Double.parseDouble(df.format(storeDistance / 1000)));
                        }
                        storeVoList.add(b);
                    }
                });
            });
        }
        return R.data(ListToPage.setPage(storeVoList, page, size));
    }

    @ApiOperation("团购收藏列表")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "分页页数", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "size", value = "分页条数", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "businessSection", value = "经营板块", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "关键词", dataType = "String", paramType = "query")
    })
    @GetMapping("selectCouponCollectList")
    public R<IPage<LifeGroupBuyMain>> selectCouponCollectList(@RequestParam(defaultValue = "1") int page,
                                                              @RequestParam(defaultValue = "10") int size,
                                                              @RequestParam String userId,
                                                              @RequestParam String businessSection,
                                                              @RequestParam String keyword){
        log.info("LifeCollectController.selectCouponCollectList?userId={},page={},size={},businessSection={},keyword={}", userId, page, size,businessSection,keyword);
        LambdaUpdateWrapper<LifeCollect> wrapper = new LambdaUpdateWrapper<>();
        LifeCollectIdentityQuery.applyUserSide(wrapper, LifeCollectIdentityQuery.resolve(userId, typeUtil));
        wrapper.eq(LifeCollect::getDeleteFlag, 0).isNotNull(LifeCollect::getCouponId).orderByDesc(LifeCollect::getCreatedTime);
        List<LifeCollect> lifeCollectList = lifeCollectMapper.selectList(wrapper);
        List<LifeGroupBuyMain> lifeCoupons = new ArrayList<>();
        if (!CollectionUtils.isEmpty(lifeCollectList)) {
            // 获取收藏的优惠券id
            List<String> ids = lifeCollectList.stream().map(LifeCollect::getCouponId).collect(Collectors.toList());
            QueryWrapper<LifeGroupBuyMain> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", ids).eq("delete_flag", 0).orderByDesc("created_time");
            // 八大类分类
            if (!StringUtils.isEmpty(businessSection)) {
                queryWrapper.eq("group_type", businessSection);
            }
            // 关键词查询
            if (!StringUtils.isEmpty(keyword)) {
                queryWrapper.like("group_name", keyword);
            }
//            lifeCoupons = lifeCouponMapper.selectList(queryWrapper);
            lifeCoupons = lifeGroupBuyMainMapper.selectList(queryWrapper);
            // 设置团购券图片
            List<String> imagesId = lifeCoupons.stream().map(LifeGroupBuyMain::getImageId).collect(Collectors.toList());
            if ( !CollectionUtils.isEmpty(imagesId) ){
                QueryWrapper<StoreImg> imgQueryWrapper = new QueryWrapper<>();
                imgQueryWrapper.in("id", imagesId);
                List<StoreImg> storeImgs = storeImgMapper.selectList(imgQueryWrapper);
                Map<String, List<StoreImg>> collect = storeImgs.stream().collect(Collectors.groupingBy(x -> String.valueOf(x.getId())));
                lifeCoupons.forEach(coupon -> {
                    String imgId = coupon.getImageId().split(",")[0];
                    if ( collect.containsKey(imgId) ){
                        coupon.setImageId(collect.get(imgId).get(0).getImgUrl());
                    }
                });
            }
        }
        return R.data(ListToPage.setPage(lifeCoupons, page, size));
    }

    @TrackEvent(
            eventType = "COLLECT",
            eventCategory = "INTERACTION",
            storeId = "#{#lifeCollect.storeId}",
            targetType = "STORE"
    )
    @ApiOperation("添加收藏")
    @ApiOperationSupport(order = 2)
    @PostMapping("addCollect")
    public R<Boolean> addCollect(LifeCollect lifeCollect) {
        log.info("LifeCollectController.addCollect?lifeCollect={}", lifeCollect.toString());
        lifeCollect.setCreatedTime(new Date());
        fillCollectUserIdentity(lifeCollect);
        int num = lifeCollectMapper.insert(lifeCollect);
        // 二手商品收藏数量+1
        if (StringUtil.isNotBlank(lifeCollect.getBusinessType()) && lifeCollect.getBusinessType().equals("1")) {
            LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(SecondGoods::getId, lifeCollect.getBusinessId());
            lambdaUpdateWrapper.setSql("collect_count = collect_count + 1");
            secondGoodsMapper.update(null, lambdaUpdateWrapper);
        }

        //同步店铺收藏数量
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(lifeCollect.getStoreId())) {
            LambdaQueryWrapper<LifeCollect> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LifeCollect::getStoreId, lifeCollect.getStoreId());
            storeInfoMapper.update(null, new LambdaUpdateWrapper<StoreInfo>().eq(StoreInfo::getId, lifeCollect.getStoreId()).set(StoreInfo::getCollectNum, lifeCollectMapper.selectCount(queryWrapper)));
        }


        if (num == 0) {
            return R.fail("收藏失败");
        }
        return R.success("收藏成功");
    }

    /**
     * 解析 user_{phone}/store_{phone}/lawyer_{phone}，写入 user_id_user_type、user_id_ref_id
     */
    private void fillCollectUserIdentity(LifeCollect lifeCollect) {
        LifeCollectIdentityQuery.fillIdentityOnCollect(lifeCollect, typeUtil, lifeUserMapper);
    }

    @ApiOperation("取消收藏")
    @ApiOperationSupport(order = 3)
    @ApiImplicitParams({@ApiImplicitParam(name = "userId", value = "用户id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "storeId", value = "店铺id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "businessId", value = "业务id", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "businessType", value = "业务类型", dataType = "String", paramType = "query")})
    @PostMapping("cancelCollect")
    public R<Boolean> cancelCollect(
            @RequestParam(value = "userId", required = false) String userId,
            @RequestParam(value = "storeId", required = false) String storeId,
            @RequestParam(value = "businessId", required = false) String businessId,
            @RequestParam(value = "businessType", required = false) String businessType,
            @RequestParam(value = "couponId", required = false) String couponId) {
        log.info("LifeCollectController.cancelCollect?userId={},storeId={},businessId={},businessType={}", userId, storeId, businessId, businessType);
        LambdaUpdateWrapper<LifeCollect> wrapper = new LambdaUpdateWrapper<>();
        LifeCollectIdentityQuery.applyUserSide(wrapper, LifeCollectIdentityQuery.resolve(userId, typeUtil));
        if(!StringUtils.isEmpty(storeId)) {
            wrapper.eq(LifeCollect::getStoreId, storeId);
        } else if (!StringUtils.isEmpty(couponId)){
            wrapper.eq(LifeCollect::getCouponId, couponId);
        }
        if (StringUtil.isNotBlank(businessType) && businessType.equals("1")) {
            wrapper.eq(LifeCollect::getBusinessId, businessId);
            wrapper.eq(LifeCollect::getBusinessType, businessType);
        } else {
            if(null == storeId){
                wrapper.isNull(LifeCollect::getStoreId);
            } else {
                wrapper.eq(LifeCollect::getStoreId, storeId);
            }
        }
        wrapper.set(LifeCollect::getDeleteFlag, 1);
        int num = lifeCollectMapper.update(null, wrapper);

        if (num == 0) {
            return R.fail("取消收藏失败");
        }

        // 二手交易收藏数量-1
        if (StringUtil.isNotBlank(businessType) && businessType.equals("1")) {
            // 创建LambdaUpdateWrapper实例用于构建更新条件
            LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            // 设置更新条件：根据商品ID匹配且收藏数大于0
            lambdaUpdateWrapper.eq(SecondGoods::getId, businessId).gt(SecondGoods::getCollectCount, 0);
            // 执行SQL语句将收藏数减1
            lambdaUpdateWrapper.setSql("collect_count = collect_count - 1");
            secondGoodsMapper.update(null, lambdaUpdateWrapper);
        }
        return R.success("取消收藏成功");
    }


    @ApiOperation("收藏商品列表")
    @PostMapping("/collectSecondGoodsByPage")
    public R<IPage<SecondGoodsRecommendVo>> collectSecondGoodsByPage(
            @RequestParam(value = "pageNum", required = false) Integer pageNum,
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
            @RequestParam(value = "longitude", required = false) String longitude,
            @RequestParam(value = "latitude", required = false) String latitude) throws Exception {
        log.info("LifeCollectController.cancelCollect?pageNum={},pageSize={},longitude={},latitude={}", pageNum, pageSize, longitude, latitude);
        try {
            IPage<SecondGoodsRecommendVo> page = new Page<>(pageNum, pageSize);
            JSONObject data = JwtUtil.getCurrentUserInfo();
            String phoneId = null;
            Integer userId = null;
            if (data != null) {
                phoneId = data.getString("phone");
                userId = data.getInteger("userId");
            }
            if (StringUtil.isBlank(phoneId)) {
                return null;
            }
            // 获取商品屏蔽列表
            List<SecondGoods> shieldedGoodsList = getShieldedGoodsList(userId);
            // 提取屏蔽商品ID
            List<Integer> shieldedGoodsIds = shieldedGoodsList.stream()
                    .map(SecondGoods::getId)
                    .collect(Collectors.toList());

//            QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
//            queryWrapper
//                    // 可以查看已删除的商品数据
//                    .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
//                    .eq("lc.delete_flag", Constants.DeleteFlag.NOT_DELETED)
//                    .notIn(CollectionUtil.isNotEmpty(shieldedGoodsIds), "sg.id", shieldedGoodsIds)
//                    .eq("lc.user_id", "user_"+lifeUser.getUserPhone())
//                    .orderByDesc("lc.created_time");

            LifeCollectIdentityQuery.Scope collectScope = LifeCollectIdentityQuery.fromLifeUserId(userId);
            IPage<SecondGoodsRecommendVo> list = lifeCollectMapper.collectSecondGoodsByPage(page, userId, collectScope.getUserType(), collectScope.getRefId(), longitude + "," + latitude, shieldedGoodsIds);
            List<Integer> idList = list.getRecords().stream() // 创建流
                    .map(obj -> obj.getId())   // 提取每个元素的 ID
                    .collect(Collectors.toList());
            if (CollectionUtil.isEmpty(idList)) {
                return R.data(list);
            }
//            List<SecondCommentVo> commentList =secondRecommendMapper.querySecondCommentInfo(idList);
            list.getRecords().forEach(item -> {
                // 距离拼接
                if (StringUtil.isNotBlank(item.getDist())) {
                    item.setPosition("距离" + item.getDist() + "km");
                }
                // 价格保留两位小数
                item.setPrice(item.getAmount() != null ? item.getAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toString() : null);

                // 评论列表
//                List<SecondCommentVo> cList = new ArrayList<>();
//                commentList.forEach(comment -> {
//                    if (item.getId().equals(comment.getBusinessId())) {
//                        cList.add(comment);
//                    }
//                });
//                if (cList.size() > 0) {
//                    item.setCommentList(cList);
//                }
            });
            return R.data(list);
        } catch (Exception e){
            log.error("收藏商品列表 Error Mgs={}", e.getMessage());
            throw new Exception(e);
        }
    }

    /**
     * 获取商品屏蔽列表
     * @param userId 用户ID
     * @return 商品屏蔽列表
     */
    private List<SecondGoods> getShieldedGoodsList(Integer userId) {
        // 调用mapper方法
        return secondGoodsMapper.getShieldedGoodsList(userId);
    }
}
