import { getRagTopicBoostWeight, getRagTopK } from "./config";
import { cosineSimilarity, embedText } from "./embedder";
import { loadKnowledgeStore } from "./knowledge-store";
import type {
  KnowledgeHit,
  KnowledgePlatform,
  KnowledgeTopic,
  RagCitation,
  RetrieveKnowledgeInput,
} from "./types";

const PLATFORM_PRIORITY: KnowledgePlatform[] = [
  "linkedin",
  "facebook",
  "instagram",
  "youtube",
  "twitter",
  "tiktok",
  "threads",
  "pinterest",
];

/** Pick one platform store per retrieval call (never merge indexes). */
export function resolvePrimaryRagPlatform(platforms: string[]): KnowledgePlatform {
  for (const preferred of PLATFORM_PRIORITY) {
    if (platforms.includes(preferred)) return preferred;
  }
  const first = platforms.find((p) => p !== "youtube" && p !== "global");
  return (first as KnowledgePlatform) || "linkedin";
}

export function buildGenerationRagQuery(input: {
  companyName: string;
  industry?: string;
  sequenceTitle?: string;
  problem?: string;
  impact?: string;
  contentCategory?: string;
  caption?: string;
  mediaType?: "caption" | "image" | "video";
}): string {
  const captionSnippet = input.caption?.replace(/#\w+/g, "").trim().slice(0, 400);
  const parts = [
    input.companyName,
    input.industry,
    input.sequenceTitle,
    input.contentCategory,
    input.problem,
    input.impact,
    captionSnippet,
    input.mediaType === "image"
      ? "social banner image best practices"
      : input.mediaType === "video"
        ? "short vertical video storyboard"
        : "B2B social caption tone and structure",
  ];
  return parts.filter(Boolean).join(" — ").slice(0, 1200);
}

function applyTopicBoost(
  score: number,
  chunkTopic: string,
  topicBoost?: KnowledgeTopic | KnowledgeTopic[],
): number {
  if (!topicBoost) return score;
  const targets = Array.isArray(topicBoost) ? topicBoost : [topicBoost];
  if (targets.some((t) => chunkTopic === t || chunkTopic.startsWith(String(t)))) {
    return score + getRagTopicBoostWeight();
  }
  return score;
}

export async function retrieveKnowledge(
  input: RetrieveKnowledgeInput,
): Promise<KnowledgeHit[]> {
  const store = await loadKnowledgeStore(input.platform);
  if (!store?.chunks?.length) return [];

  const { embedding } = await embedText(input.query);
  const topK = input.topK ?? getRagTopK();

  return store.chunks
    .map((c) => {
      const base = cosineSimilarity(embedding, c.embedding);
      const score = applyTopicBoost(base, String(c.topic), input.topicBoost);
      return {
        id: c.id,
        topic: String(c.topic),
        sectionTitle: c.sectionTitle,
        score,
        content: c.content,
        sourceFile: c.sourceFile,
      };
    })
    .sort((a, b) => b.score - a.score)
    .slice(0, topK);
}

export function hitsToCitations(
  hits: KnowledgeHit[],
  platform: KnowledgePlatform,
): RagCitation[] {
  return hits.map((h) => ({
    id: h.id,
    platform,
    topic: h.topic,
    sectionTitle: h.sectionTitle,
    score: Math.round(h.score * 10000) / 10000,
    sourceFile: h.sourceFile,
  }));
}
