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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.slodon.b2b2c.core.constant.RedisConst;
import com.slodon.b2b2c.core.constant.ResponseConst;
import com.slodon.b2b2c.core.constant.StoreConst;
import com.slodon.b2b2c.core.constant.TplPcConst;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.FileUrlUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.enums.WebSiteConstant;
import com.slodon.b2b2c.goods.pojo.Goods;
import com.slodon.b2b2c.model.goods.GoodsModel;
import com.slodon.b2b2c.model.seller.StoreModel;
import com.slodon.b2b2c.model.seller.StoreNameModel;
import com.slodon.b2b2c.model.seller.StoreSiteInfoModel;
import com.slodon.b2b2c.model.system.TplPcMallDecoModel;
import com.slodon.b2b2c.seller.example.StoreNameExample;
import com.slodon.b2b2c.seller.pojo.Store;
import com.slodon.b2b2c.seller.pojo.StoreName;
import com.slodon.b2b2c.system.example.TplPcMallDecoExample;
import com.slodon.b2b2c.system.pojo.TplPcMallDeco;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
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.HashMap;
import java.util.List;
import java.util.Map;

import static com.alibaba.fastjson.serializer.SerializerFeature.WriteMapNullValue;

@Api(tags = "front-pc首页装修")
@RestController
@RequestMapping("/v3/system/front/pcDeco")
public class FrontPcDecoController {

    @Resource
    private TplPcMallDecoModel tplPcMallDecoModel;
    @Resource
    private StoreModel storeModel;
    @Resource
    private StoreNameModel storeNameModel;
    @Resource
    private GoodsModel goodsModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private StoreSiteInfoModel storeSiteInfoModel;

