package com.slodon.b2b2c.model.seller;

import com.alibaba.fastjson.JSONObject;
import com.gexin.fastjson.JSON;
import com.slodon.b2b2c.core.constant.GoodsConst;
import com.slodon.b2b2c.core.constant.NumConstant;
import com.slodon.b2b2c.core.constant.TplPcConst;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.b2b2c.core.uid.GoodsIdGenerator;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.dao.read.goods.GoodsAnnexReadMapper;
import com.slodon.b2b2c.dao.write.goods.GoodsAnnexWriterMapper;
import com.slodon.b2b2c.dao.write.goods.GoodsBindReserveNameWriteMapper;
import com.slodon.b2b2c.dao.write.seller.StoreLabelBindGoodsWriteMapper;
import com.slodon.b2b2c.goods.example.*;
import com.slodon.b2b2c.goods.pojo.*;
import com.slodon.b2b2c.member.example.GoodsAnnexExample;
import com.slodon.b2b2c.model.goods.*;
import com.slodon.b2b2c.model.system.TplPcMallDecoModel;
import com.slodon.b2b2c.seller.example.StoreLabelBindGoodsExample;
import com.slodon.b2b2c.seller.pojo.Store;
import com.slodon.b2b2c.seller.pojo.StoreApply;
import com.slodon.b2b2c.seller.pojo.StoreLabelBindGoods;
import com.slodon.b2b2c.seller.pojo.Vendor;
import com.slodon.b2b2c.system.pojo.TplPcMallDeco;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

@Component
@Slf4j
public class StoreCreateDataModel {

    @Resource
    private GoodsModel goodsModel;

    @Resource
    private TplPcMallDecoModel tplPcMallDecoModel;

    @Resource
    private GoodsSellerModel goodsSellerModel;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private GoodsExtendModel goodsExtendModel;

    @Resource
    private ProductModel productModel;

    @Resource
    private GoodsBindAttributeValueModel goodsBindAttributeValueModel;

    @Resource
    private GoodsBindLabelModel goodsBindLabelModel;

    @Resource
    private GoodsPictureModel goodsPictureModel;

    @Resource
    private GoodsBindReserveNameModel goodsBindReserveNameModel;

    @Resource
    private StoreLabelBindGoodsModel storeLabelBindGoodsModel;

    @Resource
    private StoreLabelBindGoodsWriteMapper storeLabelBindGoodsWriteMapper;

    @Resource
    private GoodsBindReserveNameWriteMapper goodsBindReserveNameWriteMapper;

    @Resource
    private GoodsAnnexReadMapper goodsAnnexReadMapper;

    @Resource
    private GoodsAnnexWriterMapper goodsAnnexWriterMapper;

    @Resource
    private StoreModel storeModel;

    /**
     * 复制店铺默认首页,用于入驻店铺初始默认首页
     *
     * @param storeApply
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer getNewStoreDefaultTpl(Vendor vendor, StoreApply storeApply,String webSite) {
        int decoId = TplPcConst.TPL_DEFAULT_1;
        TplPcMallDeco tplPcMallDecoDb = tplPcMallDecoModel.getTplPcMallDecoByDecoId(decoId);
        AssertUtil.notNull(tplPcMallDecoDb, "店铺默认首页不存在，请重新选择");

        TplPcMallDeco deco = new TplPcMallDeco();
        deco.setWebSite(webSite);
        deco.setDecoType(tplPcMallDecoDb.getDecoType());
        deco.setDecoName(tplPcMallDecoDb.getDecoName() + "-" + storeApply.getStoreName());
        deco.setData(tplPcMallDecoDb.getData());
        deco.setIsEnable(TplPcConst.IS_ENABLE_NO);
        deco.setCreateUserId(vendor.getVendorId());
        deco.setCreateUserName(vendor.getVendorName());
        deco.setCreateTime(new Date());
        deco.setUpdateUserId(vendor.getVendorId());
        deco.setUpdateUserName(vendor.getVendorName());
        deco.setUpdateTime(new Date());
        deco.setStoreId(storeApply.getStoreId());
        int count = tplPcMallDecoModel.saveTplPcMallDeco(deco,false);
        if (count == 0) {
            throw new MallException("店铺首页创建失败，请重试");
        }
        return count;
    }

    /**
     * 复制商品表,用于入驻店铺的初始商品展示
     *
     * @param newStoreId 被赋商品的店铺id
     */
    @Transactional(rollbackFor = Exception.class)
    public List<Map<String, Object>> getNewStoreDefaultGoods(Long newStoreId) {
        //-保存商品信息
        return this.getGoodsInfoByStoreId(newStoreId);
    }

