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.decoration.DecoUtil;
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.goods.pojo.Goods;
import com.slodon.b2b2c.model.goods.GoodsModel;
import com.slodon.b2b2c.model.seller.StoreModel;
import com.slodon.b2b2c.model.system.PcFirstAdvModel;
import com.slodon.b2b2c.model.system.TplMobileDecoModel;
import com.slodon.b2b2c.seller.pojo.Store;
import com.slodon.b2b2c.system.example.PcFirstAdvExample;
import com.slodon.b2b2c.system.example.TplMobileDecoExample;
import com.slodon.b2b2c.system.pojo.PcFirstAdv;
import com.slodon.b2b2c.system.pojo.TplMobileDeco;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.ui.ModelMap;
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.WriteEnumUsingName;
import static com.alibaba.fastjson.serializer.SerializerFeature.WriteMapNullValue;

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

    @Resource
    private TplMobileDecoModel tplMobileDecoModel;
    @Resource
    private GoodsModel goodsModel;
    @Resource
    private PcFirstAdvModel pcFirstAdvModel;
    @Resource
    private StoreModel storeModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedisTemplate<String, Object> objectRedisTemplate;

    @ApiOperation("移动端首页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "os", value = "当前设备标识 可选值：android，ios，h5，weixinXcx，alipayXcx", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "装修页类型(首页-home;专题-topic;店铺-seller;活动-activity;积分商城首页-integral),默认不传", paramType = "query"),
            @ApiImplicitParam(name = "homeId", value = "首页id（预览时必传）", paramType = "query"),
            @ApiImplicitParam(name = "preview", value = "预览标识", paramType = "query")
    })
    @GetMapping("index")
    public JsonResult indexPage(String os, String homeId, String preview,
                                @RequestParam(value = "type", required = false, defaultValue = "home") String type) {
        if (type.equals("home") && !StringUtil.isEmpty(os)) {
            //获取首页装修数据，先查redis缓存是否有数据
            Object obj = objectRedisTemplate.opsForHash().get(RedisConst.MOBILE_INDEX, os);
            if (obj != null) {
                Map modelMap = (Map) obj;
                if (!StringUtil.isEmpty(os) && os.equals("weixinXcx")) {
                    modelMap.put("siteName", stringRedisTemplate.opsForValue().get("basic_site_name"));
                    modelMap.put("xcxImage", FileUrlUtil.getFileUrl(stringRedisTemplate.opsForValue().get("xcx_home_share_img"), null));
                }
                return SldResponse.success(modelMap);
            }
        }

        TplMobileDecoExample tplMobileDecoExample = new TplMobileDecoExample();
        if (!StringUtils.isEmpty(preview)) {
            if (DecoUtil.validatePreview(preview, homeId)) {
                tplMobileDecoExample.setDecoId(Integer.valueOf(homeId));
                tplMobileDecoExample.setStoreId(0L);
                tplMobileDecoExample.setType(type);
            } else {
                return SldResponse.unAuth();
            }
        } else {
            if (!StringUtil.isEmpty(os)) {
                switch (os) {
                    case "android":
                        tplMobileDecoExample.setAndroid(1);
                        break;
                    case "ios":
                        tplMobileDecoExample.setIos(1);
                        break;
                    case "h5":
                        tplMobileDecoExample.setH5(1);
                        break;
                    case "weixinXcx":
                        tplMobileDecoExample.setWeixinXcx(1);
                        break;
                    default:
                        break;
                }
            }
            tplMobileDecoExample.setStoreId(0L);
            tplMobileDecoExample.setType(type);
        }

        List<TplMobileDeco> list = tplMobileDecoModel.getTplMobileDecoList(tplMobileDecoExample, null);

        ModelMap modelMap = new ModelMap();
        if (!CollectionUtils.isEmpty(list)) {
            TplMobileDeco tplMobileDeco = list.get(0);
            if (!StringUtil.isEmpty(os) && os.equals("weixinXcx")) {
                modelMap.put("siteName", stringRedisTemplate.opsForValue().get("basic_site_name"));
                modelMap.put("xcxImage", FileUrlUtil.getFileUrl(stringRedisTemplate.opsForValue().get("xcx_home_share_img"), null));
            }
            modelMap.put("data", tplMobileDeco.getData());
            modelMap.put("showTip", tplMobileDeco.getShowTip());

            //装修页类型为首页并且设备标识不为空，存入redis
            if (type.equals("home") && !StringUtil.isEmpty(os)) {
                objectRedisTemplate.opsForHash().put(RedisConst.MOBILE_INDEX, os, modelMap);
            }
        }
        return SldResponse.success(modelMap);
    }

    @ApiOperation("移动端发现数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "os", value = "当前设备标识 可选值：android，ios，h5，weixinXcx，alipayXcx", paramType = "query")
    })
    @GetMapping("information")
    public JsonResult information(String os) {
        TplMobileDecoExample tplMobileDecoExample = new TplMobileDecoExample();

        if (!StringUtil.isEmpty(os)) {
            switch (os) {
                case "android":
                    tplMobileDecoExample.setAndroid(1);
                    break;
                case "ios":
                    tplMobileDecoExample.setIos(1);
                    break;
                case "h5":
                    tplMobileDecoExample.setH5(1);
                    break;
                case "weixinXcx":
                    tplMobileDecoExample.setWeixinXcx(1);
                    break;
                default:
                    break;
            }
        }
        tplMobileDecoExample.setStoreId(0L);
        tplMobileDecoExample.setType("information");

        List<TplMobileDeco> list = tplMobileDecoModel.getTplMobileDecoList(tplMobileDecoExample, null);

        ModelMap modelMap = new ModelMap();
        if (!CollectionUtils.isEmpty(list)) {
            String data = list.get(0).getData();
            if (!StringUtil.isEmpty(data)) {
                Object parse = JSON.parse(data);
                this.dealGoodsSale(parse);
                data = JSON.toJSONString(parse, WriteMapNullValue);
            }
            if (!StringUtil.isEmpty(os) && os.equals("weixinXcx")) {
                modelMap.put("siteName", stringRedisTemplate.opsForValue().get("basic_site_name"));
                modelMap.put("xcxImage", FileUrlUtil.getFileUrl(stringRedisTemplate.opsForValue().get("xcx_home_share_img"), null));
            }
            modelMap.put("data", data);
            modelMap.put("showTip", list.get(0).getShowTip());
        }
        return SldResponse.success(modelMap);
    }

    @ApiOperation("移动端活动或专题页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "decoId", value = "活动或专题id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "type", value = "页面类型：topic==专题，activity==活动", required = true, paramType = "query"),
            @ApiImplicitParam(name = "preview", value = "预览标识", paramType = "query")
    })
    @GetMapping("special")
    public JsonResult special(Integer decoId, String type, String preview) {
        TplMobileDeco tplMobileDeco;
        if (!StringUtils.isEmpty(preview)) {
            if (DecoUtil.validatePreview(preview, decoId.toString())) {
                tplMobileDeco = tplMobileDecoModel.getTplMobileDecoByDecoId(decoId);
            } else {
                return SldResponse.unAuth();
            }
        } else {
            tplMobileDeco = tplMobileDecoModel.getTplMobileDecoByDecoId(decoId);
        }
        if (null != tplMobileDeco) {
            if (tplMobileDeco.getType().equals(type)) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("name", tplMobileDeco.getName());
                String data = tplMobileDeco.getData();
                if (!StringUtil.isEmpty(data)) {
                    Object parse = JSON.parse(data);
                    this.dealGoodsSale(parse);
                    data = JSON.toJSONString(parse, WriteMapNullValue);
                }
                map.put("data", data);
                return SldResponse.success(map);
            }
        }
        return SldResponse.success();
    }

    @ApiOperation("移动端店铺首页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "店铺id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "os", value = "当前设备标识 可选值：android，ios，h5，weixinXcx，alipayXcx", paramType = "query"),
            @ApiImplicitParam(name = "homeId", value = "首页id（预览时必传）", paramType = "query"),
            @ApiImplicitParam(name = "preview", value = "预览标识", paramType = "query")
    })
    @GetMapping("storeIndex")
    public JsonResult storeIndex(String os, Long storeId, String homeId, String preview) {
        //查询店铺信息
        Store storeDb = storeModel.getStoreByStoreId(storeId);
        if (storeDb.getState().equals(StoreConst.STORE_STATE_CLOSE)) {
            JsonResult jsonResult = SldResponse.fail("店铺已关闭");
            jsonResult.setState(ResponseConst.STATE_STORE_CLOSE);
            return jsonResult;
        }
        TplMobileDecoExample tplMobileDecoExample = new TplMobileDecoExample();

        if (!StringUtils.isEmpty(preview)) {
            if (DecoUtil.validatePreview(preview, homeId)) {
                tplMobileDecoExample.setDecoId(Integer.valueOf(homeId));
                tplMobileDecoExample.setStoreId(storeId);
                tplMobileDecoExample.setType("home");
            } else {
                return SldResponse.unAuth();
            }
        } else {
            if (!StringUtil.isEmpty(os)) {
                switch (os) {
                    case "android":
                        tplMobileDecoExample.setAndroid(1);
                        break;
                    case "ios":
                        tplMobileDecoExample.setIos(1);
                        break;
                    case "h5":
                        tplMobileDecoExample.setH5(1);
                        break;
                    case "weixinXcx":
                        tplMobileDecoExample.setWeixinXcx(1);
                        break;
                    default:
                        break;
                }
            }
            tplMobileDecoExample.setStoreId(storeId);
            tplMobileDecoExample.setType("home");
        }

        List<TplMobileDeco> list = tplMobileDecoModel.getTplMobileDecoList(tplMobileDecoExample, null);

        ModelMap modelMap = new ModelMap();
        if (!CollectionUtils.isEmpty(list)) {
            String data = list.get(0).getData();
            if (!StringUtil.isEmpty(data)) {
                Object parse = JSON.parse(data);
                this.dealGoodsSale(parse);
                data = JSON.toJSONString(parse, WriteMapNullValue);
            }
            if (!StringUtil.isEmpty(os) && os.equals("weixinXcx")) {
                modelMap.put("siteName", stringRedisTemplate.opsForValue().get("basic_site_name"));
                modelMap.put("xcxImage", FileUrlUtil.getFileUrl(stringRedisTemplate.opsForValue().get("xcx_home_share_img"), null));
            }
            modelMap.put("data", data);
            modelMap.put("showTip", list.get(0).getShowTip());
        }
        return SldResponse.success(modelMap);
    }

    @ApiOperation("获取pc首页广告")
    @GetMapping("firstAdv")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "广告类型,1-弹层广告，2-顶部广告", required = false, defaultValue = "1")
    })
    public JsonResult<PcFirstAdv> getFirstAdv(HttpServletRequest request,@RequestParam(value = "type", required = false, defaultValue = "1") Integer type) {
        AssertUtil.isTrue(type != 1 && type != 2, "参数不对");
        PcFirstAdvExample example = new PcFirstAdvExample();
        example.setAdvId(type);
        example.setWebSite(WebUtil.getWebSite(request));
        List<PcFirstAdv> pcFirstAdvListList = pcFirstAdvModel.getPcFirstAdvList(example, null);
        if (CollectionUtils.isEmpty(pcFirstAdvListList)){
            return SldResponse.success();
        }
        return SldResponse.success(pcFirstAdvListList.get(0));
    }

    /**
     * 替换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;
            });
        }
    }
}
