import { prisma } from '@/lib/prisma'
import { getTagsProvider } from '@/lib/ai/factory'
import { getSystemConfig } from '@/lib/config'

export interface NoteForOrganization {
  id: string
  title: string | null
  content: string
}

export interface NotebookOrganization {
  notebookId: string
  notebookName: string
  notebookIcon: string | null
  notebookColor: string | null
  notes: Array<{
    noteId: string
    title: string | null
    content: string
    confidence: number
    reason: string
  }>
}

export interface OrganizationPlan {
  notebooks: NotebookOrganization[]
  totalNotes: number
  unorganizedNotes: number // Notes that couldn't be categorized
}

/**
 * Service for batch organizing notes from "Notes générales" into notebooks
 * (Story 5.3 - IA3)
 */
export class BatchOrganizationService {
  /**
   * Analyze all notes in "Notes générales" and create an organization plan
   * @param userId - User ID
   * @param language - User's preferred language (default: 'en')
   * @returns Organization plan with notebook assignments
   */
  async createOrganizationPlan(userId: string, language: string = 'en'): Promise<OrganizationPlan> {
    // 1. Get all notes without notebook (Inbox/Notes générales)
    const notesWithoutNotebook = await prisma.note.findMany({
      where: {
        userId,
        notebookId: null,
        trashedAt: null,
      },
      select: {
        id: true,
        title: true,
        content: true,
      },
      orderBy: {
        updatedAt: 'desc',
      },
      take: 50, // Limit to 50 notes for AI processing
    })

    if (notesWithoutNotebook.length === 0) {
      return {
        notebooks: [],
        totalNotes: 0,
        unorganizedNotes: 0,
      }
    }

    // 2. Get all user's notebooks
    const notebooks = await prisma.notebook.findMany({
      where: { userId },
      include: {
        labels: true,
        _count: {
          select: { notes: true },
        },
      },
      orderBy: { order: 'asc' },
    })

    if (notebooks.length === 0) {
      // No notebooks to organize into
      return {
        notebooks: [],
        totalNotes: notesWithoutNotebook.length,
        unorganizedNotes: notesWithoutNotebook.length,
      }
    }

    // 3. Call AI to create organization plan
    const plan = await this.aiOrganizeNotes(notesWithoutNotebook, notebooks, language)

    return plan
  }

  /**
   * Use AI to analyze notes and create organization plan
   */
  private async aiOrganizeNotes(
    notes: NoteForOrganization[],
    notebooks: any[],
    language: string
  ): Promise<OrganizationPlan> {
    const prompt = this.buildPrompt(notes, notebooks, language)

    const config = await getSystemConfig()
    const provider = getTagsProvider(config)
    const response = await provider.generateText(prompt)

    const plan = this.parseAIResponse(response, notes, notebooks)
    return plan
  }

