-- =========================================================
-- Migration 014: Compliance Training Engine
-- =========================================================
-- Training Module Catalog, Compliance Training Matrix (CTM),
-- Assignments, Quiz Engine, Content Pipeline, Audit Trail
-- =========================================================

-- Training-Module-Katalog (erweiterte Kurs-Metadaten)
CREATE TABLE IF NOT EXISTS training_modules (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    academy_course_id UUID REFERENCES academy_courses(id),
    module_code VARCHAR(20) NOT NULL,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    regulation_area VARCHAR(20) NOT NULL,
    nis2_relevant BOOLEAN DEFAULT FALSE,
    iso_controls JSONB DEFAULT '[]',
    frequency_type VARCHAR(20) NOT NULL DEFAULT 'annual',
    validity_days INT DEFAULT 365,
    risk_weight FLOAT DEFAULT 2.0,
    content_type VARCHAR(20) DEFAULT 'text',
    duration_minutes INT DEFAULT 30,
    pass_threshold INT DEFAULT 70,
    is_active BOOLEAN DEFAULT TRUE,
    sort_order INT DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(tenant_id, module_code)
);

-- Compliance Training Matrix: welche Rollen brauchen welche Module
CREATE TABLE IF NOT EXISTS training_matrix (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    role_code VARCHAR(10) NOT NULL,
    module_id UUID NOT NULL REFERENCES training_modules(id) ON DELETE CASCADE,
    is_mandatory BOOLEAN DEFAULT TRUE,
    priority INT DEFAULT 5,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(tenant_id, role_code, module_id)
);

