
package com.tmerclub.cloud.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.SerializeUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.i18n.LanguageEnum;
import com.tmerclub.cloud.common.product.constant.AttrType;
import com.tmerclub.cloud.common.product.constant.SupplierSpuType;
import com.tmerclub.cloud.common.product.dto.SpuAttrValueDTO;
import com.tmerclub.cloud.common.product.vo.*;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.product.mapper.AttrMapper;
import com.tmerclub.cloud.product.mapper.SpuAttrValueMapper;
import com.tmerclub.cloud.product.mapper.SpuMapper;
import com.tmerclub.cloud.product.model.SpuAttrValue;
import com.tmerclub.cloud.product.service.SpuAttrValueService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品规格属性关联信息
 *
 * @author tmerclub
 * @date 2020-10-28 15:27:24
 */
@Service
public class SpuAttrValueServiceImpl implements SpuAttrValueService {

    @Autowired
    private SpuAttrValueMapper spuAttrValueMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private AttrMapper attrMapper;

    @Override
    public void save(Long spuId, Long categoryId, List<SpuAttrValueDTO> spuAttrValueDTOList, Integer sysType) {
        List<SpuAttrValue> spuAttrValueList = setSpuAttrValueInfo(spuId, categoryId, spuAttrValueDTOList, sysType);
        if (CollUtil.isEmpty(spuAttrValueList)) {
            return;
        }
        spuAttrValueMapper.batchSave(spuAttrValueList);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSpuByAttrValueIds(List<SpuAttrValue> attrValueList, Set<Long> attrValueIds) {
        if (CollUtil.isEmpty(attrValueIds)) {
            return;
        }
        List<Long> spuIds = spuAttrValueMapper.spuIdListByAttrValueIds(attrValueIds);
        // 更新商品基本属性
        if (CollUtil.isNotEmpty(attrValueList)) {
            spuAttrValueMapper.batchUpdateSpuAttrValue(attrValueList);
        }
        if (CollUtil.isNotEmpty(spuIds)) {
            spuMapper.updateSpuUpdateTime(spuIds, null, null, null);
        }
    }


    @Override
    public void update(Long spuId, Long categoryId, Integer supplierSpuType, List<SpuAttrValueDTO> spuAttrValues) {
        List<SpuAttrValueVO> dbSpuAttrValues = getSpuAttrsBySpuId(spuId);
        if (CollUtil.isEmpty(dbSpuAttrValues) && CollUtil.isEmpty(spuAttrValues)) {
            return;
        }
        // 预防空指针
        if (Objects.isNull(spuAttrValues)) {
            spuAttrValues = new ArrayList<>(Constant.INITIAL_CAPACITY);
        } else if (Objects.isNull(dbSpuAttrValues)) {
            dbSpuAttrValues = new ArrayList<>(0);
        }
        // 根据key(attrId:attrValueId) 来筛选数据
        Map<String, SpuAttrValueVO> dbSpuAttrValueMap = dbSpuAttrValues.stream()
                .collect(Collectors.toMap(spuAttrValueVO -> spuAttrValueVO.getAttrId() + Constant.COLON + spuAttrValueVO.getAttrValueId(), attr -> attr));
        Map<String, SpuAttrValueDTO> spuAttrValueMap = spuAttrValues.stream()
                .collect(Collectors.toMap(spuAttrValueDTO -> spuAttrValueDTO.getAttrId() + Constant.COLON + spuAttrValueDTO.getAttrValueId(), attr -> attr));
        List<SpuAttrValueDTO> saveList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<SpuAttrValueDTO> updateList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        // 分别筛选出新增、更新的数据
        for (String key : spuAttrValueMap.keySet()) {
            SpuAttrValueDTO spuAttrValueDTO = spuAttrValueMap.get(key);
            // 新数据-保存
            if (!dbSpuAttrValueMap.containsKey(key)) {
                saveList.add(spuAttrValueMap.get(key));
                continue;
            }
            // 已有数据且属性值不为空-更新
            if (dbSpuAttrValueMap.containsKey(key) && StrUtil.isNotBlank(spuAttrValueDTO.getAttrValueName())) {
                updateList.add(spuAttrValueMap.get(key));
                dbSpuAttrValueMap.remove(key);
            }
        }
        // 删除商品属性
        List<Long> deleteAttrIds;
        if (MapUtil.isNotEmpty(dbSpuAttrValueMap)) {
            deleteAttrIds = dbSpuAttrValueMap.values().stream().map(SpuAttrValueVO::getAttrId).collect(Collectors.toList());
            spuAttrValueMapper.deleteBatchBySpuIdAndAttrIds(spuId, deleteAttrIds);
        }
        // 保存商品属性
        List<SpuAttrValue> spuAttrValueList = setSpuAttrValueInfo(spuId, categoryId, saveList, null);
        if (CollUtil.isNotEmpty(spuAttrValueList)) {
            spuAttrValueMapper.batchSave(spuAttrValueList);
        }
        // 更新商品属性
        List<SpuAttrValue> updateSpuAttrValueLis = new ArrayList<>(Constant.INITIAL_CAPACITY);
        if (CollUtil.isNotEmpty(updateList)) {
            updateSpuAttrValueLis = setSpuAttrValueInfo(spuId, categoryId, updateList, null);
            spuAttrValueMapper.batchUpdate(updateSpuAttrValueLis);
        }
        if (Objects.equals(supplierSpuType, SupplierSpuType.YES.value())) {
            // 同步更新代销商品的商品属性
            List<SpuAttrValue> attrValueList = new ArrayList<>(Constant.INITIAL_CAPACITY);
            List<Long> supIdListBySupplierId = spuMapper.getSupIdListBySupplierId(spuId);
            for (Long aLong : supIdListBySupplierId) {
                spuAttrValueMapper.deleteBySpuId(aLong);
                for (SpuAttrValue spuAttrValue : spuAttrValueList) {
                    spuAttrValue.setSpuId(aLong);
                    attrValueList.add(SerializeUtil.clone(spuAttrValue));
                    spuAttrValue.setSpuId(aLong);
                }
                for (SpuAttrValue spuAttrValue : updateSpuAttrValueLis) {
                    spuAttrValue.setSpuId(aLong);
                    attrValueList.add(SerializeUtil.clone(spuAttrValue));
                }

            }
            // 保存属性
            if (CollUtil.isNotEmpty(attrValueList)) {
                spuAttrValueMapper.batchSave(attrValueList);
            }
        }
    }


    @Override
    public void deleteBySpuId(Long spuId) {
        spuAttrValueMapper.deleteBySpuId(spuId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUnionDataByAttId(Long attrId, List<Long> attrValueIds) {
        if (CollUtil.isEmpty(attrValueIds)) {
            return;
        }
        List<Long> spuIds = spuAttrValueMapper.spuIdListByAttrValueIds(attrValueIds);
        spuAttrValueMapper.deleteByAttId(attrId, attrValueIds);
        if (CollUtil.isNotEmpty(spuIds)) {
            spuMapper.updateSpuUpdateTime(spuIds, null, null, null);
        }
    }

    @Override
    public void deleteByCategoryIds(Long attrId, List<Long> categoryIds) {
        if (CollUtil.isEmpty(categoryIds)) {
            return;
        }
        spuAttrValueMapper.deleteByCategoryIds(attrId, categoryIds);
        if (CollUtil.isNotEmpty(categoryIds)) {
            spuMapper.updateSpuUpdateTime(null, categoryIds, null, null);
        }
    }

    @Override
    public List<SpuAttrValueVO> getSpuAttrsBySpuId(Long spuId) {
        return spuAttrValueMapper.getSpuAttrsBySpuId(spuId);
    }

    /**
     * 为商品属性插入国际化信息
     *
     * @param spuId         商品id
     * @param categoryId    分类id（用于获取完整的属性信息）
     * @param spuAttrValues 需要插入国际化信息的属性列表
     * @return
     */
    private List<SpuAttrValue> setSpuAttrValueInfo(Long spuId, Long categoryId, List<SpuAttrValueDTO> spuAttrValues, Integer sysType) {
        if (CollUtil.isEmpty(spuAttrValues)) {
            return new ArrayList<>(0);
        }
        if (Objects.isNull(sysType)) {
            sysType = AuthUserContext.get().getSysType();
        }
        List<AttrVO> dbAttrList = attrMapper.getAttrsByCategoryIdAndAttrType(AttrType.BASIC.value(), categoryId, null, sysType);
        Map<Long, AttrVO> dbAttrMap = dbAttrList.stream().collect(Collectors.toMap(AttrVO::getAttrId, a -> a));
        List<SpuAttrValue> spuAttrValueList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (SpuAttrValueDTO spuAttrValueDTO : spuAttrValues) {
            // 不保存属性值为空的数据
            if (StrUtil.isBlank(spuAttrValueDTO.getAttrValueName())) {
                continue;
            }
            AttrVO dbAttr = dbAttrMap.get(spuAttrValueDTO.getAttrId());
            // 属性值为输入的数据，没有属性值的国际化信息， 设为通用语言
            boolean isShare = (Objects.isNull(spuAttrValueDTO.getAttrId()) && Objects.isNull(spuAttrValueDTO.getAttrValueId())) || Objects.isNull(dbAttr);
            if (isShare) {
                SpuAttrValue spuAttrValue = BeanUtil.map(spuAttrValueDTO, SpuAttrValue.class);
                spuAttrValue.setSpuId(spuId);
                spuAttrValue.setLang(LanguageEnum.LANGUAGE_ZH_CN.getLang());
                spuAttrValueList.add(spuAttrValue);
                continue;
            }
            // 插入中英文国际化信息
            SpuAttrValue spuAttrValueZh = BeanUtil.map(spuAttrValueDTO, SpuAttrValue.class);
            SpuAttrValue spuAttrValueEn = BeanUtil.map(spuAttrValueDTO, SpuAttrValue.class);
            //属性国际化信息
            for (AttrLangVO attrLangVO : dbAttr.getAttrLangList()) {
                if (Objects.equals(LanguageEnum.LANGUAGE_ZH_CN.getLang(), attrLangVO.getLang())) {
                    spuAttrValueZh.setSpuId(spuId);
                    spuAttrValueZh.setLang(LanguageEnum.LANGUAGE_ZH_CN.getLang());
                    spuAttrValueZh.setAttrName(attrLangVO.getName());
                    spuAttrValueZh.setAttrDesc(attrLangVO.getDesc());
                    spuAttrValueList.add(spuAttrValueZh);
                    continue;
                }
                spuAttrValueEn.setSpuId(spuId);
                spuAttrValueEn.setLang(LanguageEnum.LANGUAGE_EN.getLang());
                spuAttrValueEn.setAttrName(attrLangVO.getName());
                spuAttrValueEn.setAttrDesc(attrLangVO.getDesc());
                spuAttrValueList.add(spuAttrValueEn);
            }
            if (Objects.isNull(spuAttrValueDTO.getAttrValueId())) {
                continue;
            }
            // 属性值国际化信息
            Map<Long, AttrValueVO> attrValueMap = dbAttr.getAttrValues().stream()
                    .filter(attrValueVO -> Objects.equals(spuAttrValueDTO.getAttrValueId(), attrValueVO.getAttrValueId()))
                    .collect(Collectors.toMap(AttrValueVO::getAttrValueId, a -> a));
            AttrValueVO attrValueVO = attrValueMap.get(spuAttrValueDTO.getAttrValueId());
            if (Objects.isNull(attrValueVO)) {
                continue;
            }
            for (AttrValueLangVO attrValueLang : attrValueVO.getValues()) {
                if (Objects.equals(LanguageEnum.LANGUAGE_ZH_CN.getLang(), attrValueLang.getLang())) {
                    spuAttrValueZh.setAttrValueName(attrValueLang.getValue());
                    continue;
                }
                spuAttrValueEn.setAttrValueName(attrValueLang.getValue());
            }
        }
        return spuAttrValueList;
    }
}