  /**
   * Build prompt for AI (localized)
   */
  private buildPrompt(notes: NoteForOrganization[], notebooks: any[], language: string = 'en'): string {
    const notebookList = notebooks
      .map(nb => {
        const labels = nb.labels.map((l: any) => l.name).join(', ')
        const count = nb._count?.notes || 0
        return `- ${nb.name} (${count} notes)${labels ? ` [labels: ${labels}]` : ''}`
      })
      .join('\n')

    const notesList = notes
      .map((note, index) => {
        const title = note.title || 'Sans titre'
        const content = note.content.substring(0, 200)
        return `[${index}] "${title}": ${content}`
      })
      .join('\n')

    // System instructions based on language
    const instructions: Record<string, string> = {
      fr: `
Tu es un assistant qui organise des notes en les regroupant par thématique dans des carnets.

CARNETS DISPONIBLES :
${notebookList}

NOTES À ORGANISER (Notes générales) :
${notesList}

TÂCHE :
Analyse chaque note et propose le carnet le PLUS approprié.
Considère :
1. Le sujet/thème de la note (LE PLUS IMPORTANT)
2. Les labels existants dans chaque carnet
3. La cohérence thématique entre notes du même carnet

GUIDES DE CLASSIFICATION :
- SPORT/EXERCICE/ACHATS/COURSSES → Carnet Personnel
- LOISIRS/PASSIONS/SORTIES → Carnet Personnel
- SANTÉ/FITNESS/MÉDECIN → Carnet Personnel ou Santé
- FAMILLE/AMIS → Carnet Personnel
- TRAVAIL/RÉUNIONS/PROJETS/CLIENTS → Carnet Travail
- CODING/TECH/DÉVELOPPEMENT → Carnet Travail ou Code
- FINANCES/FACTURES/BANQUE → Carnet Personnel ou Finances

FORMAT DE RÉPONSE (JSON) :
Pour chaque carnet, liste les notes qui lui appartiennent :
{
  "carnets": [
    {
      "nom": "Nom du carnet",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Courte explication en français"
        }
      ]
    }
  ]
}

RÈGLES :
- Seules les notes avec confiance > 0.60 doivent être assignées
- Si une note est trop générique, ne l'assigne pas
- Sois précis dans tes regroupements thématiques
- Ta réponse doit être uniquement un JSON valide
`.trim(),
      en: `
You are an assistant that organizes notes by grouping them into notebooks based on their theme.

AVAILABLE NOTEBOOKS:
${notebookList}

NOTES TO ORGANIZE (Inbox):
${notesList}

TASK:
Analyze each note and suggest the MOST appropriate notebook.
Consider:
1. The subject/theme of the note (MOST IMPORTANT)
2. Existing labels in each notebook
3. Thematic consistency between notes in the same notebook

CLASSIFICATION GUIDE:
- SPORT/EXERCISE/SHOPPING/GROCERIES → Personal Notebook
- HOBBIES/PASSIONS/OUTINGS → Personal Notebook
- HEALTH/FITNESS/DOCTOR → Personal Notebook or Health
- FAMILY/FRIENDS → Personal Notebook
- WORK/MEETINGS/PROJECTS/CLIENTS → Work Notebook
- CODING/TECH/DEVELOPMENT → Work Notebook or Code
- FINANCE/BILLS/BANKING → Personal Notebook or Finance

RESPONSE FORMAT (JSON):
For each notebook, list the notes that belong to it:
{
  "carnets": [
    {
      "nom": "Notebook Name",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Short explanation in English"
        }
      ]
    }
  ]
}

RULES:
- Only assign notes with confidence > 0.60
- If a note is too generic, do not assign it
- Be precise in your thematic groupings
- Your response must be valid JSON only
`.trim(),
      es: `
Eres un asistente que organiza notas agrupándolas por temática en cuadernos.

CUADERNOS DISPONIBLES:
${notebookList}

NOTAS A ORGANIZAR (Bandeja de entrada):
${notesList}

TAREA:
Analiza cada nota y sugiere el cuaderno MÁS apropiado.
Considera:
1. El tema/asunto de la nota (LO MÁS IMPORTANTE)
2. Etiquetas existentes en cada cuaderno
3. Coherencia temática entre notas del mismo cuaderno

GUÍA DE CLASIFICACIÓN:
- DEPORTE/EJERCICIO/COMPRAS → Cuaderno Personal
- HOBBIES/PASIONES/SALIDAS → Cuaderno Personal
- SALUD/FITNESS/DOCTOR → Cuaderno Personal o Salud
- FAMILIA/AMIGOS → Cuaderno Personal
- TRABAJO/REUNIONES/PROYECTOS → Cuaderno Trabajo
- CODING/TECH/DESARROLLO → Cuaderno Trabajo o Código
- FINANZAS/FACTURAS/BANCO → Cuaderno Personal o Finanzas

FORMATO DE RESPUESTA (JSON):
Para cada cuaderno, lista las notas que le pertenecen:
{
  "carnets": [
    {
      "nom": "Nombre del cuaderno",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Breve explicación en español"
        }
      ]
    }
  ]
}

REGLAS:
- Solo asigna notas con confianza > 0.60
- Si una nota es demasiado genérica, no la asignes
- Sé preciso en tus agrupaciones temáticas
- Tu respuesta debe ser únicamente un JSON válido
`.trim(),
      de: `
Du bist ein Assistent, der Notizen organisiert, indem er sie thematisch in Notizbücher gruppiert.

VERFÜGBARE NOTIZBÜCHER:
${notebookList}

ZU ORGANISIERENDE NOTIZEN (Eingang):
${notesList}

AUFGABE:
Analysiere jede Notiz und schlage das AM BESTEN geeignete Notizbuch vor.
Berücksichtige:
1. Das Thema/den Inhalt der Notiz (AM WICHTIGSTEN)
2. Vorhandene Labels in jedem Notizbuch
3. Thematische Konsistenz zwischen Notizen im selben Notizbuch

KLASSIFIZIERUNGSLEITFADEN:
- SPORT/ÜBUNG/EINKAUFEN → Persönliches Notizbuch
- HOBBYS/LEIDENSCHAFTEN → Persönliches Notizbuch
- GESUNDHEIT/FITNESS/ARZT → Persönliches Notizbuch oder Gesundheit
- FAMILIE/FREUNDE → Persönliches Notizbuch
- ARBEIT/MEETINGS/PROJEKTE → Arbeitsnotizbuch
- CODING/TECH/ENTWICKLUNG → Arbeitsnotizbuch oder Code
- FINANZEN/RECHNUNGEN/BANK → Persönliches Notizbuch oder Finanzen

ANTWORTFORMAT (JSON):
Für jedes Notizbuch, liste die zugehörigen Notizen auf:
{
  "carnets": [
    {
      "nom": "Name des Notizbuchs",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Kurze Erklärung auf Deutsch"
        }
      ]
    }
  ]
}

REGELN:
- Ordne nur Notizen mit Konfidenz > 0.60
- Wenn eine Notiz zu allgemein ist, ordne sie nicht zu
- Sei präzise in deinen thematischen Gruppierungen
- Deine Antwort muss ein gültiges JSON sein
`.trim(),
      it: `
Sei un assistente che organizza le note raggruppandole per tema nei taccuini.

TACCUINI DISPONIBILI:
${notebookList}

NOTE DA ORGANIZZARE (In arrivo):
${notesList}

COMPITO:
Analizza ogni nota e suggerisci il taccuino PIÙ appropriato.
Considera:
1. L'argomento/tema della nota (PIÙ IMPORTANTE)
2. Etichette esistenti in ogni taccuino
3. Coerenza tematica tra le note dello stesso taccuino

GUIDA ALLA CLASSIFICAZIONE:
- SPORT/ESERCIZIO/SHOPPING → Taccuino Personale
- HOBBY/PASSIONI/USCITE → Taccuino Personale
- SALUTE/FITNESS/DOTTORE → Taccuino Personale o Salute
- FAMIGLIA/AMIGOS → Taccuino Personale
- LAVORO/RIUNIONI/PROGETTI → Taccuino Lavoro
- CODING/TECH/SVILUPPO → Taccuino Lavoro o Codice
- FINANZA/BILLS/BANCA → Taccuino Personale o Finanza

FORMATO RISPOSTA (JSON):
Per ogni taccuino, elenca le note che appartengono ad esso:
{
  "carnets": [
    {
      "nom": "Nome del taccuino",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Breve spiegazione in italiano"
        }
      ]
    }
  ]
}

REGOLE:
- Assegna solo note con confidenza > 0.60
- Se una nota è troppo generica, non assegnarla
- Sii preciso nei tuoi raggruppamenti tematici
- La tua risposta deve essere solo un JSON valido
`.trim(),
      pt: `
Você é um assistente que organiza notas agrupando-as por tema em cadernos.

CADERNOS DISPONÍVEIS:
${notebookList}

NOTAS A ORGANIZAR (Caixa de entrada):
${notesList}

TAREFA:
Analise cada nota e sugira o caderno MAIS apropriado.
Considere:
1. O assunto/tema da nota (MAIS IMPORTANTE)
2. Etiquetas existentes em cada caderno
3. Coerência temática entre notas do mesmo caderno

GUIA DE CLASSIFICAÇÃO:
- ESPORTE/EXERCÍCIO/COMPRAS → Caderno Pessoal
- HOBBIES/PAIXÕES/SAÍDAS → Caderno Pessoal
- SAÚDE/FITNESS/MÉDICO → Caderno Pessoal ou Saúde
- FAMÍLIA/AMIGOS → Caderno Pessoal
- TRABALHO/REUNIÕES/PROJETOS → Caderno Trabalho
- CODING/TECH/DESENVOLVIMENTO → Caderno Trabalho ou Código
- FINANÇAS/CONTAS/BANCO → Caderno Pessoal ou Finanças

FORMATO DE RESPOSTA (JSON):
Para cada caderno, liste as notas que pertencem a ele:
{
  "carnets": [
    {
      "nom": "Nome do caderno",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Breve explicação em português"
        }
      ]
    }
  ]
}

REGRAS:
- Apenas atribua notas com confiança > 0.60
- Se uma nota for muito genérica, não a atribua
- Seja preciso em seus agrupamentos temáticos
- Sua resposta deve ser apenas um JSON válido
`.trim(),
      nl: `
Je bent een assistent die notities organiseert door ze thematisch in notitieboekjes te groeperen.

BESCHIKBARE NOTITIEBOEKJES:
${notebookList}

TE ORGANISEREN NOTITIES (Inbox):
${notesList}

TAAK:
Analyseer elke notitie en stel het MEEST geschikte notitieboek voor.
Overweeg:
1. Het onderwerp/thema van de notitie (BELANGRIJKST)
2. Bestaande labels in elk notitieboekje
3. Thematische consistentie tussen notities in hetzelfde notitieboekje

CLASSIFICATIEGIDS:
- SPORT/OEFENING/WINKELEN → Persoonlijk Notitieboek
- HOBBIES/PASSIES/UITJES → Persoonlijk Notitieboek
- GEZONDHEID/FITNESS/DOKTER → Persoonlijk Notitieboek of Gezondheid
- FAMILIE/VRIENDEN → Persoonlijk Notitieboek
- WERK/VERGADERINGEN/PROJECTEN → Werk Notitieboek
- CODING/TECH/ONTWIKKELING → Werk Notitieboek of Code
- FINANCIËN/REKENINGEN/BANK → Persoonlijk Notitieboek of Financiën

ANTWOORDFORMAAT (JSON):
Voor elk notitieboekje, lijst de notities op die erbij horen:
{
  "carnets": [
    {
      "nom": "Naam van het notitieboekje",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Korte uitleg in het Nederlands"
        }
      ]
    }
  ]
}

REGELS:
- Wijs alleen notities toe met vertrouwen > 0.60
- Als een notitie te generiek is, wijs deze dan niet toe
- Wees nauwkeurig in je thematische groeperingen
- Je antwoord moet alleen een geldige JSON zijn
`.trim(),
      pl: `
Jesteś asystentem, który organizuje notatki, grupując je tematycznie w notatnikach.

DOSTĘPNE NOTATNIKI:
${notebookList}

NOTATKI DO ZORGANIZOWANIA (Skrzynka odbiorcza):
${notesList}

ZADANIE:
Przeanalizuj każdą notatkę i zasugeruj NAJBARDZIEJ odpowiedni notatnik.
Rozważ:
1. Temat/treść notatki (NAJWAŻNIEJSZE)
2. Istniejące etykiety w każdym notatniku
3. Spójność tematyczna między notatkami w tym samym notatniku

PRZEWODNIK KLASYFIKACJI:
- SPORT/ĆWICZENIA/ZAKUPY → Notatnik Osobisty
- HOBBY/PASJE/WYJŚCIA → Notatnik Osobisty
- ZDROWIE/FITNESS/LEKARZ → Notatnik Osobisty lub Zdrowie
- RODZINA/PRZYJACIELE → Notatnik Osobisty
- PRACA/SPOTKANIA/PROJEKTY → Notatnik Praca
- KODOWANIE/TECH/ROZWÓJ → Notatnik Praca lub Kod
- FINANSE/RACHUNKI/BANK → Notatnik Osobisty lub Finanse

FORMAT ODPOWIEDZI (JSON):
Dla każdego notatnika wymień należące do niego notatki:
{
  "carnets": [
    {
      "nom": "Nazwa notatnika",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Krótkie wyjaśnienie po polsku"
        }
      ]
    }
  ]
}

ZASADY:
- Przypisuj tylko notatki z pewnością > 0.60
- Jeśli notatka jest zbyt ogólna, nie przypisuj jej
- Bądź precyzyjny w swoich grupach tematycznych
- Twoja odpowiedź musi być tylko prawidłowym JSON
`.trim(),
      ru: `
Вы помощник, который организует заметки, группируя их по темам в блокноты.

ДОСТУПНЫЕ БЛОКНОТЫ:
${notebookList}

ЗАМЕТКИ ДЛЯ ОРГАНИЗАЦИИ (Входящие):
${notesList}

ЗАДАЧА:
Проанализируйте каждую заметку и предложите САМЫЙ подходящий блокнот.
Учитывайте:
1. Тему/предмет заметки (САМОЕ ВАЖНОЕ)
2. Существующие метки в каждом блокноте
3. Тематическую согласованность между заметками в одном блокноте

РУКОВОДСТВО ПО КЛАССИФИКАЦИИ:
- СПОРТ/УПРАЖНЕНИЯ/ПОКУПКИ → Личный блокнот
- ХОББИ/УВЛЕЧЕНИЯ/ВЫХОДЫ → Личный блокнот
- ЗДОРОВЬЕ/ФИТНЕС/ВРАЧ → Личный блокнот или Здоровье
- СЕМЬЯ/ДРУЗЬЯ → Личный блокнот
- РАБОТА/СОВЕЩАНИЯ/ПРОЕКТЫ → Рабочий блокнот
- КОДИНГ/ТЕХНОЛОГИИ/РАЗРАБОТКА → Рабочий блокнот или Код
- ФИНАНСЫ/СЧЕТА/БАНК → Личный блокнот или Финансы

ФОРМАТ ОТВЕТА (JSON):
Для каждого блокнота перечислите заметки, которые к нему относятся:
{
  "carnets": [
    {
      "nom": "Название блокнота",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "Краткое объяснение на русском"
        }
      ]
    }
  ]
}

ПРАВИЛА:
- Назначайте только заметки с уверенностью > 0.60
- Если заметка слишком общая, не назначайте ее
- Будьте точны в своих тематических группировках
- Ваш ответ должен быть только валидным JSON
`.trim(),
      ja: `
あなたは、テーマごとにノートを分類してノートブックに整理するアシスタントです。

利用可能なノートブック:
${notebookList}

整理するノート (受信トレイ):
${notesList}

タスク:
各ノートを分析し、最も適切なノートブックを提案してください。
考慮事項:
1. ノートの主題/テーマ (最も重要)
2. 各ノートブックの既存のラベル
3. 同じノートブック内のノート間のテーマの一貫性

分類ガイド:
- スポーツ/運動/買い物 → 個人用ノートブック
- 趣味/情熱/外出 → 個人用ノートブック
- 健康/フィットネス/医師 → 個人用ノートブックまたは健康
- 家族/友人 → 個人用ノートブック
- 仕事/会議/プロジェクト → 仕事用ノートブック
- コーディング/技術/開発 → 仕事用ノートブックまたはコード
- 金融/請求書/銀行 → 個人用ノートブックまたは金融

回答形式 (JSON):
各ノートブックについて、それに属するノートをリストアップしてください:
{
  "carnets": [
    {
      "nom": "ノートブック名",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "日本語での短い説明"
        }
      ]
    }
  ]
}

ルール:
- 信頼度が 0.60 を超えるノートのみを割り当ててください
- ノートが一般的すぎる場合は、割り当てないでください
- テーマ別のグループ化において正確であってください
- 回答は有効な JSON のみにしてください
`.trim(),
      ko: `
당신은 주제별로 노트를 분류하여 노트북으로 정리하는 도우미입니다.

사용 가능한 노트북:
${notebookList}

정리할 노트 (받은 편지함):
${notesList}

작업:
각 노트를 분석하고 가장 적절한 노트북을 제안하십시오.
고려 사항:
1. 노트의 주제/테마 (가장 중요)
2. 각 노트북의 기존 라벨
3. 동일한 노트북 내 노트 간의 주제별 일관성

분류 가이드:
- 스포츠/운동/쇼핑 → 개인 노트북
- 취미/열정/외출 → 개인 노트북
- 건강/피트니스/의사 → 개인 노트북 또는 건강
- 가족/친구 → 개인 노트북
- 업무/회의/프로젝트 → 업무 노트북
- 코딩/기술/개발 → 업무 노트북 또는 코드
- 금융/청구서/은행 → 개인 노트북 또는 금융

응답 형식 (JSON):
각 노트북에 대해 속한 노트를 나열하십시오:
{
  "carnets": [
    {
      "nom": "노트북 이름",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "한국어로 된 짧은 설명"
        }
      ]
    }
  ]
}

규칙:
- 신뢰도가 0.60을 초과하는 노트만 할당하십시오
- 노트가 너무 일반적인 경우 할당하지 마십시오
- 주제별 그룹화에서 정확해야 합니다
- 응답은 유효한 JSON이어야 합니다
`.trim(),
      zh: `
你是一个助手，负责通过按主题将笔记分组到笔记本中来整理笔记。

可用笔记本：
${notebookList}

待整理笔记（收件箱）：
${notesList}

任务：
分析每个笔记并建议最合适的笔记本。
考虑：
1. 笔记的主题/题材（最重要）
2. 每个笔记本中的现有标签
3. 同一笔记本中笔记之间的主题一致性

分类指南：
- 运动/锻炼/购物 → 个人笔记本
- 爱好/激情/郊游 → 个人笔记本
- 健康/健身/医生 → 个人笔记本或健康
- 家庭/朋友 → 个人笔记本
- 工作/会议/项目 → 工作笔记本
- 编码/技术/开发 → 工作笔记本或代码
- 金融/账单/银行 → 个人笔记本或金融

响应格式 (JSON):
对于每个笔记本，列出属于它的笔记：
{
  "carnets": [
    {
      "nom": "笔记本名称",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "中文简短说明"
        }
      ]
    }
  ]
}

规则：
- 仅分配置信度 > 0.60 的笔记
- 如果笔记太普通，请勿分配
- 在主题分组中要精确
- 您的响应必须仅为有效的 JSON
`.trim(),
      ar: `
أنت مساعد يقوم بتنظيم الملاحظات عن طريق تجميعها حسب الموضوع في دفاتر ملاحظات.

دفاتر الملاحظات المتاحة:
${notebookList}

ملاحظات للتنظيم (صندوق الوارد):
${notesList}

المهمة:
حلل كل ملاحظة واقترح دفتر الملاحظات الأكثر ملاءمة.
اعتبار:
1. موضوع/مادة الملاحظة (الأهم)
2. التسميات الموجودة في كل دفتر ملاحظات
3. الاتساق الموضوعي بين الملاحظات في نفس دفتر الملاحظات

دليل التصنيف:
- الرياضة/التمرين/التسوق → دفتر ملاحظات شخصي
- الهوايات/الشغف/النزهات → دفتر ملاحظات شخصي
- الصحة/اللياقة البدنية/الطبيب → دفتر ملاحظات شخصي أو صحة
- العائلة/الأصدقاء → دفتر ملاحظات شخصي
- العمل/الاجتماعات/المشاريع → دفتر ملاحظات العمل
- البرمجة/التقنية/التطوير → دفتر ملاحظات العمل أو الكود
- المالية/الفواتير/البنك → دفتر ملاحظات شخصي أو مالية

تنسيق الاستجابة (JSON):
لكل دفتر ملاحظات، ضع قائمة بالملاحظات التي تنتمي إليه:
{
  "carnets": [
    {
      "nom": "اسم دفتر الملاحظات",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "شرح قصير باللغة العربية"
        }
      ]
    }
  ]
}

القواعد:
- عيّن فقط الملاحظات ذات الثقة > 0.60
- إذا كانت الملاحظة عامة جدًا، فلا تقم بتعيينها
- كن دقيقًا في مجموعاتك الموضوعية
- يجب أن تكون إجابتك بتنسيق JSON صالح فقط
`.trim(),
      hi: `
आप एक सहायक हैं जो नोटों को विषय के आधार पर नोटबुक में समूहित करके व्यवस्थित करते हैं।

उपलब्ध नोटबुक:
${notebookList}

व्यवस्थित करने के लिए नोट्स (इनबॉक्स):
${notesList}

कार्य:
प्रत्येक नोट का विश्लेषण करें और सबसे उपयुक्त नोटबुक का सुझाव दें।
विचार करें:
1. नोट का विषय/थीम (सबसे महत्वपूर्ण)
2. प्रत्येक नोटबुक में मौजूदा लेबल
3. एक ही नोटबुक में नोटों के बीच विषयगत स्थिरता

वर्गीकरण गाइड:
- खेल/व्यायाम/खरीदारी → व्यक्तिगत नोटबुक
- शौक/जुनून/बाहर जाना → व्यक्तिगत नोटबुक
- स्वास्थ्य/फिटनेस/डॉक्टर → व्यक्तिगत नोटबुक या स्वास्थ्य
- परिवार/मित्र → व्यक्तिगत नोटबुक
- कार्य/बैठकें/परियोजनाएं → कार्य नोटबुक
- कोडिंग/तकनीक/विकास → कार्य नोटबुक या कोड
- वित्त/बिल/बैंक → व्यक्तिगत नोटबुक या वित्त

प्रतिक्रिया प्रारूप (JSON):
प्रत्येक नोटबुक के लिए, उन नोटों को सूचीबद्ध करें जो उससे संबंधित हैं:
{
  "carnets": [
    {
      "nom": "नोटबुक का नाम",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "हिंदी में संक्षिप्त स्पष्टीकरण"
        }
      ]
    }
  ]
}

नियम:
- केवल > 0.60 आत्मविश्वास वाले नोट्स असाइन करें
- यदि कोई नोट बहुत सामान्य है, तो उसे असाइन न करें
- अपने विषयगत समूहों में सटीक रहें
- आपकी प्रतिक्रिया केवल वैध JSON होनी चाहिए
`.trim(),
      fa: `
شما دستیاری هستید که یادداشت‌ها را با گروه‌بندی موضوعی در دفترچه‌ها سازماندهی می‌کنید.

دفترچه‌های موجود:
${notebookList}

یادداشت‌های برای سازماندهی (صندوق ورودی):
${notesList}

وظیفه:
هر یادداشت را تحلیل کنید و مناسب‌ترین دفترچه را پیشنهاد دهید.
در نظر بگیرید:
1. موضوع/تم یادداشت (مهم‌ترین)
2. برچسب‌های موجود در هر دفترچه
3. سازگاری موضوعی بین یادداشت‌ها در همان دفترچه

راهنمای طبقه‌بندی:
- ورزش/تمرین/خرید → دفترچه شخصی
- سرگرمی‌ها/علایق/گردش → دفترچه شخصی
- سلامت/تناسب اندام/پزشک → دفترچه شخصی یا سلامت
- خانواده/دوستان → دفترچه شخصی
- کار/جلسات/پروژه‌ها → دفترچه کار
- کدنویسی/تکنولوژی/توسعه → دفترچه کار یا کد
- مالی/قبض‌ها/بانک → دفترچه شخصی یا مالی

فرمت پاسخ (JSON):
برای هر دفترچه، یادداشت‌هایی که به آن تعلق دارند را لیست کنید:
{
  "carnets": [
    {
      "nom": "نام دفترچه",
      "notes": [
        {
          "index": 0,
          "confiance": 0.95,
          "raison": "توضیح کوتاه به فارسی"
        }
      ]
    }
  ]
}

قوانین:
- فقط یادداشت‌های با اطمینان > 0.60 را اختصاص دهید
- اگر یادداشتی خیلی کلی است، آن را اختصاص ندهید
- در گروه‌بندی‌های موضوعی خود دقیق باشید
- پاسخ شما باید فقط یک JSON معتبر باشد
`.trim()
    }

    // Return instruction for requested language, fallback to English
    return instructions[language] || instructions['en'] || instructions['fr']
  }

