package com.xindazhou.business.service.community.sensitive;

import com.xindazhou.business.controller.admin.community.sensitive.vo.SensitiveWordPageReqVO;
import com.xindazhou.business.controller.admin.community.sensitive.vo.SensitiveWordRespVO;
import com.xindazhou.business.controller.admin.community.sensitive.vo.SensitiveWordSaveReqVO;
import com.xindazhou.business.convert.community.sensitive.SensitiveWordConvert;
import com.xindazhou.business.dal.community.dataobject.sensitive.SensitiveWordDO;
import com.xindazhou.business.dal.community.mysql.sensitive.SensitiveWordMapper;
import com.xindazhou.framework.common.exception.util.ServiceExceptionUtil;
import com.xindazhou.framework.common.pojo.PageResult;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;

import java.util.List;
import java.util.ArrayList;

import static com.xindazhou.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;

/**
 * 敏感词 Service 实现类
 *
 * @author xindazhou
 */
@Service("communitySensitiveWordServiceImpl")
@Validated
@Slf4j
public class SensitiveWordServiceImpl implements SensitiveWordService {

    @Resource
    private SensitiveWordMapper sensitiveWordMapper;

    // sensitive-word 实例（AC自动机）
    private SensitiveWordBs sensitiveWordBs;

    @PostConstruct
    public void init() {
        refreshCache();
    }

    /**
     * 刷新敏感词缓存
     */
    public void refreshCache() {
        List<SensitiveWordDO> words = sensitiveWordMapper.selectListEnabled();
        
        // 只处理禁用词（type=1）
        List<String> forbiddenWords = new ArrayList<>();
        
        for (SensitiveWordDO word : words) {
            if (word.getType() == 1) {
                // 禁用词
                forbiddenWords.add(word.getWord());
            }
        }
        
        // 初始化 sensitive-word（使用禁用词列表，AC自动机）
        sensitiveWordBs = SensitiveWordBs.newInstance()
                .wordDeny(new com.github.houbb.sensitive.word.api.IWordDeny() {
                    @Override
                    public List<String> deny() {
                        return forbiddenWords;
                    }
                })
                .init();
        
        log.info("敏感词缓存已刷新，禁用词: {}", forbiddenWords.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createSensitiveWord(SensitiveWordSaveReqVO createReqVO) {
        // 校验敏感词是否存在
        SensitiveWordDO existWord = sensitiveWordMapper.selectOne(
                new com.xindazhou.framework.mybatis.core.query.LambdaQueryWrapperX<SensitiveWordDO>()
                        .eq(SensitiveWordDO::getWord, createReqVO.getWord()));
        if (existWord != null) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "敏感词已存在");
        }

        // 插入
        SensitiveWordDO word = SensitiveWordConvert.INSTANCE.convert(createReqVO);
        sensitiveWordMapper.insert(word);

        // 刷新缓存
        refreshCache();
        return word.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSensitiveWord(SensitiveWordSaveReqVO updateReqVO) {
        // 校验存在
        validateSensitiveWordExists(updateReqVO.getId());
        // 校验敏感词是否存在（排除自己）
        SensitiveWordDO existWord = sensitiveWordMapper.selectOne(
                new com.xindazhou.framework.mybatis.core.query.LambdaQueryWrapperX<SensitiveWordDO>()
                        .eq(SensitiveWordDO::getWord, updateReqVO.getWord())
                        .ne(SensitiveWordDO::getId, updateReqVO.getId()));
        if (existWord != null) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "敏感词已存在");
        }

        // 更新
        SensitiveWordDO updateObj = SensitiveWordConvert.INSTANCE.convert(updateReqVO);
        sensitiveWordMapper.updateById(updateObj);

        // 刷新缓存
        refreshCache();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSensitiveWord(Long id) {
        // 校验存在
        validateSensitiveWordExists(id);
        // 删除
        sensitiveWordMapper.deleteById(id);

        // 刷新缓存
        refreshCache();
    }

    private SensitiveWordDO validateSensitiveWordExists(Long id) {
        SensitiveWordDO word = sensitiveWordMapper.selectById(id);
        if (word == null) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "敏感词不存在");
        }
        return word;
    }

    @Override
    public SensitiveWordRespVO getSensitiveWord(Long id) {
        SensitiveWordDO word = validateSensitiveWordExists(id);
        return SensitiveWordConvert.INSTANCE.convert(word);
    }

    @Override
    public PageResult<SensitiveWordRespVO> getSensitiveWordPage(SensitiveWordPageReqVO pageReqVO) {
        com.xindazhou.framework.mybatis.core.query.LambdaQueryWrapperX<SensitiveWordDO> queryWrapper = new com.xindazhou.framework.mybatis.core.query.LambdaQueryWrapperX<SensitiveWordDO>()
                .likeIfPresent(SensitiveWordDO::getWord, pageReqVO.getWord())
                .eqIfPresent(SensitiveWordDO::getType, pageReqVO.getType())
                .eqIfPresent(SensitiveWordDO::getStatus, pageReqVO.getStatus())
                .orderByDesc(SensitiveWordDO::getId);
        PageResult<SensitiveWordDO> pageResult = sensitiveWordMapper.selectPage(pageReqVO, queryWrapper);
        return SensitiveWordConvert.INSTANCE.convertPage(pageResult);
    }

    @Override
    public String filterSensitiveWord(String text) {
        if (text == null || text.isEmpty()) {
            return text;
        }

        // 检查禁用词（使用 AC 自动机）
        if (sensitiveWordBs != null && sensitiveWordBs.contains(text)) {
            return null; // 包含禁用词，返回null表示不允许
        }

        // 无禁用词，返回原文本
        return text;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateStatus(List<Long> ids, Integer status) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        for (Long id : ids) {
            SensitiveWordDO updateObj = new SensitiveWordDO();
            updateObj.setId(id);
            updateObj.setStatus(status);
            sensitiveWordMapper.updateById(updateObj);
        }
        // 刷新缓存
        refreshCache();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer importSensitiveWords(org.springframework.web.multipart.MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "文件不能为空");
        }
        
        try {
            // TODO: 实现Excel/CSV文件解析和导入
            // 这里先返回0，后续实现文件解析逻辑
            log.warn("敏感词导入功能待实现");
            return 0;
        } catch (Exception e) {
            log.error("导入敏感词失败", e);
            throw ServiceExceptionUtil.exception(BAD_REQUEST, "导入失败：" + e.getMessage());
        }
    }

}


