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

import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ErrorMapping;
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 io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@ApiModel(value = "GoblinStoreMgtGoodsAddParam", description = "商品管理:添加商品入参")
@Data
public class GoblinStoreMgtGoodsAddParam implements Serializable {
    private static final long serialVersionUID = -5101611616626164702L;
    @ApiModelProperty(position = 10, required = true, value = "店铺ID")
    @NotNull(message = "店铺ID不能为空")
    private String storeId;
    @ApiModelProperty(position = 11, required = false, value = "商品ID[编辑时必传]")
    private String spuId;

    /**
     * ---------------------------- 基本信息 ----------------------------
     **/

    @ApiModelProperty(position = 12, required = true, value = "商品名称[128]")
    private String name;
    @ApiModelProperty(position = 13, required = false, value = "商品名称[128]")
    private String subtitle;
    @ApiModelProperty(position = 14, required = false, value = "商品销售价-原价[20,2]")
    private BigDecimal sellPrice;

    @ApiModelProperty(position = 15, required = true, value = "商品一级分类ID[30]")
    private String cateFid;
    @ApiModelProperty(position = 16, required = true, value = "商品二级分类ID[30]")
    private String cateSid;
    @ApiModelProperty(position = 17, required = true, value = "商品三级分类ID[30]")
    private String cateTid;

    @ApiModelProperty(position = 18, required = false, value = "商品简介[256]", example = "商品简介...")
    private String intro;

    @ApiModelProperty(position = 19, required = false, value = "商品标签列表")
    private List<String> tagList;
    @ApiModelProperty(position = 20, required = true, value = "商品图片列表")
    private List<String> imageList;
    @ApiModelProperty(position = 21, required = false, value = "商品视频地址")
    private String coverPic;
    @ApiModelProperty(position = 22, required = false, value = "商品视频地址")
    private String video;

    /**
     * ---------------------------- 价格库存 ----------------------------
     **/

    @ApiModelProperty(position = 23, required = true, value = "规格展现方式[1-常规|2-组合]", allowableValues = "1,2", example = "1")
    private String specMode;
    @ApiModelProperty(position = 24, required = false, value = "SKU规格信息[初次添加商品必填]")
//    @NotNull(message = "SKU规格信息不能为空")
    @Valid
    private List<GoblinStoreMgtGoodsAddSkuParam> skuParamList;
    @ApiModelProperty(position = 25, required = true, value = "物流模版", example = "松鼠德邦")
    private String logisticsTemplate;
    @ApiModelProperty(position = 26, required = false, value = "商品编码[默认为系统编码，也可手动输入商家自己的编码]")
    private String spuNo;

    /**
     * ---------------------------- 商品介绍 ----------------------------
     **/

    @ApiModelProperty(position = 27, required = true, value = "商品详情", example = "商品详情...")
    private String details;

    /**
     * ---------------------------- 销售属性 ----------------------------
     **/

    @ApiModelProperty(position = 28, required = true, value = "上架处理方式[1-等待手动上架|2-直接上架售卖|3-预约定时上架]", example = "1")
    private String shelvesHandle;
    @ApiModelProperty(position = 29, required = false, value = "预约上架时间[上架处理方式为3-预约定时上架时需要指定]")
    @Pattern(regexp = LnsRegex.Valid.DATETIME_FULL, message = "预约上架时间格式有误")
    private String shelvesTime;
    @ApiModelProperty(position = 30, required = false, value = "商品有效期[YYYY-MM-DD]")
    @Pattern(regexp = LnsRegex.Valid.DATETIME_YMD, message = "商品有效期格式有误")
    private String spuValidity;
    @ApiModelProperty(position = 31, required = true, value = "是否虚拟商品[0-否|1-是]", allowableValues = "0,1", example = "0")
    @Pattern(regexp = "\\b(0|1)\\b", message = "是否虚拟商品参数无效")
    private String virtualFlg;