    /**
     * @param newStoreId
     * @return
     */
    public List<Map<String, Object>> getGoodsInfoByStoreId(Long newStoreId) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        GoodsExample goodsExample = new GoodsExample();
        goodsExample.setStoreId(TplPcConst.TPL_STORE_ID);
        goodsExample.setId(108L);
        //查询店铺id=310002的商品list
        List<Goods> goodsList = goodsModel.getGoodsList(goodsExample, null);
        if (!CollectionUtils.isEmpty(goodsList)) {
            goodsList.forEach(goods -> {
                Map<String, Object> map = new HashMap<>();
                map.put("id", goods.getId());
                map.put("goodsId", goods.getGoodsId());
                map.put("goodDefaultProductId", goods.getDefaultProductId());
                map.put("getGoodsInfo", getGoodsInfo(goods.getGoodsId()));
                map.put("getGoodsExtendInfo", getGoodsExtendInfo(goods.getGoodsId()));
                map.put("getProductInfo", getProductInfo(goods.getGoodsId()));
                map.put("getGoodsBindAttribute", getGoodsBindAttribute(goods.getGoodsId()));
                map.put("getGoodsBindLabels", getGoodsBindLabels(goods.getGoodsId()));
                map.put("getGoodsPicture", getGoodsPicture(goods.getGoodsId()));
                map.put("getGoodsBindStoreInnerLabels", getGoodsBindStoreInnerLabels(goods.getGoodsId()));
                map.put("getGoodsBindReserveName", getGoodsBindReserveName(goods.getGoodsId()));

                // 商品附件
                map.put("getGoodsAnnex", goodsAnnexList(goods.getGoodsId()));

                Map<String, Object> map2 = new HashMap<>();
                map2.put("id", goods.getId());
                map2.put("goodsId", goods.getGoodsId());
                map2.put("goodDefaultProductId", goods.getDefaultProductId());
                map2.put("goodsAllInfo", map);
                mapList.add(map2);
            });
        }

        log.info("mapList:{}", JSON.toJSONString(mapList));

