package com.ruoyi.web.modules.goods.support;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.goods.constant.GoodsConstants;
import com.ruoyi.web.modules.goods.domain.BizGoodsAttr;
import com.ruoyi.web.modules.goods.dto.GoodsAttrItemDTO;
import com.ruoyi.web.modules.template.constant.AttrTemplateConstants;

/**
 * 商品属性/规格快照工具
 */
public final class GoodsAttrSupport
{
    private static final int MAX_ITEM_NAME_LEN = 64;

    private static final int MAX_VALUE_LEN = 128;

    private GoodsAttrSupport()
    {
    }

    public static List<BizGoodsAttr> flatten(Long goodsId, List<GoodsAttrItemDTO> attributes,
            List<GoodsAttrItemDTO> specs)
    {
        validateItems(attributes, specs);
        List<BizGoodsAttr> rows = new ArrayList<>();
        appendRows(goodsId, AttrTemplateConstants.ITEM_TYPE_ATTR, attributes, rows);
        appendRows(goodsId, AttrTemplateConstants.ITEM_TYPE_SPEC, specs, rows);
        return rows;
    }

    public static List<GoodsAttrItemDTO> groupByItem(List<BizGoodsAttr> rows, String attrType)
    {
        Map<String, GoodsAttrItemDTO> ordered = new LinkedHashMap<>();
        if (rows == null)
        {
            return new ArrayList<>();
        }
        for (BizGoodsAttr row : rows)
        {
            if (!attrType.equals(row.getAttrType()))
            {
                continue;
            }
            GoodsAttrItemDTO item = ordered.computeIfAbsent(row.getItemName(), name -> {
                GoodsAttrItemDTO dto = new GoodsAttrItemDTO();
                dto.setItemName(name);
                dto.setValues(new ArrayList<>());
                return dto;
            });
            item.getValues().add(row.getValueText());
        }
        return new ArrayList<>(ordered.values());
    }

    private static void validateItems(List<GoodsAttrItemDTO> attributes, List<GoodsAttrItemDTO> specs)
    {
        Set<String> attrNames = validateSection(attributes, "属性项");
        Set<String> specNames = validateSection(specs, "规格项");
        for (String name : attrNames)
        {
            if (specNames.contains(name))
            {
                throw new ServiceException(GoodsConstants.MSG_ATTR_CROSS_ITEM_NAME);
            }
        }
    }

    private static Set<String> validateSection(List<GoodsAttrItemDTO> items, String label)
    {
        Set<String> names = new HashSet<>();
        if (items == null || items.isEmpty())
        {
            return names;
        }
        for (GoodsAttrItemDTO item : items)
        {
            if (item == null || StringUtils.isEmpty(item.getItemName()))
            {
                throw new ServiceException(GoodsConstants.MSG_ATTR_ITEM_NAME_REQUIRED);
            }
            String itemName = item.getItemName().trim();
            if (itemName.length() > MAX_ITEM_NAME_LEN)
            {
                throw new ServiceException(label + "名称过长");
            }
            if (!names.add(itemName))
            {
                throw new ServiceException(GoodsConstants.MSG_ATTR_ITEM_NAME_DUPLICATE);
            }
            if (item.getValues() == null || item.getValues().isEmpty())
            {
                throw new ServiceException(GoodsConstants.MSG_ATTR_VALUE_REQUIRED);
            }
            Set<String> valueSet = new HashSet<>();
            List<String> normalizedValues = new ArrayList<>();
            for (String value : item.getValues())
            {
                if (StringUtils.isEmpty(value))
                {
                    throw new ServiceException(GoodsConstants.MSG_ATTR_VALUE_REQUIRED);
                }
                String valueText = value.trim();
                if (valueText.length() > MAX_VALUE_LEN)
                {
                    throw new ServiceException(label + "值过长");
                }
                if (!valueSet.add(valueText))
                {
                    throw new ServiceException(GoodsConstants.MSG_ATTR_VALUE_DUPLICATE);
                }
                normalizedValues.add(valueText);
            }
            item.setItemName(itemName);
            item.setValues(normalizedValues);
        }
        return names;
    }

    private static void appendRows(Long goodsId, String attrType, List<GoodsAttrItemDTO> items,
            List<BizGoodsAttr> rows)
    {
        if (items == null || items.isEmpty())
        {
            return;
        }
        int sortNo = 0;
        for (GoodsAttrItemDTO item : items)
        {
            for (String value : item.getValues())
            {
                BizGoodsAttr row = new BizGoodsAttr();
                row.setGoodsId(goodsId);
                row.setAttrType(attrType);
                row.setItemName(item.getItemName());
                row.setValueText(value);
                row.setSortNo(sortNo++);
                rows.add(row);
            }
        }
    }
}
