package com.cyksj.web.controller.manage.goods;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.annotation.Log;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.Jsons;
import com.cyksj.dto.Result;
import com.cyksj.enums.BusinessType;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.GoodsDonSkuMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.request.ReqGoodsSpuInsert;
import com.cyksj.model.manage.views.GoodsDonViewer;
import com.cyksj.model.views.CategoryGoodsCascadeView;
import com.cyksj.model.views.GoodsDetailView;
import com.cyksj.model.views.GoodsDonCategoryDetailView;
import com.cyksj.service.mange.CmsGoodsDonService;
import com.cyksj.service.mange.GoodsDonCategoryService;
import com.cyksj.service.mange.RefreshCacheService;
import com.cyksj.service.translations.BackInfoTranslationsFrontService;
import com.cyksj.service.translations.BackInfoTranslationsService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapBuilder;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chan
 * @date 2022/9/27 4:45 PM
 */

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/manage/goods")
public class CmsGoodsDonController {

    private final HttpServletRequest request;

    private final BeanSearcher beanSearcher;

    private final CmsGoodsDonService goodsDonService;

    private final RefreshCacheService refreshCacheService;

    private final GoodsDonCategoryService goodsDonCategoryService;

    private final GoodsDonSkuMapper skuMapper;

    private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;

    private final BackInfoTranslationsService backInfoTranslationsService;

    @GetMapping("/get")
    public Result<SearchResult<GoodsDonCategoryDetailView>> get(){
        SearchResult<GoodsDonCategoryDetailView> search = beanSearcher.search(GoodsDonCategoryDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(GoodsDonCategoryDetailView::getDeleted,true)
		        .put("condition", "(special_type is null or special_type != 'giftCard')")
		        .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 商品详情
     */
    @GetMapping("/get/{id}")
    public Result<GoodsDonViewer> getById(@PathVariable Long id) throws Exception {
        GoodsDonViewer goodsDonViewer = beanSearcher.searchFirst(GoodsDonViewer.class, MapUtils.builder().field(GoodsDonViewer::getId, id).build());
        if (StrUtil.isNotBlank(goodsDonViewer.getRecommendGoods())) {
            goodsDonViewer.setRecommendGoodsList(Jsons.parseList(goodsDonViewer.getRecommendGoods(), Long.class));
        }
        List<GoodsDonCategory> categoryView = goodsDonCategoryService.getCateGoryViewByGoodsId(id);
        goodsDonViewer.setCategoryList(categoryView.stream().map(GoodsDonCategory::getId).collect(Collectors.toList()));
        String lang = request.getHeader("lang");
        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
            backInfoTranslationsFrontService.setGoodsBackLanguage(goodsDonViewer, lang);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonViewer);
    }

    /**
     * 商品规格详情
     */
    @GetMapping("/get/sku/{id}")
    public Result<List<GoodsDonSku>> getSkuById(@PathVariable Long id, HttpServletRequest request) {
        List<GoodsDonSku> goodsDonSkus = beanSearcher.searchAll(GoodsDonSku.class, MapUtils.flatBuilder(request.getParameterMap()).field(GoodsDonSku::getGoodsId, id)
                .orderBy(GoodsDonSku::getSorted).asc()
                .build());
        String lang = request.getHeader("lang");
        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
            backInfoTranslationsFrontService.setSkuBackLanguage(goodsDonSkus, lang);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonSkus);
    }

    /**
     * 新增 商品spu
     */
    @PostMapping(value = "/post")
    @SaCheckPermission("platform:add")
    @Log(module = "平台管理/新增平台", businessType = BusinessType.POST, isSaveRequestData = true)
    public Result<Long> spuInsert(@Validated @RequestBody ReqGoodsSpuInsert spu) throws Exception {
        // 新增商品
        GoodsDon goods = new GoodsDon();
        if (spu.getSecondType() == null) {
            spu.setSecondType(2);
        }
        BeanUtil.copyProperties(spu, goods);
        if (StrUtil.isNotEmpty(goods.getRecommendTitle())) {
            if (CollUtil.isEmpty(spu.getRecommendGoodsList())) {
                throw BusinessRuntimeException.getInstance("请选择推荐的对应平台");
            }
        }
        goodsDonService.save(goods);
        //保存平台 分类的 关联
        List<Long> categoryList = spu.getCategoryList();
        if (CollUtil.isNotEmpty(categoryList)) {
            goodsDonCategoryService.saveBatchRelate(goods.getId(), categoryList);
        }
        refreshCacheService.refreshYhHomePageCache();
        return GatewayResponse.SUCCESS.newBuilder().toResult(goods.getId());
    }

    /**
     * 修改 商品spu
     */
    @PutMapping(value = "/update")
    @SaCheckPermission("platform:update")
    @Log(module = "平台管理/编辑平台", businessType = BusinessType.PUT, isSaveRequestData = true)
    public Result<String> spuUpdate(@Validated @RequestBody ReqGoodsSpuInsert spu) throws Exception{
        GoodsDon goods = new GoodsDon();
        BeanUtil.copyProperties(spu,goods);
        if (spu.getSpecialType() == null) {
            goods.setSpecialType(null);
        }
        if (StrUtil.isNotEmpty(goods.getRecommendTitle())) {
            if (CollUtil.isEmpty(spu.getRecommendGoodsList())) {
                throw BusinessRuntimeException.getInstance("请选择推荐的对应平台");
            }
        }
        if (CollUtil.isNotEmpty(spu.getRecommendGoodsList())) {
            Set<Long> re_goodsIds = new HashSet<>(spu.getRecommendGoodsList());
            //去除自己
            re_goodsIds.remove(spu.getId());
            goods.setRecommendGoods(Jsons.toJson(re_goodsIds));
        }
        if (StrUtil.isEmpty(goods.getRecommendTitle())) {
            goods.setRecommendTitle(null);
        }
        if (StrUtil.isEmpty(goods.getVideo())) {
            goods.setVideo(null);
        }
        if (CollUtil.isNotEmpty(spu.getRecommendGoodsList())) {
            Set<Long> re_goodsIds = new HashSet<>(spu.getRecommendGoodsList());
            //去除自己
            re_goodsIds.remove(spu.getId());
            goods.setRecommendGoods(Jsons.toJson(re_goodsIds));
        }
        String lang = request.getHeader("lang");
        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
            backInfoTranslationsService.saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type.goods, goods.getId(), goods, lang);
        } else {
            //平台 分类关系
            goodsDonCategoryService.handleGoodsRelate(goods.getId(), spu.getCategoryList());
            goodsDonService.updateById(goods);
        }
        refreshCacheService.refreshYhHomePageCache();
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }


    @PutMapping("/put/status/{id}")
    @SaCheckPermission("platform:updateStatus")
    @Log(module = "平台管理/平台上下架", businessType = BusinessType.PUT, isSaveRequestData = true, isSaveResponseData = true)
    public Result<Boolean> updateStatus(@PathVariable Long id) {
        GoodsDon goods = goodsDonService.getById(id);
        if (goods == null) {
            throw BusinessRuntimeException.getInstance("平台不存在");
        }
        goods.setStatus(!goods.getStatus());
        goodsDonService.updateById(goods);
        refreshCacheService.refreshYhHomePageCache();
        return GatewayResponse.SUCCESS.newBuilder().toResult(goods.getStatus());
    }

    @DeleteMapping("/delete/{id}")
    @SaCheckPermission("platform:delete")
    @Log(module = "平台管理/删除平台", businessType = BusinessType.DELETE, isSaveRequestData = true, isSaveResponseData = true)
    public Result<Long> deleteById(@PathVariable Long id) {
        GoodsDon goods = goodsDonService.getById(id);
        if (goods == null) {
            throw BusinessRuntimeException.getInstance("平台不存在");
        }
        goods.setDeleted(false);
        goodsDonService.updateById(goods);
        refreshCacheService.refreshYhHomePageCache();
        return GatewayResponse.SUCCESS.newBuilder().toResult(id);
    }

    /**
     * 获取所有平台列表
     */
    @GetMapping("/get/all")
    public Result<List<GoodsDon>> getAllGoodsList(Boolean isNoBuyout) {
        MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
        //过滤买断制 平台
        String conditionSql;
        if (isNoBuyout != null && isNoBuyout) {
            mapBuilder.field(GoodsDon::getSpecialType).op(Operator.IsNull);
            conditionSql = "(select count(*) from goods_don_sku sku where sku.goods_id = g.id and sku.months = 300) = 0";
        } else {
            conditionSql = "(special_type is null or special_type != 'giftCard')";
        }
        conditionSql += "  and exists (select id from goods_don_sku sku where sku.goods_id = g.id limit 1)";
        List<GoodsDon> goodsDons = beanSearcher.searchAll(GoodsDon.class, mapBuilder
                .put("condition", conditionSql)
                .field(GoodsDon::getDeleted, true)
                .onlySelect(GoodsDon::getId, GoodsDon::getCategory, GoodsDon::getType, GoodsDon::getTitle, GoodsDon::getSecondType,GoodsDon::getIsThirdGoods).build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDons);
    }

    /**
     * 获取礼品卡平台
     */
    @GetMapping("/get/giftCard")
    public Result<GoodsDon> getGiftCard() {
        GoodsDon goodsDon = beanSearcher.searchFirst(GoodsDon.class, MapUtils.builder()
                .field(GoodsDon::getSpecialType, GoodsDon.SpecialType.giftCard.name())
                .build());
        List<GoodsDonCategory> categoryView = goodsDonCategoryService.getCateGoryViewByGoodsId(goodsDon.getId());
        goodsDon.setCategoryList(categoryView.stream().map(GoodsDonCategory::getId).collect(Collectors.toList()));
        return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDon);
    }

    /**
     * 获取所有平台以及其规格
     */
    @GetMapping("/get/all/goods/sku")
    public Result<List<GoodsDetailView>> getAllGoodsDetail(Boolean isNoBuyout, Boolean isMirror) {
        MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
        //过滤买断制 平台
        String conditionSql;
        if (isNoBuyout != null && isNoBuyout) {
            mapBuilder.field(GoodsDon::getSpecialType).op(Operator.IsNull);
            conditionSql = "(select count(*) from goods_don_sku sku where sku.goods_id = g.id and sku.months = 300) = 0";
        } else {
            conditionSql = "(special_type is null or special_type != 'giftCard')";
        }
        String mirrorSql = StrUtil.EMPTY;
        if (isMirror != null) {
            mirrorSql += " and is_mirror = " + isMirror;
        }
        conditionSql += String.format("  and exists (select id from goods_don_sku sku where sku.goods_id = g.id %s limit 1)", mirrorSql);

        List<GoodsDetailView> goodsDons = beanSearcher.searchAll(GoodsDetailView.class, mapBuilder
                .put("condition", conditionSql)
                .field(GoodsDetailView::getType, 1)
                .field(GoodsDetailView::getStatus, 1)
                .field(GoodsDetailView::getDeleted, true)
                .onlySelect(GoodsDetailView::getId, GoodsDetailView::getTitle)
                .build());
        goodsDons.forEach(e -> {
            List<GoodsDonSku> donSkus = skuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
                    .eq(GoodsDonSku::getGoodsId, e.getId())
                    .eq(isMirror != null, GoodsDonSku::getIsMirror, isMirror)
                    .eq(GoodsDonSku::getStatus, 1)
                    .select(GoodsDonSku::getId, GoodsDonSku::getSpecVal));
            e.setSkuList(donSkus);
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDons);
    }

    /**
     * 所有分类平台 级联
     */
    @GetMapping("/get/category/goods/cascade")
    public Result<List<CategoryGoodsCascadeView>> getCategoryGoodsCascade() {
        List<CategoryGoodsCascadeView> categoryGoodsCascadeViews = beanSearcher.searchAll(CategoryGoodsCascadeView.class, MapUtils.builder().build());
        //按分类分组
        Map<String, List<CategoryGoodsCascadeView>> byType = categoryGoodsCascadeViews.stream()
                .collect(Collectors.groupingBy(CategoryGoodsCascadeView::getCategoryName));
        List<CategoryGoodsCascadeView> result = new ArrayList<>();
        byType.forEach((categoryName, data) -> {
            CategoryGoodsCascadeView cascadeView = new CategoryGoodsCascadeView();
            cascadeView.setLabel(categoryName);
            cascadeView.setValue(categoryName);
            List<CategoryGoodsCascadeView.ChildGoods> child = data.stream().map(view -> coverToChildGoods(view)).collect(Collectors.toList());
            cascadeView.setChildren(child);
            result.add(cascadeView);
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(result);
    }

    private CategoryGoodsCascadeView.ChildGoods coverToChildGoods(CategoryGoodsCascadeView cascadeView) {
        CategoryGoodsCascadeView.ChildGoods childGoods = new CategoryGoodsCascadeView.ChildGoods();
        childGoods.setValue(cascadeView.getGoodsId());
        childGoods.setLabel(cascadeView.getTitle());
        return childGoods;
    }
}