        if (!CollectionUtils.isEmpty(mapList)) {
            mapList.forEach(c -> {
                Store store = storeModel.getStoreByStoreId(newStoreId);

                Map<String, Object> map = (Map<String, Object>) c.get("goodsAllInfo");
                log.info("**** map:{} *****", JSON.toJSONString(map));

                Goods goods = JSONObject.parseObject(JSON.toJSONString(map.get("getGoodsInfo")), Goods.class);
                log.info("goods:{}", JSON.toJSONString(goods));
                goods.setStoreId(newStoreId);
                goods.setIsSelf(NumConstant.TWO);
                goods.setIsRecommend(NumConstant.ZERO);
                goods.setOnlineTime(null);
                goods.setBrandId(null);
                goods.setBrandName(null);
                goods.setStoreName(store.getStoreName());
                Goods newGoodsInfo = insertGoods(goods);

                GoodsExtend goodsExtend = JSONObject.parseObject(JSON.toJSONString(map.get("getGoodsExtendInfo")), GoodsExtend.class);
                log.info("goodsExtend:{}", JSON.toJSONString(goodsExtend));
                goodsExtend.setGoodsId(newGoodsInfo.getGoodsId());
                insertGoodsExtend(goodsExtend);

                List<Product> products = JSONObject.parseArray(JSON.toJSONString(map.get("getProductInfo")), Product.class);
                log.info("products:{}", JSON.toJSONString(products));
                products.forEach(product -> {
                    product.setGoodsId(newGoodsInfo.getGoodsId());
                    product.setStoreId(newStoreId);
                    insertProduct(product);
                });

                List<GoodsBindAttributeValue> goodsBindAttributeValues = JSONObject.parseArray(JSON.toJSONString(map.get("getGoodsBindAttribute")), GoodsBindAttributeValue.class);
                log.info("goodsBindAttributeValues:{}", JSON.toJSONString(goodsBindAttributeValues));
                goodsBindAttributeValues.forEach(goodsBindAttributeValue -> {
                    goodsBindAttributeValue.setGoodsId(newStoreId);
                    insertGoodsBindAttribute(goodsBindAttributeValue);
                });

                List<GoodsBindLabel> goodsBindLabels = JSONObject.parseArray(JSON.toJSONString(map.get("getGoodsBindLabels")), GoodsBindLabel.class);
                log.info("goodsBindLabels:{}", JSON.toJSONString(goodsBindLabels));
                goodsBindLabels.forEach(goodsBindLabel -> {
                    goodsBindLabel.setGoodsId(newStoreId);
                    insertGoodsBindLabels(goodsBindLabel);
                });

                List<GoodsPicture> goodsPictures = JSONObject.parseArray(JSON.toJSONString(map.get("getGoodsPicture")), GoodsPicture.class);
                log.info("goodsPictures:{}", JSON.toJSONString(goodsPictures));
                goodsPictures.forEach(goodsPicture -> {
                    goodsPicture.setGoodsId(newGoodsInfo.getGoodsId());
                    goodsPicture.setStoreId(newStoreId);
                    insertGoodsPicture(goodsPicture);
                });

                List<StoreLabelBindGoods> storeLabelBindGoods = JSONObject.parseArray(JSON.toJSONString(map.get("getGoodsBindStoreInnerLabels")), StoreLabelBindGoods.class);
                log.info("storeLabelBindGoods:{}", JSON.toJSONString(storeLabelBindGoods));
                storeLabelBindGoods.forEach(storeLabelBindGoods1 -> {
                    storeLabelBindGoods1.setGoodsId(newGoodsInfo.getGoodsId());
                    storeLabelBindGoods1.setStoreId(newStoreId);
//                    insertGoodsBindStoreInnerLabels(storeLabelBindGoods1);
                });

                List<GoodsBindReserveName> goodsBindReserveNames = JSONObject.parseArray(JSON.toJSONString(map.get("getGoodsBindReserveName")), GoodsBindReserveName.class);
                log.info("goodsBindReserveNames:{}", JSON.toJSONString(goodsBindReserveNames));
                goodsBindReserveNames.forEach(goodsBindReserveName -> {
                    goodsBindReserveName.setGoodsId(newGoodsInfo.getGoodsId());
                    insertGoodsBindReserveName(goodsBindReserveName);
                });

                List<GoodsAnnex> goodsAnnexes = JSONObject.parseArray(JSON.toJSONString(map.get("getGoodsAnnex")), GoodsAnnex.class);
                log.info("goodsAnnexes:{}", JSON.toJSONString(goodsAnnexes));
                goodsAnnexes.forEach(goodsAnnex -> {
                    goodsAnnex.setGoodsId(newGoodsInfo.getGoodsId());
                    goodsAnnex.setStoreId(newStoreId);
                    insertGoodsAnnex(goodsAnnex);
                });

            });
        }

