import { anthropicApi } from './api';
import * as db from './db';

const SYSTEM_PROMPT = `You are an AI knowledge extractor for Respellion, an IT company built on radical transparency.
You receive a source text. Your task is to extract core concepts, roles, and processes, and return them as a structured JSON Knowledge Graph.
Facts should be integrated into the descriptions of the other labels and NOT be extracted as unique topics.

ALWAYS return a valid JSON object in the following format:
{
  "topics": [
    {
      "id": "unique-slug",
      "label": "Topic title",
      "type": "concept | role | process",
      "description": "A concise, clear explanation of max 3 sentences."
    }
  ],
  "relations": [
    {
      "source": "topic-id-1",
      "target": "topic-id-2",
      "type": "related_to | depends_on | part_of | executed_by"
    }
  ]
}
Return JSON only. No markdown blocks or other text.`;

export async function processSourceText(textContent, sourceName) {
  const rec = await db.addSource({ name: sourceName, status: 'processing' });
  const sourceId = rec.id;

  try {
    const responseText = await anthropicApi.generateContent(SYSTEM_PROMPT, `Analyze the following text:\n\n${textContent}`);

    let extractedData;
    try {
      const jsonMatch = responseText.match(/\{[\s\S]*\}/);
      const jsonStr = jsonMatch ? jsonMatch[0] : responseText;
      extractedData = JSON.parse(jsonStr);
    } catch (e) {
      throw new Error('AI response was not valid JSON.');
    }

    await mergeKnowledgeGraph(extractedData);
    await db.updateSourceStatus(sourceId, 'completed');

    return { success: true, data: extractedData };

  } catch (error) {
    await db.updateSourceStatus(sourceId, 'failed', error.message);
    throw error;
  }
}

async function mergeKnowledgeGraph(newData) {
  const existingTopics = await db.getTopics();
  const existingRelations = await db.getRelations();

  const topicsMap = new Map(existingTopics.map(t => [t.id, t]));

  if (newData.topics && Array.isArray(newData.topics)) {
    for (const t of newData.topics) {
      if (!topicsMap.has(t.id)) {
        topicsMap.set(t.id, t);
      }
    }
  }

  const newRelations = [...existingRelations];
  if (newData.relations && Array.isArray(newData.relations)) {
    for (const r of newData.relations) {
      const isDup = newRelations.some(ex => ex.source === r.source && ex.target === r.target && ex.type === r.type);
      if (!isDup) {
        newRelations.push(r);
      }
    }
  }

  await db.saveTopics(Array.from(topicsMap.values()));
  await db.saveRelations(newRelations);
}
