package com.agent.management.repository;

import com.agent.management.model.entity.TranslationEntry;
import com.agent.management.repository.json.AbstractJsonRepository;
import com.agent.management.repository.json.JsonStore;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 翻译缓存持久化仓库
 *
 * 文件：translations.json
 * 业务 key：sourceText（原文 trim 后值），全文精确匹配
 *
 * 写入并发说明：
 * 不同 sourceText 的并发 save 在 AbstractJsonRepository.save 中存在
 * loadAll→writeAll 之间的覆盖窗口（不同文件读写锁，不互斥），
 * 因此本仓库的 save(sourceText, translatedText) 加 synchronized 串行化。
 * 写频率极低（仅在 LLM 翻译成功时触发），无性能影响。
 */
@Component
public class TranslationCacheRepository extends AbstractJsonRepository<TranslationEntry> {

    public TranslationCacheRepository(JsonStore store) {
        super(store, new TypeReference<>() {});
    }

    @Override
    protected String getFileName() {
        return "translations.json";
    }

    @Override
    protected Long getId(TranslationEntry entity) {
        return entity.getId();
    }

    @Override
    protected void setId(TranslationEntry entity, Long id) {
        entity.setId(id);
    }

    /**
     * 按原文查找缓存条目（全文精确匹配）
     */
    public Optional<TranslationEntry> findBySourceText(String sourceText) {
        if (sourceText == null) return Optional.empty();
        List<TranslationEntry> all = findAll();
        return all.stream()
                .filter(e -> sourceText.equals(e.getSourceText()))
                .findFirst();
    }

    /**
     * 保存翻译结果：存在则更新译文，不存在则新增
     * 方法级 synchronized 规避并发覆盖窗口
     */
    public synchronized void save(String sourceText, String translatedText) {
        if (sourceText == null || translatedText == null) return;

        List<TranslationEntry> all = findAll();
        for (TranslationEntry e : all) {
            if (sourceText.equals(e.getSourceText())) {
                if (!translatedText.equals(e.getTranslatedText())) {
                    e.setTranslatedText(translatedText);
                    writeAll(all);
                }
                return;
            }
        }

        TranslationEntry entry = new TranslationEntry();
        entry.setSourceText(sourceText);
        entry.setTranslatedText(translatedText);
        entry.setCreatedAt(LocalDateTime.now());
        save(entry);
    }
}