  private normalizeForMatch(str: string): string {
    return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').trim()
  }

  /**
   * Parse AI response into OrganizationPlan
   */
  private parseAIResponse(
    response: string,
    notes: NoteForOrganization[],
    notebooks: any[]
  ): OrganizationPlan {
    try {
      const jsonMatch = response.match(/\{[\s\S]*\}/)
      if (!jsonMatch) {
        throw new Error('No JSON found in response')
      }

      const aiData = JSON.parse(jsonMatch[0])

      const notebookOrganizations: NotebookOrganization[] = []

      for (const aiNotebook of aiData.carnets || []) {
        const aiName = this.normalizeForMatch(aiNotebook.nom || '')
        const notebook = notebooks.find(nb => this.normalizeForMatch(nb.name) === aiName)
          || notebooks.find(nb => this.normalizeForMatch(nb.name).includes(aiName) || aiName.includes(this.normalizeForMatch(nb.name)))
        if (!notebook) continue

        const noteAssignments = aiNotebook.notes
          .filter((n: any) => n.confiance > 0.60) // Only high confidence
          .map((n: any) => {
            const note = notes[n.index]
            if (!note) return null

            return {
              noteId: note.id,
              title: note.title,
              content: note.content,
              confidence: n.confiance,
              reason: n.raison || '',
            }
          })
          .filter(Boolean)

        if (noteAssignments.length > 0) {
          notebookOrganizations.push({
            notebookId: notebook.id,
            notebookName: notebook.name,
            notebookIcon: notebook.icon,
            notebookColor: notebook.color,
            notes: noteAssignments,
          })
        }
      }

      // Count unorganized notes
      const organizedNoteIds = new Set(
        notebookOrganizations.flatMap(nb => nb.notes.map(n => n.noteId))
      )
      const unorganizedCount = notes.length - organizedNoteIds.size

      return {
        notebooks: notebookOrganizations,
        totalNotes: notes.length,
        unorganizedNotes: unorganizedCount,
      }
    } catch (error) {
      console.error('Failed to parse AI response:', error, '\nRaw response:', response.substring(0, 500))
      throw new Error(`AI response parsing failed: ${error instanceof Error ? error.message : 'Invalid JSON'}`)
    }
  }

  /**
   * Apply the organization plan (move notes to notebooks)
   * @param userId - User ID
   * @param plan - Organization plan to apply
   * @param selectedNoteIds - Specific note IDs to organize (user can deselect)
   * @returns Number of notes moved
   */
  async applyOrganizationPlan(
    userId: string,
    plan: OrganizationPlan,
    selectedNoteIds: string[]
  ): Promise<number> {
    let movedCount = 0

    for (const notebookOrg of plan.notebooks) {
      // Filter notes that are selected
      const notesToMove = notebookOrg.notes.filter(n =>
        selectedNoteIds.includes(n.noteId)
      )

      if (notesToMove.length === 0) continue

      // Move notes to notebook
      await prisma.note.updateMany({
        where: {
          id: { in: notesToMove.map(n => n.noteId) },
          userId,
        },
        data: {
          notebookId: notebookOrg.notebookId,
        },
      })

      movedCount += notesToMove.length
    }

    return movedCount
  }
}

// Export singleton instance
export const batchOrganizationService = new BatchOrganizationService()