    @ApiOperation("pc首页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "decoType", value = "装修页类型(默认index-首页装修，topic-专题装修)", paramType = "query"),
            @ApiImplicitParam(name = "decoId", value = "商城装修页面组装信息id(topic类型必传)", paramType = "query")
    })
    @ApiResponses(
            @ApiResponse(code = 200, message = "data==装修数据")
    )
    @GetMapping("index")
    public JsonResult indexPage(HttpServletRequest request, @RequestParam(value = "decoType", required = false, defaultValue = "index") String decoType,
                                @RequestParam(value = "decoId", required = false) Integer decoId) {
        String webSite = WebUtil.getWebSite(request);
        Map<String, Object> modelMap = new HashMap();
        if ("index".equals(decoType) && StringUtil.isNullOrZero(decoId)) {
            //获取首页装修，先查redis缓存是否有数据
            String pcIndex = stringRedisTemplate.opsForValue().get(RedisConst.PC_INDEX + "_" + webSite);
            if (!StringUtils.isEmpty(pcIndex)) {
                modelMap.put("data", pcIndex);
                return SldResponse.success(modelMap);
            }
        }
        TplPcMallDeco deco = null;
        TplPcMallDecoExample example = new TplPcMallDecoExample();
        example.setWebSite(webSite);
        example.setIsEnable(TplPcConst.IS_ENABLE_YES);
        if ("index".equals(decoType) && StringUtil.isNullOrZero(decoId)) {
            example.setDecoType("index");
            example.setStoreId(0L);
            List<TplPcMallDeco> tplPcMallDecoList = tplPcMallDecoModel.getTplPcMallDecoList(example, null);
            if (!CollectionUtils.isEmpty(tplPcMallDecoList)) {
                deco = tplPcMallDecoList.get(0);
            }
        } else {
            deco = tplPcMallDecoModel.getTplPcMallDecoByDecoId(decoId);
        }

        if (deco == null) {
            return SldResponse.success(modelMap);
        }

        String data = deco.getData();
        //存入redis
        if ("index".equals(decoType) && StringUtil.isNullOrZero(decoId) && !StringUtil.isEmpty(data)) {
            stringRedisTemplate.opsForValue().set(RedisConst.PC_INDEX + "_" + webSite, data);
        }
        modelMap.put("data", data);
        return SldResponse.success(modelMap);
    }

    @ApiOperation("pc店铺首页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "店铺id", required = true),
            @ApiImplicitParam(name = "decoId", value = "装修页id", paramType = "query")
    })
    @ApiResponses(
            @ApiResponse(code = 200, message = "data==装修数据")
    )
    @GetMapping("sellerIndex")
    public JsonResult sellerIndexPage(HttpServletRequest request, @RequestParam(value = "storeId") Long storeId, Integer decoId) {
        String webSite = WebUtil.getWebSite(request);
        //查询店铺信息
        Store storeDb = storeModel.getStoreByStoreId(storeId);
        Integer state = storeDb.getState();
        if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            storeDb = storeSiteInfoModel.getStoreByStoreIdAndWebSite(storeDb.getStoreId(), WebSiteConstant.MEMBER_DISTRIBUTOR);
            if (!StringUtils.isEmpty(storeDb.getStoreId())) {
                StoreNameExample storeNameExample = new StoreNameExample();
                storeNameExample.setStoreId(storeDb.getStoreId());
                storeNameExample.setWebSite(WebSiteConstant.MEMBER_DISTRIBUTOR);
                StoreName storeName = storeNameModel.getStoreNameByExample(storeNameExample);
                storeDb.setStoreName(storeName != null ? storeName.getStoreName() : null);
                storeDb.setState(state);
            }
        }
        if (storeDb.getState().equals(StoreConst.STORE_STATE_CLOSE)) {
            JsonResult jsonResult = SldResponse.fail("店铺已关闭");
            jsonResult.setState(ResponseConst.STATE_STORE_CLOSE);
            return jsonResult;
        }
        if (storeDb.getBusinessState() == StoreConst.STORE_BUSINESS_STATE_DECORATION) {
            JsonResult jsonResult = SldResponse.fail("店铺装修筹备中");
            jsonResult.setState(ResponseConst.STATE_STORE_BUSINESS_STATE_DECORATION);
            return jsonResult;
        }
        if (storeDb.getBusinessState() == StoreConst.STORE_BUSINESS_STATE_CLOSE) {
            JsonResult jsonResult = SldResponse.fail("店铺暂停经营");
            jsonResult.setState(ResponseConst.STATE_STORE_BUSINESS_STATE_CLOSE);
            return jsonResult;
        }
        Map<String, Object> modelMap = new HashMap();
        String data = null;
        //decoId不为空说明是预览
        if (!StringUtil.isNullOrZero(decoId)) {
            TplPcMallDeco tplPcMallDeco = tplPcMallDecoModel.getTplPcMallDecoByDecoId(decoId);
            AssertUtil.notNull(tplPcMallDeco, "该装修页不存在");
            //如果店铺id不一致直接返回空数据
            if (!tplPcMallDeco.getStoreId().equals(storeId)) {
                return SldResponse.success(modelMap);
            }
            Object parse = JSON.parse(tplPcMallDeco.getData());
            this.dealGoodsSale(parse);
            data = JSON.toJSONString(parse, WriteMapNullValue);
        } else {
            TplPcMallDecoExample example = new TplPcMallDecoExample();
            example.setStoreId(storeId);
            example.setWebSite(webSite);
            example.setIsEnable(TplPcConst.IS_ENABLE_YES);
            example.setDecoType("index");
            List<TplPcMallDeco> tplPcMallDecoList = tplPcMallDecoModel.getTplPcMallDecoList(example, null);
            if (!CollectionUtils.isEmpty(tplPcMallDecoList)) {
                TplPcMallDeco deco = tplPcMallDecoList.get(0);
                Object parse = JSON.parse(deco.getData());
                this.dealGoodsSale(parse);
                data = JSON.toJSONString(parse, WriteMapNullValue);
            }
        }
        modelMap.put("data", data);
        return SldResponse.success(modelMap);
    }

    /**
     * 替换json对象中的商品销量
     *
     * @param object json对象
     */
    private void dealGoodsSale(Object object) {
        if (object instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) object;
            if (jsonObject.containsKey("goodsId")) {
                Long goodsId = jsonObject.getLong("goodsId");
                //查询商品信息
                Goods goods = goodsModel.getGoodsByGoodsId(goodsId);
                // 如果商品不存在或不是上架状态，则从JSON中移除该商品
                if (goods == null || goods.getState() == null || goods.getState() != 3) {
                    // 标记需要移除的商品，但不在遍历过程中直接移除
                    return;
                }
                if (jsonObject.containsKey("actualSales")) {
                    //销量
                    int salesVolume = goods.getActualSales() + goods.getVirtualSales();
                    jsonObject.put("actualSales", salesVolume);
                }
                if (jsonObject.containsKey("goodsPrice")) {
                    //价格
                    jsonObject.put("goodsPrice", goods.getGoodsPrice());
                }
                if (jsonObject.containsKey("mainImage")) {
                    //图片
                    jsonObject.put("mainImage", FileUrlUtil.getFileUrl(goods.getMainImage(), null));
                }
                if (jsonObject.containsKey("goodsName")) {
                    //名称
                    jsonObject.put("goodsName", goods.getGoodsName());
                }
            }
            jsonObject.values().forEach(this::dealGoodsSale);
            return;
        }
        if (object instanceof JSONArray) {
            JSONArray o = (JSONArray) object;
            // 使用迭代器以便在遍历过程中安全地移除元素
            o.removeIf(item -> {
                if (item instanceof JSONObject) {
                    JSONObject jsonObject = (JSONObject) item;
                    if (jsonObject.containsKey("goodsId")) {
                        Long goodsId = jsonObject.getLong("goodsId");
                        Goods goods = goodsModel.getGoodsByGoodsId(goodsId);
                        // 如果商品不存在或不是上架状态，则移除该商品
                        return goods == null || goods.getState() == null || goods.getState() != 3;
                    }
                }
                // 对于数组中的其他元素，递归处理
                dealGoodsSale(item);
                return false;
            });
        }
    }

}