    /**
     * ---------------------------- 服务保障 ----------------------------
     **/

    @ApiModelProperty(position = 32, required = false, value = "商品服务支持ID列表")
    private List<String> ssidList;

    /**
     * ---------------------------- 专属标签 ----------------------------
     **/

    @ApiModelProperty(position = 33, required = true, value = "商品关联音乐人、艺术家、IP列表")
    private List<String> extagList;


    /**
     * 生成SPU
     *
     * @return GoblinGoodsInfoVo
     */
    public GoblinGoodsInfoVo initGoodsInfoVo() {
        GoblinGoodsInfoVo vo = GoblinGoodsInfoVo.getNew();
        vo.setStoreId(this.getStoreId());
        if (StringUtils.isBlank(this.getSpuId())) {
            vo.setSpuId(IDGenerator.nextMilliId2());
        } else {
            vo.setSpuId(this.getSpuId());
        }
        if (StringUtils.isBlank(this.getSpuNo())) {
            vo.setSpuNo(vo.getSpuId());
        } else {
            vo.setSpuNo(this.getSpuNo());
        }
        vo.setName(this.getName());
        vo.setSubtitle(this.getSubtitle());
        vo.setSellPrice(this.getSellPrice());
//        vo.setPriceGe(BigDecimal.ZERO);
//        vo.setPriceLe(BigDecimal.ZERO);
        vo.setIntro(this.getIntro());
        vo.setDetails(this.getDetails());
        vo.setCoverPic(this.getCoverPic());
        vo.setVideo(this.getVideo());
        vo.setSpecMode(this.getSpecMode());
        vo.setCateFid(this.getCateFid());
        vo.setCateSid(this.getCateSid());
        vo.setCateTid(this.getCateTid());
//        vo.setStoreCateFid(null);
//        vo.setStoreCateSid(null);
//        vo.setStoreCateTid(null);
//        vo.setBrandId(null);
        vo.setShelvesHandle(this.getShelvesHandle());
        vo.setShelvesTime(this.getShelvesTime());
        vo.setSpuValidity(this.getSpuValidity());
        vo.setVirtualFlg(this.getVirtualFlg());
        vo.setStatus("1");
//        vo.setReason(null);
        vo.setShelvesStatus("0");
        vo.setSpuAppear("0");
        vo.setDelFlg("0");
//        vo.setShelvesAt(null);
        vo.setImageList(this.getImageList());
        vo.setLogisticsTemplate(this.getLogisticsTemplate());
//        vo.setCreatedBy();
//        vo.setCreatedAt();
//        vo.setUpdatedBy();
//        vo.setUpdatedAt();
//        vo.setSpecVoList();
//        vo.setTagVoList();
//        vo.setServiceSupportVoList();
//        vo.setExtagVoList();
        return vo;
    }

    /**
     * 编辑SPU参数整理
     *
     * @return GoblinGoodsInfoVo
     */
    public GoblinGoodsInfoVo initEditGoodsInfoVo() {
        GoblinGoodsInfoVo vo = GoblinGoodsInfoVo.getNew();
        vo.setStoreId(this.getStoreId());
        vo.setSpuId(this.getSpuId());
        vo.setSpuNo(this.getSpuNo());
        vo.setName(this.getName());
        vo.setSubtitle(this.getSubtitle());
        vo.setSellPrice(this.getSellPrice());
        vo.setIntro(this.getIntro());
        vo.setDetails(this.getDetails());
        vo.setCoverPic(this.getCoverPic());
        vo.setVideo(this.getVideo());
        vo.setSpecMode(this.getSpecMode());
        vo.setCateFid(this.getCateFid());
        vo.setCateSid(this.getCateSid());
        vo.setCateTid(this.getCateTid());
        vo.setShelvesHandle(this.getShelvesHandle());
        vo.setShelvesTime(this.getShelvesTime());
        vo.setSpuValidity(this.getSpuValidity());
        vo.setVirtualFlg(this.getVirtualFlg());
        vo.setImageList(this.getImageList());
        vo.setLogisticsTemplate(this.getLogisticsTemplate());
        return vo;
    }

