package com.liquidnet.service.goblin.service.impl.manage;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.PageReadListener;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.dto.GoblinGoodsImportDto;
import com.liquidnet.service.goblin.dto.GoblinGoodsSpecDto;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSpecValueVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSpecVo;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.ObjectUtil;
import com.liquidnet.service.goblin.util.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;

@Slf4j
@Service
public class GoblinStoreMgtGoodsImportService {
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;
    @Autowired
    GoblinMongoUtils goblinMongoUtils;

    /**
     * 大小字母 || 数字
     * 长度：0,50
     */
    public static final String ALPHABET_NUMBER_UNDER_50 = "^[a-zA-Z0-9]{0,50}$";
    /**
     * 大小字母 || 数字
     * 长度：0,32
     */
    public static final String ALPHABET_NUMBER_32 = "^[a-zA-Z0-9]{0,32}$";

    public void goodsInformationDataAnalysisProcessing(MultipartFile file, String uid, String storeId) throws IOException {
        ArrayList<GoblinGoodsInfoVo> goodsInfoVos = ObjectUtil.goblinGoodsInfoVoArrayList();
        ArrayList<GoblinGoodsSkuInfoVo> goodsSkuInfoVos = ObjectUtil.getGoblinGoodsSkuInfoVoArrayList();
        LinkedList<Object[]> initGoodsSkuObjs = CollectionUtil.linkedListObjectArr();
        EasyExcel.read(file.getInputStream(), GoblinGoodsImportDto.class, new PageReadListener<GoblinGoodsImportDto>(dts -> {
            GoblinGoodsInfoVo lastGoodsInfoVo = null;
            LocalDateTime now = LocalDateTime.now();
            for (GoblinGoodsImportDto dt : dts) {
                log.debug("dt1:{}", dt.toString());
                if (StringUtils.isEmpty(dt.getSpuName()) || dt.getSpuName().length() > 100
                        || StringUtils.isEmpty(dt.getSkuSpec())
                        || null == dt.getPrice() || dt.getPrice().compareTo(BigDecimal.valueOf(0.01)) < 0 || dt.getPrice().compareTo(BigDecimal.valueOf(9999999)) > 0
                        || null == dt.getStock() || dt.getStock() < 0 || dt.getStock() > 9999999
                ) {// 数据不规范停止解析并提示用户
                    throw new LiquidnetServiceException("-1", "数据内容不规范【请核实必填项信息】");
                }

                boolean tobeNextSpuFlg = false;
                if (null == lastGoodsInfoVo || !lastGoodsInfoVo.getName().equals(dt.getSpuName())) {
                    lastGoodsInfoVo = GoblinGoodsInfoVo.getNew();
                    tobeNextSpuFlg = true;
                }

                if (tobeNextSpuFlg) {
                    lastGoodsInfoVo.setName(dt.getSpuName());//*
                    if (StringUtils.isNotEmpty(dt.getSpuCode())) {
                        if (Pattern.matches(ALPHABET_NUMBER_UNDER_50, dt.getSpuCode())) throw new LiquidnetServiceException("-1", "数据内容不规范【商品编码格式错误】");
                        lastGoodsInfoVo.setSpuId(IDGenerator.nextMilliId2() + dt.getSpuCode());//*
                    } else {
                        lastGoodsInfoVo.setSpuId(IDGenerator.nextMilliId2());//*
                    }
//                    if (StringUtils.isNotEmpty(dt.getSpuBarCode())) {
//                        lastGoodsInfoVo.setSpuNo(dt.getSpuBarCode());//*
//                    } else {
                        lastGoodsInfoVo.setSpuNo(lastGoodsInfoVo.getSpuId());//*
//                    }
                    if (StringUtils.isNotEmpty(dt.getSpuImgs())) {
                        if (!dt.getSkuImg().startsWith("【图片链接】")) throw new LiquidnetServiceException("-1", "数据内容不规范【商品图片格式错误】");
                        String[] spuImgsArr = dt.getSpuImgs().replace("【图片链接】", "").replace(";", "；").split("；");
                        if (spuImgsArr.length > 15) throw new LiquidnetServiceException("-1", "数据内容不规范【商品图片最多支持15张】");
                        List<String> imageList = Arrays.asList(spuImgsArr);
                        lastGoodsInfoVo.setImageList(imageList);
                        lastGoodsInfoVo.setCoverPic(imageList.get(0));
                    }

                    lastGoodsInfoVo.setSpuType(0);//*
                    lastGoodsInfoVo.setSpecMode("1");//*
                    lastGoodsInfoVo.setShelvesHandle("1");
                    lastGoodsInfoVo.setVirtualFlg("0");
                    lastGoodsInfoVo.setStatus("3");
                    lastGoodsInfoVo.setShelvesStatus("0");
                    lastGoodsInfoVo.setSpuAppear("0");//*
                    lastGoodsInfoVo.setSpuCanbuy("1");
                    lastGoodsInfoVo.setDelFlg("0");
                    lastGoodsInfoVo.setCreatedAt(now);
                    lastGoodsInfoVo.setCreatedBy(uid);//*
                    lastGoodsInfoVo.setStoreId(storeId);//*

                    this.goodsInformationDataAnalysisProcessingForSku(dt, lastGoodsInfoVo, uid, storeId, now, true, goodsSkuInfoVos, initGoodsSkuObjs);

                    goodsInfoVos.add(lastGoodsInfoVo);
                } else {
                    this.goodsInformationDataAnalysisProcessingForSku(dt, lastGoodsInfoVo, uid, storeId, now, false, goodsSkuInfoVos, initGoodsSkuObjs);
                }
                log.debug("dt2:{}", lastGoodsInfoVo);
            }
            log.debug("dt3-1:{}", JsonUtils.toJson(goodsInfoVos));
            log.debug("dt3-2:{}", JsonUtils.toJson(goodsSkuInfoVos));

            goblinMongoUtils.insertMgtGoodsInfoVos(goodsInfoVos);
            goblinMongoUtils.insertMgtGoodsSkuInfoVos(goodsSkuInfoVos);
            goodsSkuInfoVos.forEach(r -> goblinRedisUtils.setSkuStock(null, r.getSkuId(), r.getSkuStock()));

            LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
            toMqSqls.add(SqlMapping.get("goblin_goods.insert"));
            LinkedList<Object[]> initGoodsObjs = CollectionUtil.linkedListObjectArr();
            goodsInfoVos.forEach(r -> initGoodsObjs.add(new Object[]{
                    r.getSpuId(), r.getSpuNo(), r.getName(), r.getSubtitle(), r.getSellPrice(),
                    r.getPriceGe(), r.getPriceLe(), r.getIntro(), r.getDetails(), r.getCoverPic(),
                    r.getVideo(), r.getSpecMode(), r.getStoreId(), r.getCateFid(), r.getCateSid(),
                    r.getCateTid(), r.getStoreCateFid(), r.getStoreCateSid(), r.getStoreCateTid(), r.getBrandId(),
                    r.getShelvesHandle(), r.getShelvesTime(), r.getSpuValidity(), r.getVirtualFlg(), r.getStatus(),
                    r.getShelvesStatus(), r.getSpuAppear(), r.getShelvesAt(), r.getCreatedBy(), r.getCreatedAt(),
                    r.getLogisticsTemplate()
            }));
            toMqSqls.add(SqlMapping.get("goblin_goods_sku.insert"));
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_GOODS.getKey(), SqlMapping.gets(toMqSqls, initGoodsObjs, initGoodsSkuObjs));
        }) {
            @Override
            public void invoke(GoblinGoodsImportDto data, AnalysisContext context) {
                Integer approximateTotalRowNumber = context.readSheetHolder().getApproximateTotalRowNumber();
                if (approximateTotalRowNumber > 501) {
                    log.error("店铺商品管理:批量导入数据:异常[UID={},storeId={},totalRowNumber={}]", uid, storeId, approximateTotalRowNumber);
                    throw new LiquidnetServiceException("-1", "超出总行数限制500");
                }
                super.invoke(data, context);
            }
        }).sheet().doReadSync();
    }

    private void goodsInformationDataAnalysisProcessingForSku(GoblinGoodsImportDto dt, GoblinGoodsInfoVo lastGoodsInfoVo,
                                                              String uid, String storeId, LocalDateTime now, boolean hasNextSpuFlg,
                                                              List<GoblinGoodsSkuInfoVo> goodsSkuInfoVos, LinkedList<Object[]> initGoodsSkuObjs) {
        GoblinGoodsSkuInfoVo skuInfoVo = GoblinGoodsSkuInfoVo.getNew();

        skuInfoVo.setName("");
        String[] skuSpecArr = dt.getSkuSpec().replace(":", "：").replace(";", "；").split("；");
        List<GoblinGoodsSpecVo> spuSpecVos = hasNextSpuFlg ? ObjectUtil.getGoblinGoodsSpecVoArrayList() : lastGoodsInfoVo.getSpecVoList();
        List<GoblinGoodsSpecDto> skuSpecDtos = ObjectUtil.getGoblinGoodsSpecDtoArrayList();
        for (int i = 0, size = skuSpecArr.length; i < size; i++) {
            String skuSpec = skuSpecArr[i];
            if (StringUtils.isEmpty(skuSpec)) {// 数据不规范停止解析并提示用户
                throw new LiquidnetServiceException("-1", "数据内容不规范【请核实商品规格信息】");
            }
            String[] specArr = skuSpec.split("：");
            if (ArrayUtils.isEmpty(specArr) || specArr.length != 2
                    || specArr[0].length() > 5 || specArr[1].length() > 40
            ) {// 数据不规范停止解析并提示用户
                throw new LiquidnetServiceException("-1", "数据内容不规范【请核实商品规格信息】");
            }

            GoblinGoodsSpecDto skuSpecDto = GoblinGoodsSpecDto.getNew();
            skuSpecDto.setSpecName(specArr[0]);
            skuSpecDto.setSpecVname(specArr[1]);
            skuSpecDtos.add(skuSpecDto);

            skuInfoVo.setName(skuInfoVo.getName().concat(skuSpecDto.getSpecVname()));

            if (hasNextSpuFlg) {
                List<GoblinGoodsSpecValueVo> spuSpecValueVos = ObjectUtil.getGoblinGoodsSpecValueVoArrayList();
                spuSpecValueVos.add(GoblinGoodsSpecValueVo.getNew().setSpecVname(skuSpecDto.getSpecVname()).setSpecVsort(1));
                GoblinGoodsSpecVo spuSpecVo = GoblinGoodsSpecVo.getNew().setSpecName(skuSpecDto.getSpecName()).setSpecSort(i + 1).setSpecValues(spuSpecValueVos);
                spuSpecVos.add(spuSpecVo);
            } else {
                Optional<GoblinGoodsSpecVo> hasSpecOptional = spuSpecVos.stream().filter(r -> r.getSpecName().equals(skuSpecDto.getSpecName())).findAny();
                if (hasSpecOptional.isPresent()) {
                    GoblinGoodsSpecVo spuSpecVo = hasSpecOptional.get();

                    List<GoblinGoodsSpecValueVo> spuSpecValueVos = spuSpecVo.getSpecValues();
                    Optional<GoblinGoodsSpecValueVo> any = spuSpecValueVos.stream().filter(r -> r.getSpecVname().equals(skuSpecDto.getSpecVname())).findAny();
                    if (!any.isPresent()) {
                        spuSpecValueVos.add(
                                GoblinGoodsSpecValueVo.getNew().setSpecVname(skuSpecDto.getSpecVname()).setSpecVsort(lastGoodsInfoVo.getSkuIdList().size() + 1)
                        );
                        spuSpecVo.setSpecValues(spuSpecValueVos);
                    }
                } else {// 不匹配的规格直接跳过（默认只匹配商品第一行数据中的规格项）
                    return;
                }
            }
        }

        skuInfoVo.setStock(dt.getStock());//*
        skuInfoVo.setSkuStock(dt.getStock());//*
        skuInfoVo.setPrice(dt.getPrice());//*
        skuInfoVo.setPriceMember(dt.getPrice());//*
        if (StringUtils.isNotEmpty(dt.getSkuCode())) {
            if (Pattern.matches(ALPHABET_NUMBER_UNDER_50, dt.getSkuCode())) throw new LiquidnetServiceException("-1", "数据内容不规范【规格编码格式错误】");
            skuInfoVo.setSkuId(lastGoodsInfoVo.getSpuId().concat(dt.getSkuCode()).concat(StringUtils.right(String.valueOf(System.nanoTime()), 5)));//*
        } else {
            skuInfoVo.setSkuId(lastGoodsInfoVo.getSpuId().concat(StringUtils.right(String.valueOf(System.nanoTime()), 5)));//*
        }
        if (StringUtils.isNotEmpty(dt.getSkuImg())) {
            if (!dt.getSkuImg().startsWith("【图片链接】")) throw new LiquidnetServiceException("-1", "数据内容不规范【规格图片格式错误】");
            String[] skuImgArr = dt.getSkuImg().replace("【图片链接】", "").replace(";", "；").split("；");
            if (skuImgArr.length > 1) throw new LiquidnetServiceException("-1", "数据内容不规范【规格图片仅支持1张】");
            skuInfoVo.setSkuPic(skuImgArr[0]);
        }
        if (StringUtils.isNotEmpty(dt.getSkuBarCode())) {
            if (Pattern.matches(ALPHABET_NUMBER_32, dt.getSkuCode())) throw new LiquidnetServiceException("-1", "数据内容不规范【规格条码格式错误】");
            skuInfoVo.setSkuNo(dt.getSkuBarCode());//*
        } else {
            skuInfoVo.setSkuNo(lastGoodsInfoVo.getSpuNo());//*
        }

        skuInfoVo.setSpuId(lastGoodsInfoVo.getSpuId());//*
        skuInfoVo.setSkuType(0);//*
        skuInfoVo.setBuyFactor("0");
        skuInfoVo.setBuyLimit(0);
        skuInfoVo.setStatus("3");
        skuInfoVo.setShelvesStatus(lastGoodsInfoVo.getShelvesStatus());
        skuInfoVo.setSoldoutStatus("0");//*
        skuInfoVo.setSkuAppear("0");//*
        skuInfoVo.setSkuCanbuy("1");
        skuInfoVo.setDelFlg("0");
        skuInfoVo.setCreatedAt(now);//*
        skuInfoVo.setCreatedBy(uid);//*
        skuInfoVo.setStoreId(storeId);
        skuInfoVo.setSkuSpecList(skuSpecDtos);

        goodsSkuInfoVos.add(skuInfoVo);
        initGoodsSkuObjs.add(new Object[]{
                skuInfoVo.getSkuId(), skuInfoVo.getSpuId(), skuInfoVo.getSkuNo(), skuInfoVo.getName(), skuInfoVo.getSubtitle(),
                skuInfoVo.getSellPrice(), skuInfoVo.getSkuPic(), skuInfoVo.getSkuIsbn(), skuInfoVo.getStock(), skuInfoVo.getSkuStock(),
                skuInfoVo.getWarningStock(), skuInfoVo.getPrice(), skuInfoVo.getPriceMember(), skuInfoVo.getWeight(), skuInfoVo.getBuyFactor(),
                skuInfoVo.getBuyRoster(), skuInfoVo.getBuyLimit(), skuInfoVo.getStoreId(), skuInfoVo.getSkuValidity(), skuInfoVo.getVirtualFlg(),
                skuInfoVo.getStatus(), skuInfoVo.getShelvesStatus(), skuInfoVo.getSkuAppear(), skuInfoVo.getShelvesAt(), uid,
                now, skuInfoVo.getLogisticsTemplate()
        });

        if (hasNextSpuFlg) {
            List<String> skuIdList = CollectionUtil.arrayListString();
            skuIdList.add(skuInfoVo.getSkuId());
            lastGoodsInfoVo.setSkuIdList(skuIdList);
            lastGoodsInfoVo.setSpecVoList(spuSpecVos);
            lastGoodsInfoVo.setPriceGe(skuInfoVo.getPrice());
            lastGoodsInfoVo.setPriceLe(skuInfoVo.getPrice());
        } else {
            BigDecimal priceGe = lastGoodsInfoVo.getPriceGe();
            BigDecimal priceLe = lastGoodsInfoVo.getPriceLe();
            List<String> skuIdList = lastGoodsInfoVo.getSkuIdList();

            skuIdList.add(skuInfoVo.getSkuId());

            lastGoodsInfoVo.setSkuIdList(skuIdList);
            lastGoodsInfoVo.setSpecVoList(spuSpecVos);
            lastGoodsInfoVo.setPriceGe(skuInfoVo.getPrice().compareTo(priceGe) < 0 ? skuInfoVo.getPrice() : priceGe);
            lastGoodsInfoVo.setPriceLe(priceLe.compareTo(skuInfoVo.getPrice()) < 0 ? skuInfoVo.getPrice() : priceLe);
        }
    }
}
