package com.ruoyi.warehouse.service.impl;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.warehouse.domain.OutRecord;
import com.ruoyi.warehouse.domain.StockInfo;
import com.ruoyi.warehouse.mapper.StockInfoMapper;
import com.ruoyi.warehouse.service.IOutRecordService;
import com.ruoyi.warehouse.service.IStockInfoService;

@Service
public class StockInfoServiceImpl implements IStockInfoService
{
    private static final int MAX_KEYWORD_TOKEN_COUNT = 5;

    @Autowired
    private StockInfoMapper stockInfoMapper;

    @Autowired
    private IOutRecordService outRecordService;

    @Override
    public List<StockInfo> selectStockInfoList(StockInfo stockInfo)
    {
        List<String> tokens = parseKeywordTokens(stockInfo);
        List<StockInfo> list = stockInfoMapper.selectStockInfoList(stockInfo);
        if (tokens.isEmpty())
        {
            return list;
        }
        List<ScoredStock> scoredList = new ArrayList<>();
        for (StockInfo item : list)
        {
            int score = scoreStock(item, tokens);
            if (score > 0)
            {
                scoredList.add(new ScoredStock(item, score));
            }
        }
        scoredList.sort((left, right) -> {
            int scoreCompare = Integer.compare(right.score, left.score);
            if (scoreCompare != 0)
            {
                return scoreCompare;
            }
            long leftId = left.stock.getId() == null ? 0L : left.stock.getId();
            long rightId = right.stock.getId() == null ? 0L : right.stock.getId();
            return Long.compare(rightId, leftId);
        });
        List<StockInfo> result = new ArrayList<>(scoredList.size());
        for (ScoredStock item : scoredList)
        {
            result.add(item.stock);
        }
        return result;
    }

    private List<String> parseKeywordTokens(StockInfo stockInfo)
    {
        if (stockInfo == null || StringUtils.isBlank(stockInfo.getProductName()))
        {
            return new ArrayList<>();
        }
        LinkedHashSet<String> tokens = new LinkedHashSet<>();
        String keyword = stockInfo.getProductName().trim().toLowerCase();
        for (String item : keyword.split("[\\s,，;；、]+"))
        {
            if (StringUtils.isNotBlank(item))
            {
                tokens.add(item.trim());
            }
            if (tokens.size() >= MAX_KEYWORD_TOKEN_COUNT)
            {
                break;
            }
        }
        if (tokens.isEmpty())
        {
            return new ArrayList<>();
        }
        stockInfo.getParams().put("keywordTokens", new ArrayList<>(tokens));
        return new ArrayList<>(tokens);
    }

    private int scoreStock(StockInfo stock, List<String> tokens)
    {
        int totalScore = 0;
        for (String token : tokens)
        {
            int tokenScore = 0;
            tokenScore += scoreField(stock.getProductName(), token, 120, 90, 60);
            tokenScore += scoreField(stock.getSpec(), token, 90, 70, 45);
            tokenScore += scoreField(stock.getBrand(), token, 80, 60, 40);
            tokenScore += scoreField(stock.getCategory(), token, 70, 50, 35);
            tokenScore += scoreField(stock.getAreaName(), token, 65, 45, 30);
            tokenScore += scoreField(stock.getUnit(), token, 35, 0, 20);
            tokenScore += scoreField(stock.getProductCode(), token, 0, 0, 10);
            tokenScore += scoreField(stock.getAreaCode(), token, 0, 0, 10);
            if (tokenScore <= 0)
            {
                return 0;
            }
            totalScore += tokenScore;
        }
        return totalScore;
    }

    private int scoreField(String value, String token, int exactScore, int prefixScore, int containsScore)
    {
        if (StringUtils.isBlank(value) || StringUtils.isBlank(token))
        {
            return 0;
        }
        String lowerValue = value.toLowerCase();
        if (exactScore > 0 && lowerValue.equals(token))
        {
            return exactScore;
        }
        if (prefixScore > 0 && lowerValue.startsWith(token))
        {
            return prefixScore;
        }
        if (containsScore > 0 && lowerValue.contains(token))
        {
            return containsScore;
        }
        return 0;
    }

    private static class ScoredStock
    {
        private final StockInfo stock;
        private final int score;

        private ScoredStock(StockInfo stock, int score)
        {
            this.stock = stock;
            this.score = score;
        }
    }

    @Override
    public StockInfo selectStockInfoById(Long id)
    {
        return stockInfoMapper.selectStockInfoById(id);
    }

    @Override
    public int outStock(OutRecord outRecord)
    {
        StockInfo stockInfo = stockInfoMapper.selectStockInfoById(outRecord.getId());
        if (stockInfo == null)
        {
            throw new ServiceException("库存记录不存在");
        }
        outRecord.setId(null);
        outRecord.setAreaId(stockInfo.getAreaId());
        outRecord.setProductId(stockInfo.getProductId());
        return outRecordService.insertOutRecord(outRecord);
    }
}