-- Training-Zuweisungen (automatisch oder manuell)
CREATE TABLE IF NOT EXISTS training_assignments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    module_id UUID NOT NULL REFERENCES training_modules(id) ON DELETE CASCADE,
    user_id UUID NOT NULL,
    user_name VARCHAR(255) NOT NULL,
    user_email VARCHAR(255) NOT NULL,
    role_code VARCHAR(10),
    trigger_type VARCHAR(20) NOT NULL,
    trigger_event VARCHAR(100),
    status VARCHAR(20) DEFAULT 'pending',
    progress_percent INT DEFAULT 0,
    quiz_score FLOAT,
    quiz_passed BOOLEAN,
    quiz_attempts INT DEFAULT 0,
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,
    deadline TIMESTAMPTZ NOT NULL,
    certificate_id UUID,
    escalation_level INT DEFAULT 0,
    last_escalation_at TIMESTAMPTZ,
    enrollment_id UUID REFERENCES academy_enrollments(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Quiz-Fragenbank (persistent, nicht nur JSONB)
CREATE TABLE IF NOT EXISTS training_quiz_questions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    module_id UUID NOT NULL REFERENCES training_modules(id) ON DELETE CASCADE,
    question TEXT NOT NULL,
    options JSONB NOT NULL,
    correct_index INT NOT NULL,
    explanation TEXT,
    difficulty VARCHAR(10) DEFAULT 'medium',
    is_active BOOLEAN DEFAULT TRUE,
    sort_order INT DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Quiz-Versuche (jeder Versuch einzeln getracked)
CREATE TABLE IF NOT EXISTS training_quiz_attempts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    assignment_id UUID NOT NULL REFERENCES training_assignments(id) ON DELETE CASCADE,
    user_id UUID NOT NULL,
    answers JSONB NOT NULL,
    score FLOAT NOT NULL,
    passed BOOLEAN NOT NULL,
    correct_count INT NOT NULL,
    total_count INT NOT NULL,
    duration_seconds INT,
    attempted_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Audit Trail fuer Training-Aktionen
CREATE TABLE IF NOT EXISTS training_audit_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
    user_id UUID,
    action VARCHAR(50) NOT NULL,
    entity_type VARCHAR(30) NOT NULL,
    entity_id UUID,
    details JSONB DEFAULT '{}',
    ip_address VARCHAR(45),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Module-Inhalte (LLM-generiert oder manuell)
CREATE TABLE IF NOT EXISTS training_module_content (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    module_id UUID NOT NULL REFERENCES training_modules(id) ON DELETE CASCADE,
    version INT DEFAULT 1,
    content_format VARCHAR(20) DEFAULT 'markdown',
    content_body TEXT NOT NULL,
    summary TEXT,
    generated_by VARCHAR(50),
    llm_model VARCHAR(100),
    is_published BOOLEAN DEFAULT FALSE,
    reviewed_by UUID,
    reviewed_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- =========================================================
-- INDEXES
-- =========================================================

CREATE INDEX IF NOT EXISTS idx_training_modules_tenant ON training_modules(tenant_id);
CREATE INDEX IF NOT EXISTS idx_training_modules_regulation ON training_modules(tenant_id, regulation_area);
CREATE INDEX IF NOT EXISTS idx_training_matrix_tenant_role ON training_matrix(tenant_id, role_code);
CREATE INDEX IF NOT EXISTS idx_training_matrix_module ON training_matrix(module_id);
CREATE INDEX IF NOT EXISTS idx_training_assignments_tenant ON training_assignments(tenant_id);
CREATE INDEX IF NOT EXISTS idx_training_assignments_user ON training_assignments(tenant_id, user_id);
CREATE INDEX IF NOT EXISTS idx_training_assignments_status ON training_assignments(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_training_assignments_deadline ON training_assignments(deadline)
    WHERE status NOT IN ('completed', 'expired');
CREATE INDEX IF NOT EXISTS idx_training_assignments_overdue ON training_assignments(tenant_id, deadline, status)
    WHERE status IN ('pending', 'in_progress') AND deadline < NOW();
CREATE INDEX IF NOT EXISTS idx_training_quiz_questions_module ON training_quiz_questions(module_id);
CREATE INDEX IF NOT EXISTS idx_training_quiz_attempts_assignment ON training_quiz_attempts(assignment_id);
CREATE INDEX IF NOT EXISTS idx_training_audit_log_tenant ON training_audit_log(tenant_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_training_module_content_module ON training_module_content(module_id, is_published);

-- =========================================================
-- SEED DATA: Template Modules (tenant_id = 00000000-...)
-- =========================================================

DO $$
DECLARE
    t_id UUID := '00000000-0000-0000-0000-000000000000';
    m_gdpr_bas UUID; m_gdpr_adv UUID; m_gdpr_art UUID; m_gdpr_dpia UUID;
    m_nis2_m1 UUID; m_nis2_m2 UUID; m_nis2_m3 UUID; m_nis2_m4 UUID; m_nis2_m5 UUID;
    m_isms_bas UUID; m_isms_int UUID; m_isms_aud UUID;
    m_ai_bas UUID; m_ai_adv UUID; m_ai_risk UUID;
    m_gesch_bas UUID; m_hin_bas UUID;
    m_mail_sec UUID; m_soc_eng UUID; m_phish UUID;
BEGIN
    -- Skip if seed data already exists
    IF EXISTS (SELECT 1 FROM training_modules WHERE tenant_id = t_id LIMIT 1) THEN
        RAISE NOTICE 'Seed data already exists, skipping';
        RETURN;
    END IF;

    -- Insert modules and capture IDs
    INSERT INTO training_modules (id, tenant_id, module_code, title, description, regulation_area, nis2_relevant, frequency_type, validity_days, risk_weight, duration_minutes, pass_threshold, sort_order)
    VALUES
        (gen_random_uuid(), t_id, 'GDPR-BAS', 'DSGVO Grundlagen', 'Grundlegende Datenschutzprinzipien, Rechtsgrundlagen, Verarbeitungsgrundsaetze', 'dsgvo', false, 'annual', 365, 2.0, 30, 70, 1),
        (gen_random_uuid(), t_id, 'GDPR-ADV', 'DSGVO Vertiefung', 'Auftragsverarbeitung, Drittlandtransfer, Datenschutz-Management', 'dsgvo', false, 'annual', 365, 2.5, 45, 70, 2),
        (gen_random_uuid(), t_id, 'GDPR-ART', 'Betroffenenrechte', 'Auskunft, Berichtigung, Loeschung, Einschraenkung, Datenportabilitaet', 'dsgvo', false, 'annual', 365, 2.0, 30, 70, 3),
        (gen_random_uuid(), t_id, 'GDPR-DPIA', 'Datenschutz-Folgenabschaetzung', 'DSFA-Durchfuehrung, Schwellwertanalyse, Risikobewertung', 'dsgvo', false, 'event_trigger', 365, 3.0, 60, 80, 4),
        (gen_random_uuid(), t_id, 'NIS2-M1', 'NIS2 Geschaeftsleitungspflicht', 'Haftung, Schulungspflicht, Risikomanagement-Governance', 'nis2', true, 'annual', 365, 3.0, 45, 80, 5),
        (gen_random_uuid(), t_id, 'NIS2-M2', 'NIS2 Incident Response', 'Meldepflichten, 24h/72h-Fristen, Incident-Response-Plan', 'nis2', true, 'annual', 365, 3.0, 60, 80, 6),
        (gen_random_uuid(), t_id, 'NIS2-M3', 'NIS2 Lieferkettensicherheit', 'Supply-Chain-Risiken, Dienstleisterbewertung, Vertragsklauseln', 'nis2', true, 'annual', 365, 2.5, 45, 70, 7),
        (gen_random_uuid(), t_id, 'NIS2-M4', 'NIS2 BCM', 'Business Continuity, Notfallplanung, Wiederherstellung', 'nis2', true, 'annual', 365, 2.5, 45, 70, 8),
        (gen_random_uuid(), t_id, 'NIS2-M5', 'NIS2 Risikomanagement', 'Risikoanalyse, Massnahmenplanung, Wirksamkeitspruefung', 'nis2', true, 'annual', 365, 3.0, 60, 80, 9),
        (gen_random_uuid(), t_id, 'ISMS-BAS', 'ISMS Grundlagen', 'ISO 27001 Anforderungen, PDCA-Zyklus, Informationssicherheitspolitik', 'iso27001', false, 'annual', 365, 2.0, 30, 70, 10),
        (gen_random_uuid(), t_id, 'ISMS-INT', 'ISMS Interne Audits', 'Audit-Planung, Durchfuehrung, Berichterstattung, Massnahmenverfolgung', 'iso27001', false, 'annual', 365, 2.5, 45, 70, 11),
        (gen_random_uuid(), t_id, 'ISMS-AUD', 'ISMS Audit-Vorbereitung', 'Zertifizierungsaudit, Dokumentation, Nachweisfuehrung', 'iso27001', false, 'event_trigger', 365, 2.5, 60, 70, 12),
        (gen_random_uuid(), t_id, 'AI-BAS', 'KI-Kompetenz Grundlagen', 'EU AI Act Ueberblick, KI-Risikokategorien, Transparenzpflichten', 'ai_act', false, 'annual', 365, 2.0, 30, 70, 13),
        (gen_random_uuid(), t_id, 'AI-ADV', 'KI-Risikomanagement', 'Hochrisiko-KI, Konformitaetsbewertung, Dokumentationspflichten', 'ai_act', false, 'annual', 365, 2.5, 45, 70, 14),
        (gen_random_uuid(), t_id, 'AI-RISK', 'Hochrisiko-KI-Systeme', 'Risikomanagementsystem, Qualitaet der Trainingsdaten, Human Oversight', 'ai_act', false, 'event_trigger', 365, 3.0, 60, 80, 15),
        (gen_random_uuid(), t_id, 'GESCH-BAS', 'Geschaeftsgeheimnisschutz', 'GeschGehG, Schutzkonzept, NDAs, technische Massnahmen', 'geschgehg', false, 'annual', 365, 2.0, 30, 70, 16),
        (gen_random_uuid(), t_id, 'HIN-BAS', 'Hinweisgeberschutz', 'HinSchG, Meldekanal, Vertraulichkeit, Repressalienverbot', 'hinschg', false, 'annual', 365, 2.0, 30, 70, 17),
        (gen_random_uuid(), t_id, 'MAIL-SEC', 'E-Mail-Sicherheit', 'Phishing, Spam, Verschluesselung, Sichere Kommunikation', 'iso27001', false, 'micro', 180, 1.5, 15, 70, 18),
        (gen_random_uuid(), t_id, 'SOC-ENG', 'Social Engineering Abwehr', 'Manipulationstechniken, Pretexting, Baiting, Tailgating', 'iso27001', false, 'micro', 180, 1.5, 15, 70, 19),
        (gen_random_uuid(), t_id, 'PHISH', 'Phishing-Erkennung', 'Phishing-Merkmale, Pruefschritte, Meldeprozess', 'iso27001', false, 'micro', 180, 1.5, 10, 70, 20);

    -- Get module IDs for CTM
    SELECT id INTO m_gdpr_bas FROM training_modules WHERE tenant_id = t_id AND module_code = 'GDPR-BAS';
    SELECT id INTO m_gdpr_adv FROM training_modules WHERE tenant_id = t_id AND module_code = 'GDPR-ADV';
    SELECT id INTO m_gdpr_art FROM training_modules WHERE tenant_id = t_id AND module_code = 'GDPR-ART';
    SELECT id INTO m_gdpr_dpia FROM training_modules WHERE tenant_id = t_id AND module_code = 'GDPR-DPIA';
    SELECT id INTO m_nis2_m1 FROM training_modules WHERE tenant_id = t_id AND module_code = 'NIS2-M1';
    SELECT id INTO m_nis2_m2 FROM training_modules WHERE tenant_id = t_id AND module_code = 'NIS2-M2';
    SELECT id INTO m_nis2_m3 FROM training_modules WHERE tenant_id = t_id AND module_code = 'NIS2-M3';
    SELECT id INTO m_nis2_m4 FROM training_modules WHERE tenant_id = t_id AND module_code = 'NIS2-M4';
    SELECT id INTO m_nis2_m5 FROM training_modules WHERE tenant_id = t_id AND module_code = 'NIS2-M5';
    SELECT id INTO m_isms_bas FROM training_modules WHERE tenant_id = t_id AND module_code = 'ISMS-BAS';
    SELECT id INTO m_isms_int FROM training_modules WHERE tenant_id = t_id AND module_code = 'ISMS-INT';
    SELECT id INTO m_isms_aud FROM training_modules WHERE tenant_id = t_id AND module_code = 'ISMS-AUD';
    SELECT id INTO m_ai_bas FROM training_modules WHERE tenant_id = t_id AND module_code = 'AI-BAS';
    SELECT id INTO m_ai_adv FROM training_modules WHERE tenant_id = t_id AND module_code = 'AI-ADV';
    SELECT id INTO m_ai_risk FROM training_modules WHERE tenant_id = t_id AND module_code = 'AI-RISK';
    SELECT id INTO m_gesch_bas FROM training_modules WHERE tenant_id = t_id AND module_code = 'GESCH-BAS';
    SELECT id INTO m_hin_bas FROM training_modules WHERE tenant_id = t_id AND module_code = 'HIN-BAS';
    SELECT id INTO m_mail_sec FROM training_modules WHERE tenant_id = t_id AND module_code = 'MAIL-SEC';
    SELECT id INTO m_soc_eng FROM training_modules WHERE tenant_id = t_id AND module_code = 'SOC-ENG';
    SELECT id INTO m_phish FROM training_modules WHERE tenant_id = t_id AND module_code = 'PHISH';

    -- CTM: R1 Geschaeftsfuehrung
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R1', m_gdpr_bas, true, 1), (t_id, 'R1', m_nis2_m1, true, 1),
        (t_id, 'R1', m_nis2_m5, true, 2), (t_id, 'R1', m_isms_bas, true, 2),
        (t_id, 'R1', m_ai_bas, true, 3), (t_id, 'R1', m_gesch_bas, true, 3);

    -- CTM: R2 IT-Leitung
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R2', m_nis2_m2, true, 1), (t_id, 'R2', m_nis2_m5, true, 1),
        (t_id, 'R2', m_isms_bas, true, 2), (t_id, 'R2', m_isms_int, true, 2),
        (t_id, 'R2', m_mail_sec, true, 3), (t_id, 'R2', m_soc_eng, true, 3),
        (t_id, 'R2', m_phish, true, 3);

    -- CTM: R3 DSB
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R3', m_gdpr_bas, true, 1), (t_id, 'R3', m_gdpr_adv, true, 1),
        (t_id, 'R3', m_gdpr_art, true, 1), (t_id, 'R3', m_gdpr_dpia, true, 2),
        (t_id, 'R3', m_isms_bas, true, 3);

    -- CTM: R4 ISB
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R4', m_nis2_m2, true, 1), (t_id, 'R4', m_nis2_m3, true, 1),
        (t_id, 'R4', m_nis2_m4, true, 1), (t_id, 'R4', m_nis2_m5, true, 1),
        (t_id, 'R4', m_isms_bas, true, 2), (t_id, 'R4', m_isms_int, true, 2),
        (t_id, 'R4', m_isms_aud, true, 2);

    -- CTM: R5 HR
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R5', m_gdpr_bas, true, 1), (t_id, 'R5', m_gdpr_art, true, 1),
        (t_id, 'R5', m_hin_bas, true, 2);

    -- CTM: R6 Einkauf
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R6', m_gdpr_bas, true, 1), (t_id, 'R6', m_nis2_m3, true, 1),
        (t_id, 'R6', m_gesch_bas, true, 2);

    -- CTM: R7 Fachabteilung
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R7', m_gdpr_bas, true, 1), (t_id, 'R7', m_ai_bas, true, 2),
        (t_id, 'R7', m_mail_sec, true, 3), (t_id, 'R7', m_soc_eng, true, 3);

    -- CTM: R8 IT-Admin
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R8', m_nis2_m2, true, 1), (t_id, 'R8', m_nis2_m5, true, 1),
        (t_id, 'R8', m_isms_bas, true, 2), (t_id, 'R8', m_mail_sec, true, 3),
        (t_id, 'R8', m_soc_eng, true, 3), (t_id, 'R8', m_phish, true, 3);

    -- CTM: R9 Alle Mitarbeiter
    INSERT INTO training_matrix (tenant_id, role_code, module_id, is_mandatory, priority) VALUES
        (t_id, 'R9', m_gdpr_bas, true, 1), (t_id, 'R9', m_mail_sec, true, 2),
        (t_id, 'R9', m_soc_eng, true, 2), (t_id, 'R9', m_phish, true, 2);

    RAISE NOTICE 'Training Engine seed data inserted successfully';
END $$;