    /**
     * 生成SKU列表以及SPU规格等信息
     *
     * @param goodsInfoVo  GoblinGoodsInfoVo
     * @param vos          List<GoblinGoodsSkuInfoVo>
     * @param goodsSpecVos List<GoblinGoodsSpecVo>
     */
    public void initGoodsSkuInfoVo(GoblinGoodsInfoVo goodsInfoVo, List<GoblinGoodsSkuInfoVo> vos,
                                   List<GoblinGoodsSpecVo> goodsSpecVos) {
        List<GoblinStoreMgtGoodsAddSkuParam> mgtGoodsAddSkuParamList = this.getSkuParamList();
        if (CollectionUtils.isEmpty(mgtGoodsAddSkuParamList)) {
            ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("149006");
            throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
        }

        List<String> skuIdList = CollectionUtil.arrayListString();
        BigDecimal priceGe = BigDecimal.ZERO, priceLe = BigDecimal.ZERO;
        int size = mgtGoodsAddSkuParamList.size(), skuSpecSize = 0;
        for (int i = 0; i < size; i++) {
            GoblinStoreMgtGoodsAddSkuParam addSkuParam = mgtGoodsAddSkuParamList.get(i);
            String skuId = addSkuParam.getSkuId();

            GoblinGoodsSkuInfoVo vo = GoblinGoodsSkuInfoVo.getNew();
            if (StringUtils.isBlank(skuId)) {
                vo.setSkuId(goodsInfoVo.getSpuId().concat(StringUtils.right(String.valueOf(System.nanoTime()), 5)));
            } else {
                vo.setSkuId(skuId);
            }
            vo.setSpuId(goodsInfoVo.getSpuId());
            vo.setSkuNo(goodsInfoVo.getSpuNo());
            vo.setName(goodsInfoVo.getName());
            vo.setSubtitle(goodsInfoVo.getSubtitle());
            vo.setSkuPic(addSkuParam.getSkuPic());
            vo.setSkuIsbn(addSkuParam.getSkuIsbn());
            vo.setStock(addSkuParam.getStock());
            vo.setSkuStock(vo.getStock());
            vo.setWarningStock(addSkuParam.getWarningStock());
            vo.setSellPrice(addSkuParam.getSellPrice());
            vo.setPrice(addSkuParam.getPrice());
            vo.setPriceMember(addSkuParam.getPriceMember());
            vo.setWeight(addSkuParam.getWeight());
            vo.setBuyFactor(addSkuParam.getBuyFactor());
            vo.setBuyRoster(addSkuParam.getBuyRoster());
            vo.setBuyLimit(addSkuParam.getBuyLimit());
            vo.setStoreId(goodsInfoVo.getStoreId());
            vo.setSkuValidity(DateUtil.Formatter.yyyyMMddHHmmss.parse(addSkuParam.getSkuValidity()));
            vo.setVirtualFlg(goodsInfoVo.getVirtualFlg());
            vo.setStatus("3");// 没有审核流程，默认通过
//            vo.setReason();
            vo.setShelvesStatus("0");
            vo.setSkuAppear(StringUtils.isBlank(addSkuParam.getSkuAppear()) ? "0" : addSkuParam.getSkuAppear());
            vo.setDelFlg("0");
//            vo.setShelvesAt();
            vo.setCreatedBy(goodsInfoVo.getCreatedBy());
            vo.setCreatedAt(goodsInfoVo.getCreatedAt());
//            vo.setUpdatedBy();
//            vo.setUpdatedAt();
            vo.setLogisticsTemplate(goodsInfoVo.getLogisticsTemplate());

            List<GoblinGoodsSpecDto> skuSpecList = addSkuParam.getSkuSpecList();
            vo.setSkuSpecList(skuSpecList);

            for (GoblinGoodsSkuInfoVo goodsSkuInfoVo : vos) {// 规格比对
                Map<String, String> skuSpecMap = goodsSkuInfoVo.getSkuSpecList().stream()
                        .collect(Collectors.toMap(GoblinGoodsSpecDto::getSpecName, GoblinGoodsSpecDto::getSpecVname, (k1, k2) -> k2));
                boolean diffSpecFlg = false;
                for (GoblinGoodsSpecDto goodsSpecDto : skuSpecList) {
                    String specName = goodsSpecDto.getSpecName();
                    if (!skuSpecMap.get(specName).equals(goodsSpecDto.getSpecVname())) {
                        diffSpecFlg = true;// 多个规格中只要存在一个不一致，即可跳过，标记为允许添加
                        break;
                    }
                }
                if (!diffSpecFlg) {// 重复的规格信息
                    ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("149006");
                    throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
                }
            }
            vos.add(vo);

            skuIdList.add(vo.getSkuId());
            priceGe = priceGe.compareTo(vo.getPrice()) > 0 ? vo.getPrice() : priceGe;
            priceLe = priceLe.compareTo(vo.getPrice()) < 0 ? vo.getPrice() : priceLe;

            if (CollectionUtils.isEmpty(skuSpecList) || (skuSpecSize > 0 && skuSpecSize != skuSpecList.size())) {
                ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("149006");
                throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
            }
            int specSize = skuSpecList.size();// SKU包含的规格数量
            skuSpecSize = i == 0 ? specSize : skuSpecSize;// 标记第一个SKU的规格数量，用于校验
            List<String> skuSpecNListTmp = CollectionUtil.arrayListString();// 标记单个SKU的规格名称，用于校验
            for (int j = 0; j < specSize; j++) {
                GoblinGoodsSpecDto specDto = skuSpecList.get(j);
                String specName = specDto.getSpecName();
                String specVname = specDto.getSpecVname();

                GoblinGoodsSpecValueVo specValueVo = GoblinGoodsSpecValueVo.getNew().setSpecVname(specVname).setSpecVsort(i);
                if (i == 0) {
                    if (goodsSpecVos.stream().anyMatch(r -> r.getSpecName().equals(specName))) {// 单SKU重复的规格
                        ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("149006");
                        throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
                    }
                    ArrayList<GoblinGoodsSpecValueVo> specValueVos = new ArrayList<>();
                    specValueVos.add(specValueVo);
                    goodsSpecVos.add(GoblinGoodsSpecVo.getNew().setSpecName(specName).setSpecSort(j).setSpecValues(specValueVos));
                } else {
                    Optional<GoblinGoodsSpecVo> filterGoodsSpecOptional = goodsSpecVos.stream().filter(r -> r.getSpecName().equals(specName)).findAny();
                    if (filterGoodsSpecOptional.isPresent()) {// 存在该规格
                        if (filterGoodsSpecOptional.get().getSpecValues().stream().noneMatch(r -> r.getSpecVname().equals(specVname))) {
                            // 且不包含该规格值，则补充规格对应的值
                            filterGoodsSpecOptional.get().getSpecValues().add(specValueVo);
                        }
                    } else {// 不存在该规格，则不同SKU规格不一致
                        ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("149006");
                        throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
                    }
                }
                if (!skuSpecNListTmp.isEmpty() && skuSpecNListTmp.contains(specName)) {// 单SKU重复的规格
                    ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("149006");
                    throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
                }
                skuSpecNListTmp.add(specName);
            }
        }
        goodsInfoVo.setPriceGe(priceGe);
        goodsInfoVo.setPriceLe(priceLe);
        goodsInfoVo.setSpecVoList(goodsSpecVos);
        goodsInfoVo.setSkuIdList(skuIdList);
    }
}