        return mapList;
    }

    public Goods getGoodsInfo(Long id) {
        return goodsModel.getGoodsByGoodsId(id);
    }

    public GoodsExtend getGoodsExtendInfo(Long id) {
        return goodsExtendModel.getGoodsExtendByGoodsId(id);
    }

    public List<Product> getProductInfo(Long goodsId) {
        ProductExample productExample = new ProductExample();
        productExample.setGoodsId(goodsId);
        return productModel.getProductList(productExample, null);
    }

    public List<GoodsBindAttributeValue> getGoodsBindAttribute(Long goodsId) {
        GoodsBindAttributeValueExample example = new GoodsBindAttributeValueExample();
        example.setGoodsId(goodsId);
        return goodsBindAttributeValueModel.getGoodsBindAttributeValueList(example, null);
    }

    public List<GoodsBindLabel> getGoodsBindLabels(Long goodsId) {
        GoodsBindLabelExample example = new GoodsBindLabelExample();
        example.setGoodsId(goodsId);
        return goodsBindLabelModel.getGoodsBindLabelList(example, null);
    }

    public List<GoodsPicture> getGoodsPicture(Long goodsId) {
        GoodsPictureExample example = new GoodsPictureExample();
        example.setGoodsId(goodsId);
        return goodsPictureModel.getGoodsPictureList(example, null);
    }

    public List<StoreLabelBindGoods> getGoodsBindStoreInnerLabels(Long goodsId) {
        StoreLabelBindGoodsExample example = new StoreLabelBindGoodsExample();
        example.setGoodsId(goodsId);
        return storeLabelBindGoodsModel.getStoreLabelBindGoodsList(example, null);
    }

    public List<GoodsBindReserveName> getGoodsBindReserveName(Long goodsId) {
        GoodsBindReserveNameExample example = new GoodsBindReserveNameExample();
        example.setGoodsId(goodsId);
        return goodsBindReserveNameModel.getGoodsBindReserveNameList(example, null);
    }

    public List<GoodsAnnex> goodsAnnexList(Long goodsId) {
        GoodsAnnexExample example = new GoodsAnnexExample();
        GoodsAnnexExample.Criteria criteria = example.createCriteria();
        criteria.andGoodsIdEqualTo(goodsId);
        criteria.andStatusEqualTo(NumConstant.ONE);
        return goodsAnnexReadMapper.selectByExample(example);
    }

    public Goods insertGoods(Goods goods) {
        long goodsId = GoodsIdGenerator.goodsIdGenerator();//商品id
        long defaultProductId = GoodsIdGenerator.productIdGenerator();//生成一个默认货品id
        goods.setGoodsId(goodsId);
        goods.setDefaultProductId(defaultProductId);
        goods.setState(GoodsConst.GOODS_STATE_WAREHOUSE_NO_AUDIT);
        goodsModel.saveGoods(goods);
        log.info("***** insertGoods goods:{} ******", goods);
        return goods;
    }

    public void insertGoodsExtend(GoodsExtend goodsExtend) {
        goodsExtendModel.saveGoodsExtend(goodsExtend);
    }

    public void insertProduct(Product product) {
        productModel.saveProduct(product);
    }

    public void insertGoodsBindAttribute(GoodsBindAttributeValue goodsBindAttributeValue) {
        goodsBindAttributeValueModel.saveGoodsBindAttributeValue(goodsBindAttributeValue);
    }

    public void insertGoodsBindLabels(GoodsBindLabel goodsBindLabel) {
        goodsBindLabelModel.saveGoodsBindLabel(goodsBindLabel);
    }

    public void insertGoodsPicture(GoodsPicture picture) {
        goodsPictureModel.saveGoodsPicture(picture);
    }

    public void insertGoodsBindStoreInnerLabels(StoreLabelBindGoods storeLabelBindGoods) {
        storeLabelBindGoodsWriteMapper.insert(storeLabelBindGoods);
    }

    public void insertGoodsBindReserveName(GoodsBindReserveName goodsBindReserveName) {
        goodsBindReserveNameWriteMapper.insert(goodsBindReserveName);
    }

    public void insertGoodsAnnex(GoodsAnnex goodsAnnex) {
        goodsAnnexWriterMapper.insert(goodsAnnex);
    }

    public void addStoreGoodsNum(Long newStoreId) {

    }

    /**
     * 处理商品状态
     *
     * @param sellNow 是否立即售卖，true==是，false==放入仓库
     * @return
     */
    private Integer dealGoodsState(Boolean sellNow) {
        //查询系统配置，是否需要审核，true==需要审核
        boolean needAudit = GoodsConst.GOODS_PUBLISH_NEED_AUDIT_YES.equals(stringRedisTemplate.opsForValue().get("goods_publish_need_audit"));
        if (sellNow) {
            //立即售卖
            return needAudit ? GoodsConst.GOODS_STATE_SELL_NOW_TO_AUDIT : GoodsConst.GOODS_STATE_UPPER;
        } else {
            //放入仓库
            return needAudit ? GoodsConst.GOODS_STATE_WAREHOUSE_TO_AUDIT : GoodsConst.GOODS_STATE_WAREHOUSE_NO_AUDIT;
        }
    }
}