#!/usr/bin/env node
/**
 * Script zum Erstellen von öffentlichen Sprachkursen für verschiedene Sprachen
 * 
 * Verwendung:
 * node backend/scripts/create-language-courses.js
 * 
 * Erstellt öffentliche Kurse für alle Kombinationen von:
 * - Zielsprachen: Bisaya, Französisch, Spanisch, Latein, Italienisch, Portugiesisch, Tagalog
 * - Muttersprachen: Deutsch, Englisch, Spanisch, Französisch, Italienisch, Portugiesisch
 * 
 * Die Kurse werden automatisch einem System-Benutzer zugeordnet und sind öffentlich zugänglich.
 */

import { sequelize } from '../utils/sequelize.js';
import VocabCourse from '../models/community/vocab_course.js';
import VocabCourseLesson from '../models/community/vocab_course_lesson.js';
import VocabGrammarExercise from '../models/community/vocab_grammar_exercise.js';
import User from '../models/community/user.js';
import crypto from 'crypto';
import bcrypt from 'bcryptjs';

// Kursstruktur für alle Sprachen (4 Wochen, 40 Lektionen)
const LESSON_TEMPLATE = [
  // WOCHE 1: Grundlagen & Aussprache
  { week: 1, day: 1, num: 1, type: 'conversation', title: 'Begrüßungen & Höflichkeit', 
    desc: 'Lerne die wichtigsten Begrüßungen und Höflichkeitsformeln', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Höflichkeit ist wichtig. Lächeln hilft!' },
  
  { week: 1, day: 1, num: 2, type: 'vocab', title: 'Überlebenssätze - Teil 1', 
    desc: 'Die 10 wichtigsten Sätze für den Alltag', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: 'Diese Sätze helfen dir sofort im Alltag weiter.' },
  
  { week: 1, day: 2, num: 3, type: 'vocab', title: 'Familienwörter', 
    desc: 'Mama, Papa, Geschwister, Großeltern und mehr', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: 'Familienwörter sind wichtig für echte Gespräche.' },
  
  { week: 1, day: 2, num: 4, type: 'conversation', title: 'Familien-Gespräche', 
    desc: 'Einfache Gespräche mit Familienmitgliedern', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Familienkonversationen sind herzlicher als formelle Gespräche.' },
  
  { week: 1, day: 3, num: 5, type: 'conversation', title: 'Gefühle & Zuneigung', 
    desc: 'Wie man Gefühle ausdrückt', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Gefühle auszudrücken ist wichtig für echte Verbindung.' },
  
  { week: 1, day: 3, num: 6, type: 'vocab', title: 'Überlebenssätze - Teil 2', 
    desc: 'Weitere wichtige Alltagssätze', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 1, day: 4, num: 7, type: 'conversation', title: 'Essen & Fürsorge', 
    desc: 'Gespräche rund ums Essen', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Essen verbindet Menschen überall auf der Welt.' },
  
  { week: 1, day: 4, num: 8, type: 'vocab', title: 'Essen & Trinken', 
    desc: 'Wichtige Wörter rund ums Essen', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 1, day: 5, num: 9, type: 'review', title: 'Woche 1 - Wiederholung', 
    desc: 'Wiederhole alle Inhalte der ersten Woche', 
    targetMin: 30, targetScore: 80, review: false,
    cultural: 'Wiederholung ist der Schlüssel zum Erfolg!' },
  
  { week: 1, day: 5, num: 10, type: 'vocab', title: 'Woche 1 - Vokabeltest', 
    desc: 'Teste dein Wissen aus Woche 1', 
    targetMin: 15, targetScore: 80, review: true,
    cultural: null },

  // WOCHE 2: Alltag & Familie
  { week: 2, day: 1, num: 11, type: 'conversation', title: 'Alltagsgespräche - Teil 1', 
    desc: 'Wie war dein Tag? Was machst du?', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Alltagsgespräche sind wichtig für echte Kommunikation.' },
  
  { week: 2, day: 1, num: 12, type: 'vocab', title: 'Haus & Familie', 
    desc: 'Wörter für Haus, Zimmer, Familie', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 2, day: 2, num: 13, type: 'conversation', title: 'Alltagsgespräche - Teil 2', 
    desc: 'Wohin gehst du? Was machst du heute?', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: null },
  
  { week: 2, day: 2, num: 14, type: 'vocab', title: 'Ort & Richtung', 
    desc: 'Wo, hier, dort, gehen zu', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 2, day: 3, num: 15, type: 'grammar', title: 'Zeitformen - Grundlagen', 
    desc: 'Vergangenheit, Gegenwart, Zukunft', 
    targetMin: 25, targetScore: 75, review: true,
    cultural: 'Zeitformen sind wichtig für präzise Kommunikation.' },
  
  { week: 2, day: 3, num: 16, type: 'vocab', title: 'Zeit & Datum', 
    desc: 'Jetzt, morgen, gestern, heute', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 2, day: 4, num: 17, type: 'conversation', title: 'Einkaufen & Preise', 
    desc: 'Wie viel kostet das? Kann es billiger sein?', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Einkaufen ist eine wichtige Alltagssituation.' },
  
  { week: 2, day: 4, num: 18, type: 'vocab', title: 'Zahlen & Preise', 
    desc: 'Zahlen 1-100, Preise, Mengen', 
    targetMin: 25, targetScore: 85, review: true,
    cultural: null },
  
  { week: 2, day: 5, num: 19, type: 'review', title: 'Woche 2 - Wiederholung', 
    desc: 'Wiederhole alle Inhalte der zweiten Woche', 
    targetMin: 30, targetScore: 80, review: false,
    cultural: null },
  
  { week: 2, day: 5, num: 20, type: 'vocab', title: 'Woche 2 - Vokabeltest', 
    desc: 'Teste dein Wissen aus Woche 2', 
    targetMin: 15, targetScore: 80, review: true,
    cultural: null },

  // WOCHE 3: Vertiefung
  { week: 3, day: 1, num: 21, type: 'conversation', title: 'Gefühle & Emotionen', 
    desc: 'Wie man verschiedene Gefühle ausdrückt', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Emotionen auszudrücken ist wichtig für echte Verbindung.' },
  
  { week: 3, day: 1, num: 22, type: 'vocab', title: 'Gefühle & Emotionen', 
    desc: 'Wörter für verschiedene Gefühle', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 3, day: 2, num: 23, type: 'conversation', title: 'Gesundheit & Wohlbefinden', 
    desc: 'Gespräche über Gesundheit', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: null },
  
  { week: 3, day: 2, num: 24, type: 'vocab', title: 'Körper & Gesundheit', 
    desc: 'Wörter rund um den Körper und Gesundheit', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 3, day: 3, num: 25, type: 'grammar', title: 'Höflichkeitsformen', 
    desc: 'Wie man höflich spricht', 
    targetMin: 20, targetScore: 75, review: true,
    cultural: 'Höflichkeit ist extrem wichtig in jeder Kultur.' },
  
  { week: 3, day: 3, num: 26, type: 'conversation', title: 'Bitten & Fragen', 
    desc: 'Wie man höflich fragt und bittet', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: null },
  
  { week: 3, day: 4, num: 27, type: 'conversation', title: 'Kinder & Familie', 
    desc: 'Gespräche mit und über Kinder', 
    targetMin: 15, targetScore: 80, review: false,
    cultural: 'Kinder sind sehr wichtig in Familien.' },
  
  { week: 3, day: 4, num: 28, type: 'vocab', title: 'Kinder & Spiel', 
    desc: 'Wörter für Kinder und Spielsachen', 
    targetMin: 20, targetScore: 85, review: true,
    cultural: null },
  
  { week: 3, day: 5, num: 29, type: 'review', title: 'Woche 3 - Wiederholung', 
    desc: 'Wiederhole alle Inhalte der dritten Woche', 
    targetMin: 30, targetScore: 80, review: false,
    cultural: null },
  
  { week: 3, day: 5, num: 30, type: 'vocab', title: 'Woche 3 - Vokabeltest', 
    desc: 'Teste dein Wissen aus Woche 3', 
    targetMin: 15, targetScore: 80, review: true,
    cultural: null },

  // WOCHE 4: Freies Sprechen
  { week: 4, day: 1, num: 31, type: 'conversation', title: 'Freies Gespräch - Thema 1', 
    desc: 'Übe freies Sprechen zu verschiedenen Themen', 
    targetMin: 20, targetScore: 75, review: false,
    cultural: 'Fehler sind okay! Muttersprachler schätzen das Bemühen.' },
  
  { week: 4, day: 1, num: 32, type: 'vocab', title: 'Wiederholung - Woche 1 & 2', 
    desc: 'Wiederhole wichtige Vokabeln aus den ersten beiden Wochen', 
    targetMin: 25, targetScore: 85, review: true,
    cultural: null },
  
  { week: 4, day: 2, num: 33, type: 'conversation', title: 'Freies Gespräch - Thema 2', 
    desc: 'Weitere Übung im freien Sprechen', 
    targetMin: 20, targetScore: 75, review: false,
    cultural: null },
  
  { week: 4, day: 2, num: 34, type: 'vocab', title: 'Wiederholung - Woche 3', 
    desc: 'Wiederhole wichtige Vokabeln aus Woche 3', 
    targetMin: 25, targetScore: 85, review: true,
    cultural: null },
  
  { week: 4, day: 3, num: 35, type: 'conversation', title: 'Komplexere Gespräche', 
    desc: 'Längere Gespräche zu verschiedenen Themen', 
    targetMin: 25, targetScore: 75, review: false,
    cultural: 'Je mehr du sprichst, desto besser wirst du!' },
  
  { week: 4, day: 3, num: 36, type: 'review', title: 'Gesamtwiederholung', 
    desc: 'Wiederhole alle wichtigen Inhalte des Kurses', 
    targetMin: 30, targetScore: 80, review: false,
    cultural: null },
  
  { week: 4, day: 4, num: 37, type: 'conversation', title: 'Praktische Übung', 
    desc: 'Simuliere echte Gesprächssituationen', 
    targetMin: 25, targetScore: 75, review: false,
    cultural: null },
  
  { week: 4, day: 4, num: 38, type: 'vocab', title: 'Abschlusstest - Vokabeln', 
    desc: 'Finaler Vokabeltest über den gesamten Kurs', 
    targetMin: 20, targetScore: 80, review: true,
    cultural: null },
  
  { week: 4, day: 5, num: 39, type: 'review', title: 'Abschlussprüfung', 
    desc: 'Finale Prüfung über alle Kursinhalte', 
    targetMin: 30, targetScore: 80, review: false,
    cultural: 'Gratulation zum Abschluss des Kurses!' },
  
  { week: 4, day: 5, num: 40, type: 'culture', title: 'Kulturelle Tipps & Tricks', 
    desc: 'Wichtige kulturelle Hinweise für den Alltag', 
    targetMin: 15, targetScore: 0, review: false,
    cultural: 'Kulturelles Verständnis ist genauso wichtig wie die Sprache selbst.' }
];

// Zielsprachen (die zu lernenden Sprachen)
const TARGET_LANGUAGES = [
  'Bisaya',
  'Französisch',
  'Spanisch',
  'Latein',
  'Italienisch',
  'Portugiesisch',
  'Tagalog'
];

// Muttersprachen (für die Kurse erstellt werden)
const NATIVE_LANGUAGES = [
  'Deutsch',
  'Englisch',
  'Spanisch',
  'Französisch',
  'Italienisch',
  'Portugiesisch'
];

// Generiere Kurskonfigurationen für alle Kombinationen
function generateCourseConfigs() {
  const configs = [];
  
  for (const targetLang of TARGET_LANGUAGES) {
    for (const nativeLang of NATIVE_LANGUAGES) {
      // Überspringe, wenn Zielsprache = Muttersprache
      if (targetLang === nativeLang) continue;
      
      const title = `${targetLang} für ${nativeLang}sprachige - Schnellstart in 4 Wochen`;
      let description = `Lerne ${targetLang} schnell und praktisch für den Alltag. `;
      
      if (targetLang === 'Latein') {
        description = `Lerne ${targetLang} systematisch mit Fokus auf Grammatik und Vokabular. `;
      } else if (targetLang === 'Bisaya') {
        description = `Lerne ${targetLang} (Cebuano) schnell und praktisch für den Familienalltag. `;
      }
      
      description += `Fokus auf Sprechen & Hören mit strukturiertem 4-Wochen-Plan.`;
      
      configs.push({
        targetLanguageName: targetLang,
        nativeLanguageName: nativeLang,
        title,
        description,
        difficultyLevel: 1
      });
    }
  }
  
  return configs;
}

const LANGUAGE_COURSES = generateCourseConfigs();

async function findOrCreateLanguage(languageName, ownerUserId) {
  // Suche zuerst nach vorhandener Sprache
  const [existing] = await sequelize.query(
    `SELECT id FROM community.vocab_language WHERE name = :name LIMIT 1`,
    {
      replacements: { name: languageName },
      type: sequelize.QueryTypes.SELECT
    }
  );

  if (existing) {
    console.log(`   ✅ Sprache "${languageName}" bereits vorhanden (ID: ${existing.id})`);
    return existing.id;
  }

  // Erstelle neue Sprache
  const shareCode = crypto.randomBytes(8).toString('hex');
  const [created] = await sequelize.query(
    `INSERT INTO community.vocab_language (owner_user_id, name, share_code) 
     VALUES (:ownerUserId, :name, :shareCode) 
     RETURNING id`,
    {
      replacements: { ownerUserId, name: languageName, shareCode },
      type: sequelize.QueryTypes.SELECT
    }
  );

  console.log(`   ✅ Sprache "${languageName}" erstellt (ID: ${created.id})`);
  return created.id;
}

async function createCourseForLanguage(targetLanguageId, nativeLanguageId, languageConfig, ownerUserId) {
  const shareCode = crypto.randomBytes(8).toString('hex');
  
  const course = await VocabCourse.create({
    ownerUserId,
    title: languageConfig.title,
    description: languageConfig.description,
    languageId: Number(targetLanguageId),
    nativeLanguageId: nativeLanguageId ? Number(nativeLanguageId) : null,
    difficultyLevel: languageConfig.difficultyLevel || 1,
    isPublic: true,
    shareCode
  });

  console.log(`   ✅ Kurs erstellt: "${course.title}" (ID: ${course.id}, Share-Code: ${shareCode})`);

  // Erstelle Lektionen
  const createdLessons = [];
  for (const lessonData of LESSON_TEMPLATE) {
    const lesson = await VocabCourseLesson.create({
      courseId: course.id,
      chapterId: null,
      lessonNumber: lessonData.num,
      title: lessonData.title,
      description: lessonData.desc,
      weekNumber: lessonData.week,
      dayNumber: lessonData.day,
      lessonType: lessonData.type,
      culturalNotes: lessonData.cultural,
      targetMinutes: lessonData.targetMin,
      targetScorePercent: lessonData.targetScore,
      requiresReview: lessonData.review
    });
    createdLessons.push({ lesson, lessonData });
  }

  console.log(`   ✅ ${LESSON_TEMPLATE.length} Lektionen erstellt`);

  // Erstelle Beispiel-Grammatik-Übungen für Grammar-Lektionen
  let grammarExerciseCount = 0;
  for (const { lesson, lessonData } of createdLessons) {
    if (lessonData.type === 'grammar') {
      // Erstelle 2-3 Beispiel-Übungen für jede Grammar-Lektion
      const exercises = createExampleGrammarExercises(lesson.id, lessonData, ownerUserId);
      for (const exercise of exercises) {
        await VocabGrammarExercise.create(exercise);
        grammarExerciseCount++;
      }
    }
  }

  if (grammarExerciseCount > 0) {
    console.log(`   ✅ ${grammarExerciseCount} Grammatik-Übungen erstellt`);
  }

  return course;
}

// Erstelle Beispiel-Grammatik-Übungen für eine Grammar-Lektion
function createExampleGrammarExercises(lessonId, lessonData, ownerUserId) {
  const exercises = [];
  
  // Beispiel-Übung 1: Gap Fill (Lückentext)
  exercises.push({
    lessonId: lessonId,
    exerciseTypeId: 1, // gap_fill
    exerciseNumber: 1,
    title: `${lessonData.title} - Übung 1`,
    instruction: 'Fülle die Lücken mit den richtigen Wörtern.',
    questionData: JSON.stringify({
      type: 'gap_fill',
      text: 'Hallo! Wie geht es {gap}? Mir geht es {gap}, danke!',
      gaps: 2
    }),
    answerData: JSON.stringify({
      type: 'gap_fill',
      answers: ['dir', 'gut']
    }),
    explanation: 'Die richtigen Antworten sind "dir" und "gut".',
    createdByUserId: ownerUserId
  });

  // Beispiel-Übung 2: Multiple Choice
  exercises.push({
    lessonId: lessonId,
    exerciseTypeId: 2, // multiple_choice
    exerciseNumber: 2,
    title: `${lessonData.title} - Übung 2`,
    instruction: 'Wähle die richtige Antwort aus.',
    questionData: JSON.stringify({
      type: 'multiple_choice',
      question: 'Wie sagt man "Guten Tag" auf ' + lessonData.title.split(' - ')[0] + '?',
      options: ['Option A', 'Option B', 'Option C', 'Option D']
    }),
    answerData: JSON.stringify({
      type: 'multiple_choice',
      correctAnswer: 0
    }),
    explanation: 'Die richtige Antwort ist Option A.',
    createdByUserId: ownerUserId
  });

  return exercises;
}

async function findOrCreateSystemUser() {
  // Versuche zuerst einen System-Benutzer zu finden (z.B. mit username "system" oder "admin")
  let systemUser = await User.findOne({ 
    where: { 
      username: 'system' 
    } 
  });

  if (!systemUser) {
    // Versuche Admin-Benutzer
    systemUser = await User.findOne({ 
      where: { 
        username: 'admin' 
      } 
    });
  }

  if (!systemUser) {
    // Erstelle einen System-Benutzer
    console.log('   ℹ️  Erstelle System-Benutzer für öffentliche Kurse...');
    const saltRounds = 10;
    const randomPassword = crypto.randomBytes(32).toString('hex');
    const hashedPassword = await bcrypt.hash(randomPassword, saltRounds);
    
    systemUser = await User.create({
      username: 'system',
      email: 'system@your-part.de',
      password: hashedPassword,
      active: true,
      registrationDate: new Date()
    });
    
    // hashedId wird automatisch vom Hook gesetzt, aber warte kurz darauf
    await systemUser.reload();
    console.log(`   ✅ System-Benutzer erstellt (ID: ${systemUser.id}, hashedId: ${systemUser.hashedId})`);
  } else {
    console.log(`   ✅ System-Benutzer gefunden (ID: ${systemUser.id}, Username: ${systemUser.username})`);
  }

  return systemUser;
}

async function createAllLanguageCourses() {
  try {
    // Finde oder erstelle System-Benutzer
    const systemUser = await findOrCreateSystemUser();

    console.log(`\n🚀 Erstelle öffentliche Sprachkurse (Besitzer: System-Benutzer ID ${systemUser.id})\n`);

    const createdCourses = [];

    // Stelle sicher, dass alle benötigten Sprachen existieren
    console.log(`\n🌍 Stelle sicher, dass alle Sprachen existieren...`);
    const allLanguages = [...new Set([...TARGET_LANGUAGES, ...NATIVE_LANGUAGES])];
    const languageMap = new Map();
    
    for (const langName of allLanguages) {
      const langId = await findOrCreateLanguage(langName, systemUser.id);
      languageMap.set(langName, langId);
    }

    for (const langConfig of LANGUAGE_COURSES) {
      console.log(`\n📚 Verarbeite: ${langConfig.targetLanguageName} für ${langConfig.nativeLanguageName}sprachige`);
      
      const targetLanguageId = languageMap.get(langConfig.targetLanguageName);
      const nativeLanguageId = languageMap.get(langConfig.nativeLanguageName);
      
      // Prüfe, ob Kurs bereits existiert (unabhängig vom Besitzer, wenn öffentlich)
      const existingCourse = await VocabCourse.findOne({
        where: {
          languageId: targetLanguageId,
          nativeLanguageId: nativeLanguageId,
          isPublic: true
        }
      });

      if (existingCourse) {
        console.log(`   ⚠️  Kurs "${langConfig.title}" existiert bereits (ID: ${existingCourse.id})`);
        createdCourses.push({ 
          ...langConfig, 
          courseId: existingCourse.id, 
          targetLanguageId, 
          nativeLanguageId, 
          skipped: true 
        });
        continue;
      }

      // Erstelle Kurs
      const course = await createCourseForLanguage(targetLanguageId, nativeLanguageId, langConfig, systemUser.id);
      createdCourses.push({ 
        ...langConfig, 
        courseId: course.id, 
        targetLanguageId, 
        nativeLanguageId, 
        shareCode: course.shareCode 
      });
    }

    console.log(`\n\n🎉 Zusammenfassung:\n`);
    console.log(`   Gesamt: ${LANGUAGE_COURSES.length} Sprachen`);
    console.log(`   Erstellt: ${createdCourses.filter(c => !c.skipped).length} Kurse`);
    console.log(`   Übersprungen: ${createdCourses.filter(c => c.skipped).length} Kurse`);
    
    console.log(`\n📋 Erstellte Kurse:\n`);
    for (const course of createdCourses) {
      if (course.skipped) {
        console.log(`   ⚠️  ${course.languageName}: Bereits vorhanden (ID: ${course.courseId})`);
      } else {
        console.log(`   ✅ ${course.languageName}: ${course.title}`);
        console.log(`      Share-Code: ${course.shareCode}`);
      }
    }

    console.log(`\n💡 Nächste Schritte:`);
    console.log(`   1. Füge Vokabeln zu den Vokabel-Lektionen hinzu`);
    console.log(`   2. Erstelle Grammatik-Übungen für die Grammatik-Lektionen`);
    console.log(`   3. Teile die Kurse mit anderen (Share-Codes oben)`);

    return createdCourses;
  } catch (error) {
    console.error('❌ Fehler beim Erstellen der Kurse:', error);
    throw error;
  }
}

// CLI-Aufruf
// Keine Parameter mehr nötig - verwendet automatisch System-Benutzer
createAllLanguageCourses()
  .then(() => {
    process.exit(0);
  })
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });
