package com.slodon.b2b2c.controller.goods.front;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.slodon.b2b2c.core.constant.GoodsCategoryConst;
import com.slodon.b2b2c.core.constant.GoodsConst;
import com.slodon.b2b2c.core.constant.RedisConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.i18n.Language;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.core.util.UserUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.enums.SeoTypeConstant;
import com.slodon.b2b2c.goods.dto.SearchConditionDTO;
import com.slodon.b2b2c.goods.example.*;
import com.slodon.b2b2c.goods.pojo.*;
import com.slodon.b2b2c.member.pojo.Member;
import com.slodon.b2b2c.model.goods.*;
import com.slodon.b2b2c.model.seller.StoreModel;
import com.slodon.b2b2c.vo.goods.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Api(tags = "front-分类列表")
@RestController
@RequestMapping("v3/goods/front/goods/category")
public class FrontGoodsCategoryController extends BaseController {

    @Resource
    private GoodsCategoryModel goodsCategoryModel;
    @Resource
    private GoodsBrandModel goodsBrandModel;
    @Resource
    private GoodsAttributeModel goodsAttributeModel;
    @Resource
    private GoodsAttributeValueModel goodsAttributeValueModel;
    @Resource
    private GoodsCategoryBindBrandModel goodsCategoryBindBrandModel;
    @Resource
    private GoodsCategoryBindAttributeModel goodsCategoryBindAttributeModel;
    @Resource
    private ESGoodsModel esGoodsModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private StoreModel storeModel;

    @ApiOperation("一级分类列表")
    @GetMapping("topCategory")
    public JsonResult<List<FrontGoodsCategoryVO>> topCategory(HttpServletRequest request) {
        List<FrontGoodsCategoryVO> vos = new ArrayList<>();
        String webSite = WebUtil.getWebSite(request);
        //查询redis缓存
        String dataJson = stringRedisTemplate.opsForValue().get(RedisConst.GOODS_CATEGORY + "_" + webSite);
        if (!StringUtils.isEmpty(dataJson)) {
            JSONArray jsonArray = JSONArray.parseArray(dataJson);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                FrontGoodsCategoryVO vo = new FrontGoodsCategoryVO();
                vo.setWebSite(jsonObject.getString("webSite"));
                vo.setCategoryId(jsonObject.getInteger("categoryId"));
                vo.setCategoryName(jsonObject.getString("categoryName"));
                vo.setPid(jsonObject.getInteger("pid"));
                vo.setGrade(jsonObject.getInteger("grade"));
                vo.setMobileImage(jsonObject.getString("mobileImage"));
                vos.add(vo);
            }
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("二三级分类")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId1", value = "一级分类Id", required = true)
    })
    @GetMapping("bottomCategory")
    public JsonResult<List<FrontGoodsCategoryVO>> bottomCategory(HttpServletRequest request, Integer categoryId1) {
        List<FrontGoodsCategoryVO> vos = new ArrayList<>();
        String webSite = WebUtil.getWebSite(request);
        //查询redis缓存
        String dataJson = stringRedisTemplate.opsForValue().get(RedisConst.FRONT_GOODS_CATEGORY + "_" + webSite);
        if (!StringUtils.isEmpty(dataJson)) {
            JSONArray jsonArray = JSONArray.parseArray(dataJson);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Integer categoryId = jsonObject.getInteger("categoryId");
                if (categoryId1.equals(categoryId)) {
                    JSONArray array2 = JSONArray.parseArray(jsonObject.getString("children"));
                    if (!CollectionUtils.isEmpty(array2)) {
                        for (int j = 0; j < array2.size(); j++) {
                            JSONObject object = array2.getJSONObject(j);
                            FrontGoodsCategoryVO categoryVO = new FrontGoodsCategoryVO();
                            categoryVO.setCategoryId(object.getInteger("categoryId"));
                            categoryVO.setCategoryName(object.getString("categoryName"));
                            categoryVO.setPid(object.getInteger("pid"));
                            categoryVO.setGrade(object.getInteger("grade"));
                            JSONArray array3 = JSONArray.parseArray(object.getString("children"));
                            List<FrontGoodsCategoryVO> children = new ArrayList<>();
                            if (!CollectionUtils.isEmpty(array3)) {
                                for (int k = 0; k < array3.size(); k++) {
                                    JSONObject jsonObject2 = array3.getJSONObject(k);
                                    FrontGoodsCategoryVO goodsCategoryVO = new FrontGoodsCategoryVO();
                                    goodsCategoryVO.setCategoryId(jsonObject2.getInteger("categoryId"));
                                    goodsCategoryVO.setCategoryName(jsonObject2.getString("categoryName"));
                                    goodsCategoryVO.setPid(jsonObject2.getInteger("pid"));
                                    goodsCategoryVO.setGrade(jsonObject2.getInteger("grade"));
                                    goodsCategoryVO.setCategoryImage(jsonObject2.getString("categoryImage"));
                                    children.add(goodsCategoryVO);
                                }
                            }
                            categoryVO.setChildren(children);
                            vos.add(categoryVO);
                        }
                    }
                    break;
                }
            }
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("逐级获取分类列表接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId", value = "分类Id", paramType = "query", required = true),
            @ApiImplicitParam(name = "grade", value = "分类级别: 1-一级，2-二级，3-三级", paramType = "query", required = true)
    })
    @GetMapping("listByPId")
    public JsonResult<List<FrontGoodsCategoryVO>> listByPId(HttpServletRequest request,
                                                            @RequestParam(value = "categoryId", defaultValue = "0") Integer categoryId,
                                                            @RequestParam(value = "grade", defaultValue = "1") Integer grade) {
        List<FrontGoodsCategoryVO> vos = new ArrayList<>();

        String webSite = WebUtil.getWebSite(request);
                //查询redis缓存
        String dataJson = stringRedisTemplate.opsForValue().get(RedisConst.FRONT_GOODS_CATEGORY + "_" + webSite);
        if (!StringUtils.isEmpty(dataJson)) {
            JSONArray jsonArray = JSONArray.parseArray(dataJson);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                if (grade == GoodsCategoryConst.CATEGORY_GRADE_1) {
                    FrontGoodsCategoryVO vo = new FrontGoodsCategoryVO();
                    Integer categoryId1 = jsonObject.getInteger("categoryId");
                    vo.setCategoryId(categoryId1);
                    vo.setCategoryName(jsonObject.getString("categoryName"));
                    vo.setPid(jsonObject.getInteger("pid"));
                    vo.setGrade(jsonObject.getInteger("grade"));

                    SysSeoVO  sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(
                            Integer.valueOf(vo.getCategoryId()).longValue(), SeoTypeConstant.SEO_TYPE_GOODS_CATEGORY,webSite);
                    vo.setSeoInfo(sysSeoVO);
                    if (categoryId1.equals(categoryId)) {
                        JSONArray array = JSONArray.parseArray(jsonObject.getString("children"));
                        List<FrontGoodsCategoryVO> children = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(array)) {
                            for (int k = 0; k < array.size(); k++) {
                                JSONObject jsonObject1 = array.getJSONObject(k);
                                FrontGoodsCategoryVO categoryVO = new FrontGoodsCategoryVO();
                                categoryVO.setCategoryId(jsonObject1.getInteger("categoryId"));
                                categoryVO.setCategoryName(jsonObject1.getString("categoryName"));
                                categoryVO.setPid(jsonObject1.getInteger("pid"));
                                categoryVO.setGrade(jsonObject1.getInteger("grade"));
                                categoryVO.setChildren(null);
                                sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(
                                        Integer.valueOf(categoryVO.getCategoryId()).longValue(), SeoTypeConstant.SEO_TYPE_GOODS_CATEGORY, webSite);
                                categoryVO.setSeoInfo(sysSeoVO);
                                children.add(categoryVO);
                            }
                        }
                        vo.setChildren(children);
                    }
                    vos.add(vo);
                } else if (grade == GoodsCategoryConst.CATEGORY_GRADE_2) {
                    JSONArray array2 = JSONArray.parseArray(jsonObject.getString("children"));
                    if (!CollectionUtils.isEmpty(array2)) {
                        for (int j = 0; j < array2.size(); j++) {
                            JSONObject object = array2.getJSONObject(j);
                            Integer categoryId2 = object.getInteger("categoryId");
                            if (categoryId2.equals(categoryId)) {
                                FrontGoodsCategoryVO vo = new FrontGoodsCategoryVO();
                                vo.setCategoryId(object.getInteger("categoryId"));
                                vo.setCategoryName(object.getString("categoryName"));
                                vo.setPid(object.getInteger("pid"));
                                vo.setGrade(object.getInteger("grade"));
                                SysSeoVO sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(
                                        Integer.valueOf(vo.getCategoryId()).longValue(), SeoTypeConstant.SEO_TYPE_GOODS_CATEGORY,webSite);
                                vo.setSeoInfo(sysSeoVO);
                                JSONArray array3 = JSONArray.parseArray(object.getString("children"));
                                if (!CollectionUtils.isEmpty(array3)) {
                                    List<FrontGoodsCategoryVO> children = new ArrayList<>();
                                    for (int k = 0; k < array3.size(); k++) {
                                        JSONObject jsonObject1 = array3.getJSONObject(k);
                                        FrontGoodsCategoryVO categoryVO = new FrontGoodsCategoryVO();
                                        categoryVO.setCategoryId(jsonObject1.getInteger("categoryId"));
                                        categoryVO.setCategoryName(jsonObject1.getString("categoryName"));
                                        categoryVO.setPid(jsonObject1.getInteger("pid"));
                                        categoryVO.setGrade(jsonObject1.getInteger("grade"));
                                        categoryVO.setChildren(null);
                                        sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(
                                                Integer.valueOf(categoryVO.getCategoryId()).longValue(), SeoTypeConstant.SEO_TYPE_GOODS_CATEGORY,webSite);
                                        categoryVO.setSeoInfo(sysSeoVO);
                                        children.add(categoryVO);
                                    }
                                    vo.setChildren(children);
                                }
                                vos.add(vo);
                            }
                        }
                    }
                } else {
                    JSONArray array2 = JSONArray.parseArray(jsonObject.getString("children"));
                    if (!CollectionUtils.isEmpty(array2)) {
                        for (int j = 0; j < array2.size(); j++) {
                            JSONObject object = array2.getJSONObject(j);
                            Integer categoryId2 = object.getInteger("categoryId");
                            if (categoryId2.equals(categoryId)) {
                                JSONArray array3 = JSONArray.parseArray(object.getString("children"));
                                if (!CollectionUtils.isEmpty(array3)) {
                                    for (int k = 0; k < array3.size(); k++) {
                                        JSONObject jsonObject1 = array3.getJSONObject(k);
                                        FrontGoodsCategoryVO vo = new FrontGoodsCategoryVO();
                                        vo.setCategoryId(jsonObject1.getInteger("categoryId"));
                                        vo.setCategoryName(jsonObject1.getString("categoryName"));
                                        vo.setPid(jsonObject1.getInteger("pid"));
                                        vo.setGrade(jsonObject1.getInteger("grade"));
                                        vo.setChildren(null);
                                        SysSeoVO sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(
                                                Integer.valueOf(vo.getCategoryId()).longValue(), SeoTypeConstant.SEO_TYPE_GOODS_CATEGORY,webSite);
                                        vo.setSeoInfo(sysSeoVO);
                                        vos.add(vo);
                                    }
                                }
                            }
                        }
                    }
                }

            }
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("首页分类商品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId1", value = "一级分类Id", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("list")
    public JsonResult<GoodsCategoryTreeVO> list(HttpServletRequest request, Integer categoryId1) {
        Member member = UserUtil.getUser(request, Member.class);
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        String webSite = WebUtil.getWebSite(request);
        List<GoodsCategoryTreeVO.CategoryInfoVO> categoryList = new ArrayList<>();
        List<GoodsListVO> goodsList = new ArrayList<>();
        //查询redis缓存
        String dataJson = stringRedisTemplate.opsForValue().get(RedisConst.FRONT_GOODS_CATEGORY + "_" + webSite);
        if (!StringUtils.isEmpty(dataJson)) {
            JSONArray jsonArray = JSONArray.parseArray(dataJson);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Integer categoryId = jsonObject.getInteger("categoryId");
                if (categoryId1.equals(categoryId)) {
                    JSONArray array2 = JSONArray.parseArray(jsonObject.getString("children"));
                    if (!CollectionUtils.isEmpty(array2)) {
                        for (int j = 0; j < array2.size(); j++) {
                            JSONObject object = array2.getJSONObject(j);
                            GoodsCategoryTreeVO.CategoryInfoVO vo = new GoodsCategoryTreeVO.CategoryInfoVO();
                            vo.setCategoryId(object.getInteger("categoryId"));
                            vo.setCategoryName(object.getString("categoryName"));
                            vo.setPid(object.getInteger("pid"));
                            vo.setGrade(object.getInteger("grade"));
                            vo.setCategoryImage(object.getString("categoryImage"));
                            categoryList.add(vo);

                            //查询当前一级分类下的商品列表
                            SearchConditionDTO qc = new SearchConditionDTO();
                            qc.setCategoryIds(categoryId1.toString());
                            qc.setWebSite(webSite);
                            goodsList = esGoodsModel.searchGoodsByES(qc, pager, member);
                        }
                    }
                    break;
                }
            }
        }
        return SldResponse.success(new GoodsCategoryTreeVO(categoryList, goodsList, pager));
    }

    @ApiOperation("筛选")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId", value = "二级分类Id或三级分类Id", paramType = "query")
    })
    @GetMapping("screenList")
    public JsonResult<GoodsScreenListVO> screenList(HttpServletRequest request, SearchConditionDTO qc, Integer categoryId) {
        GoodsScreenListVO vo = new GoodsScreenListVO();
        //是否需要使用ES查询默认的分类id；默认分类id：搜索到的商品的前500条记录中，三级分类最多的三级分类id
        boolean needDefaultCategoryId = false;
        if (StringUtil.isNullOrZero(categoryId)) {
            //未传分类id
            needDefaultCategoryId = true;
        } else {
            GoodsCategory goodsCategory = goodsCategoryModel.getGoodsCategoryByCategoryId(categoryId);
            AssertUtil.notNull(goodsCategory,"获取分类信息为空");
            if (goodsCategory.getGrade() != GoodsCategoryConst.CATEGORY_GRADE_3) {
                //传了分类id，但不是三级分类
                needDefaultCategoryId = true;
                qc.setCategoryIds(categoryId.toString());
            }
        }
        //查询默认分类id
        if (needDefaultCategoryId) {
            categoryId = esGoodsModel.getDefaultCategoryId(qc);
            log.debug("默认分类id：" + categoryId);
        }
        if (StringUtil.isNullOrZero(categoryId)) {
            //没有符合条件的结果
            return SldResponse.success(vo);
        }
        GoodsCategory goodsCategory = goodsCategoryModel.getGoodsCategoryByCategoryId(categoryId);
        AssertUtil.notNull(goodsCategory, "获取分类信息为空");

        GoodsCategoryExample example = new GoodsCategoryExample();
        example.setState(GoodsCategoryConst.CATEGORY_STATE_1);
        example.setOrderBy("sort asc, create_time desc");
        example.setPid(goodsCategory.getPid());
        List<GoodsCategory> categoryList = goodsCategoryModel.getGoodsCategoryList(example, null);
        List<GoodsScreenListVO.CategoryVO> categoryVOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(categoryList)) {
            categoryList.forEach(category -> {
                categoryVOS.add(new GoodsScreenListVO.CategoryVO(category.getCategoryId(), category.getCategoryName()));
            });
        }
        vo.setCategoryList(categoryVOS);

        //查询分类绑定的品牌
        GoodsCategoryBindBrandExample brandExample = new GoodsCategoryBindBrandExample();
        brandExample.setCategoryId(goodsCategory.getCategoryId());
        List<GoodsCategoryBindBrand> categoryBindBrandList = goodsCategoryBindBrandModel.getGoodsCategoryBindBrandList(brandExample, null);
        List<GoodsScreenListVO.BrandVO> brandVOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(categoryBindBrandList)) {
            categoryBindBrandList.forEach(categoryBindBrand -> {
                GoodsBrand goodsBrand = goodsBrandModel.getGoodsBrandByBrandId(categoryBindBrand.getBrandId());
                AssertUtil.notNull(goodsBrand, "品牌不存在");
                brandVOS.add(new GoodsScreenListVO.BrandVO(goodsBrand));
            });
        }
        vo.setBrandList(brandVOS);
        //查询分类绑定的属性
        GoodsCategoryBindAttributeExample attributeExample = new GoodsCategoryBindAttributeExample();
        attributeExample.setCategoryId(goodsCategory.getCategoryId());
        List<GoodsCategoryBindAttribute> categoryBindAttributeList = goodsCategoryBindAttributeModel.getGoodsCategoryBindAttributeList(attributeExample, null);
        List<GoodsScreenListVO.AttributeVO> attributeVOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(categoryBindAttributeList)) {
            StringBuffer attributeIds = new StringBuffer();
            categoryBindAttributeList.forEach(goodsCategoryBindAttribute -> {
                attributeIds.append(",").append(goodsCategoryBindAttribute.getAttributeId());
            });
            //查属性表中的对应属性
            GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
            goodsAttributeExample.setAttributeIdIn(attributeIds.toString().substring(1));
            goodsAttributeExample.setIsShow(GoodsConst.IS_ATTRIBUTE_YES);
            goodsAttributeExample.setOrderBy("sort asc, create_time desc");
            List<GoodsAttribute> goodsAttributeList = goodsAttributeModel.getGoodsAttributeList(goodsAttributeExample, null);
            goodsAttributeList.forEach(goodsAttribute -> {
                GoodsScreenListVO.AttributeVO attributeVO = new GoodsScreenListVO.AttributeVO(goodsAttribute.getAttributeId(), goodsAttribute.getAttributeName());
                //查询属性值
                GoodsAttributeValueExample valueExample = new GoodsAttributeValueExample();
                valueExample.setAttributeId(goodsAttribute.getAttributeId());
                List<GoodsAttributeValue> attributeValueList = goodsAttributeValueModel.getGoodsAttributeValueList(valueExample, null);
                AssertUtil.notEmpty(attributeValueList, "属性值不存在");
                List<GoodsScreenListVO.AttributeVO.AttributeValueVO> valueVOS = new ArrayList<>();
                attributeValueList.forEach(attributeValue -> {
                    valueVOS.add(new GoodsScreenListVO.AttributeVO.AttributeValueVO(attributeValue.getValueId(), attributeValue.getAttributeValue()));
                });
                attributeVO.setAttributeValueList(valueVOS);
                attributeVOS.add(attributeVO);
            });
        }
        vo.setAttributeList(attributeVOS);
        return SldResponse.success(vo);
    }

    /**
     * 只获取商品二级分类
     *
     * @param request
     * @return
     */
    @GetMapping("getSecondCategory")
    public JsonResult<List<FrontGoodsCategoryVO>> getSecondCategory(HttpServletRequest request) {
        String webSite = WebUtil.getWebSite(request);
        List<FrontGoodsCategoryVO> vos = new ArrayList<>();
        //查询redis缓存
        String dataJson = stringRedisTemplate.opsForValue().get(RedisConst.FRONT_GOODS_CATEGORY + "_" + webSite);
        if (!StringUtils.isEmpty(dataJson)) {
            JSONArray jsonArray = JSONArray.parseArray(dataJson);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray array2 = JSONArray.parseArray(jsonObject.getString("children"));
                if (!CollectionUtils.isEmpty(array2)) {
                    for (int j = 0; j < array2.size(); j++) {
                        JSONObject object = array2.getJSONObject(j);
                        FrontGoodsCategoryVO vo = new FrontGoodsCategoryVO();
                        if(object.getInteger("homeShow") != null && object.getInteger("homeShow") == GoodsCategoryConst.IS_SHOW_PC_1){
                            vo.setCategoryId(object.getInteger("categoryId"));
                            vo.setCategoryName(object.getString("categoryName"));
                            vo.setPid(object.getInteger("pid"));
                            vo.setGrade(object.getInteger("grade"));
                            vo.setHomeShow(object.getInteger("homeShow"));
                            SysSeoVO sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(
                                    Integer.valueOf(vo.getCategoryId()).longValue(), SeoTypeConstant.SEO_TYPE_GOODS_CATEGORY,webSite);
                            vo.setSeoInfo(sysSeoVO);
                            vos.add(vo);
                        }
                    }
                }
            }
        }
        return SldResponse.success(vos);
    }

}
