import { promises as fs } from "fs";
import path from "path";
import {
  KNOWLEDGE_PLATFORMS,
  type KnowledgePlatform,
  type KnowledgeStore,
} from "./types";

const storeCache = new Map<KnowledgePlatform, KnowledgeStore>();

export function isKnowledgePlatform(value: string): value is KnowledgePlatform {
  return (KNOWLEDGE_PLATFORMS as readonly string[]).includes(value);
}

export function knowledgeStorePath(platform: KnowledgePlatform): string {
  return path.join(process.cwd(), "data", "knowledge", platform, "chunks.json");
}

export async function knowledgeStoreExists(platform: KnowledgePlatform): Promise<boolean> {
  try {
    await fs.access(knowledgeStorePath(platform));
    return true;
  } catch {
    return false;
  }
}

export async function loadKnowledgeStore(platform: KnowledgePlatform): Promise<KnowledgeStore | null> {
  const cached = storeCache.get(platform);
  if (cached) return cached;

  const filePath = knowledgeStorePath(platform);
  try {
    const raw = await fs.readFile(filePath, "utf8");
    const parsed = JSON.parse(raw) as KnowledgeStore;
    if (!Array.isArray(parsed.chunks)) {
      return null;
    }
    storeCache.set(platform, parsed);
    return parsed;
  } catch {
    return null;
  }
}

export function clearKnowledgeStoreCache(platform?: KnowledgePlatform): void {
  if (platform) {
    storeCache.delete(platform);
    return;
  }
  storeCache.clear();
}

export async function loadKnowledgeCatalog(): Promise<{
  platforms: { platform: KnowledgePlatform; chunkCount: number; path: string }[];
} | null> {
  try {
    const raw = await fs.readFile(
      path.join(process.cwd(), "data", "knowledge", "catalog.json"),
      "utf8",
    );
    const catalog = JSON.parse(raw) as {
      platforms?: { platform: string; chunkCount: number; path: string }[];
    };
    const platforms = (catalog.platforms ?? [])
      .filter((p) => isKnowledgePlatform(p.platform))
      .map((p) => ({
        platform: p.platform as KnowledgePlatform,
        chunkCount: p.chunkCount,
        path: p.path,
      }));
    return { platforms };
  } catch {
    return null;
  }
}
