package com.hertz.modules.knowledge.service;

import com.hertz.config.AppPathResolver;
import java.io.File;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class KnowledgeVectorStoreManager {

  private final EmbeddingModel embeddingModel;
  private final AppPathResolver pathResolver;

  @Value("${spring.ai.vectorstore.simple.store.path:vector-store.json}")
  private String vectorStorePath;

  private final Map<Long, SimpleVectorStore> cache = new ConcurrentHashMap<>();
  private final Map<Long, Object> locks = new ConcurrentHashMap<>();

  public KnowledgeVectorStoreManager(EmbeddingModel embeddingModel, AppPathResolver pathResolver) {
    this.embeddingModel = embeddingModel;
    this.pathResolver = pathResolver;
  }

  public SimpleVectorStore get(Long kbId) {
    Object lock = locks.computeIfAbsent(kbId, k -> new Object());
    synchronized (lock) {
      return cache.computeIfAbsent(kbId, id -> {
        SimpleVectorStore store = SimpleVectorStore.builder(embeddingModel).build();
        File file = resolveStoreFile(id).toFile();
        if (file.exists()) {
          store.load(file);
        }
        return store;
      });
    }
  }

  public void save(Long kbId) {
    Object lock = locks.computeIfAbsent(kbId, k -> new Object());
    synchronized (lock) {
      SimpleVectorStore store = get(kbId);
      store.save(resolveStoreFile(kbId).toFile());
    }
  }

  public void replace(Long kbId, SimpleVectorStore newStore) {
    Object lock = locks.computeIfAbsent(kbId, k -> new Object());
    synchronized (lock) {
      cache.put(kbId, newStore);
      newStore.save(resolveStoreFile(kbId).toFile());
    }
  }

  public void delete(Long kbId) {
    Object lock = locks.computeIfAbsent(kbId, k -> new Object());
    synchronized (lock) {
      cache.remove(kbId);
      File file = resolveStoreFile(kbId).toFile();
      if (file.exists()) {
        file.delete();
      }
    }
  }

  private Path resolveStoreFile(Long kbId) {
    File configured = new File(pathResolver.resolve(vectorStorePath));
    File baseDir;
    if (vectorStorePath.endsWith(".json")) {
      baseDir = configured.getParentFile() == null ? new File(".") : configured.getParentFile();
    } else {
      baseDir = configured;
    }
    if (!baseDir.exists()) {
      baseDir.mkdirs();
    }
    return new File(baseDir, "vector-store-kb-" + kbId + ".json").toPath();
  }
}
