package com.gxwebsoft.house.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.house.entity.HouseFaq;
import com.gxwebsoft.house.mapper.HouseFaqMapper;
import com.gxwebsoft.house.param.HouseFaqParam;
import com.gxwebsoft.house.service.HouseFaqService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * AI找房常见问题Service实现
 */
@Service
public class HouseFaqServiceImpl extends ServiceImpl<HouseFaqMapper, HouseFaq> implements HouseFaqService {

    @Override
    public PageResult<HouseFaq> pageRel(HouseFaqParam param) {
        PageParam<HouseFaq, HouseFaqParam> page = new PageParam<>(param);
        page.setDefaultOrder("sort_number asc, faq_id desc");
        List<HouseFaq> list = baseMapper.selectPageRel(page, param);
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public List<HouseFaq> listRel(HouseFaqParam param) {
        return baseMapper.selectListRel(param);
    }

    @Override
    public HouseFaq getByIdRel(Integer faqId) {
        HouseFaqParam param = new HouseFaqParam();
        param.setFaqId(faqId);
        return param.getOne(baseMapper.selectListRel(param));
    }

    @Override
    public List<HouseFaq> findBestMatches(String queryText, int limit) {
        return findBestMatches(queryText, limit, null);
    }

    @Override
    public List<HouseFaq> findBestMatches(String queryText, int limit, Integer tenantId) {
        HouseFaqParam param = new HouseFaqParam();
        param.setStatus(0);
        param.setTenantId(tenantId);
        List<HouseFaq> all = baseMapper.selectListRel(param);
        if (StrUtil.isBlank(queryText) || all == null || all.isEmpty()) {
            return new ArrayList<>();
        }
        final String normalizedQuery = normalizeText(queryText);
        return all.stream()
            .map(item -> new ScoredFaq(item, score(item, normalizedQuery)))
            .filter(item -> item.score > 0)
            .sorted(Comparator.comparingInt(ScoredFaq::getScore).reversed()
                .thenComparing(item -> item.faq.getSortNumber() == null ? Integer.MAX_VALUE : item.faq.getSortNumber()))
            .limit(limit)
            .map(ScoredFaq::getFaq)
            .collect(Collectors.toList());
    }

    private int score(HouseFaq faq, String normalizedQuery) {
        int score = 0;
        String question = normalizeText(faq.getQuestion());
        String keywords = normalizeText(faq.getKeywords());
        String answer = normalizeText(faq.getAnswer());
        String category = normalizeText(faq.getCategory());
        if (StrUtil.isBlank(normalizedQuery)) {
            return score;
        }
        if (question.contains(normalizedQuery)) {
            score += 120;
        }
        if (keywords.contains(normalizedQuery)) {
            score += 100;
        }
        if (answer.contains(normalizedQuery)) {
            score += 40;
        }
        if (category.contains(normalizedQuery)) {
            score += 30;
        }
        for (String token : tokenize(normalizedQuery)) {
            if (token.length() < 2) {
                continue;
            }
            if (question.contains(token)) {
                score += 20;
            }
            if (keywords.contains(token)) {
                score += 18;
            }
            if (answer.contains(token)) {
                score += 8;
            }
            if (category.contains(token)) {
                score += 6;
            }
        }
        return score;
    }

    private List<String> tokenize(String text) {
        String normalized = normalizeText(text);
        List<String> tokens = new ArrayList<>();
        for (String item : normalized.split("[,，\\s+/|]+")) {
            if (StrUtil.isNotBlank(item)) {
                tokens.add(item);
            }
        }
        return tokens;
    }

    private String normalizeText(String text) {
        if (text == null) {
            return "";
        }
        return text.replace("　", " ")
            .replace("，", ",")
            .replace("。", " ")
            .replace("；", " ")
            .replace("：", " ")
            .replace("（", "(")
            .replace("）", ")")
            .replace("㎡", "平")
            .replace("m²", "平")
            .replace("M²", "平")
            .toLowerCase(Locale.ROOT)
            .trim();
    }

    private static class ScoredFaq {
        private final HouseFaq faq;
        private final int score;

        private ScoredFaq(HouseFaq faq, int score) {
            this.faq = faq;
            this.score = score;
        }

        public HouseFaq getFaq() {
            return faq;
        }

        public int getScore() {
            return score;
        }
    }
}
