"""
PDF Export Module for Abiturkorrektur System

Generates:
- Individual Gutachten PDFs for each student
- Klausur overview PDFs with grade distribution
- Niedersachsen-compliant formatting
"""

import io
from datetime import datetime
from typing import Dict, List, Optional, Any

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY, TA_RIGHT
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, Image, KeepTogether
)
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont


# =============================================
# CONSTANTS
# =============================================

GRADE_POINTS_TO_NOTE = {
    15: "1+", 14: "1", 13: "1-",
    12: "2+", 11: "2", 10: "2-",
    9: "3+", 8: "3", 7: "3-",
    6: "4+", 5: "4", 4: "4-",
    3: "5+", 2: "5", 1: "5-",
    0: "6"
}

CRITERIA_DISPLAY_NAMES = {
    "rechtschreibung": "Sprachliche Richtigkeit (Rechtschreibung)",
    "grammatik": "Sprachliche Richtigkeit (Grammatik)",
    "inhalt": "Inhaltliche Leistung",
    "struktur": "Aufbau und Struktur",
    "stil": "Ausdruck und Stil"
}

CRITERIA_WEIGHTS = {
    "rechtschreibung": 15,
    "grammatik": 15,
    "inhalt": 40,
    "struktur": 15,
    "stil": 15
}


# =============================================
# STYLES
# =============================================

def get_custom_styles():
    """Create custom paragraph styles for Gutachten."""
    styles = getSampleStyleSheet()

    # Title style
    styles.add(ParagraphStyle(
        name='GutachtenTitle',
        parent=styles['Heading1'],
        fontSize=16,
        spaceAfter=12,
        alignment=TA_CENTER,
        textColor=colors.HexColor('#1e3a5f')
    ))

    # Subtitle style
    styles.add(ParagraphStyle(
        name='GutachtenSubtitle',
        parent=styles['Heading2'],
        fontSize=12,
        spaceAfter=8,
        spaceBefore=16,
        textColor=colors.HexColor('#2c5282')
    ))

    # Section header
    styles.add(ParagraphStyle(
        name='SectionHeader',
        parent=styles['Heading3'],
        fontSize=11,
        spaceAfter=6,
        spaceBefore=12,
        textColor=colors.HexColor('#2d3748'),
        borderColor=colors.HexColor('#e2e8f0'),
        borderWidth=0,
        borderPadding=0
    ))

    # Body text
    styles.add(ParagraphStyle(
        name='GutachtenBody',
        parent=styles['Normal'],
        fontSize=10,
        leading=14,
        alignment=TA_JUSTIFY,
        spaceAfter=6
    ))

    # Small text for footer/meta
    styles.add(ParagraphStyle(
        name='MetaText',
        parent=styles['Normal'],
        fontSize=8,
        textColor=colors.grey,
        alignment=TA_LEFT
    ))

    # List item
    styles.add(ParagraphStyle(
        name='ListItem',
        parent=styles['Normal'],
        fontSize=10,
        leftIndent=20,
        bulletIndent=10,
        spaceAfter=4
    ))

    return styles


# =============================================
# PDF GENERATION FUNCTIONS
# =============================================

def generate_gutachten_pdf(
    student_data: Dict[str, Any],
    klausur_data: Dict[str, Any],
    annotations: List[Dict[str, Any]] = None,
    workflow_data: Dict[str, Any] = None
) -> bytes:
    """
    Generate a PDF Gutachten for a single student.

    Args:
        student_data: Student work data including criteria_scores, gutachten, grade_points
        klausur_data: Klausur metadata (title, subject, year, etc.)
        annotations: List of annotations for annotation summary
        workflow_data: Examiner workflow data (EK, ZK, DK info)

    Returns:
        PDF as bytes
    """
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(
        buffer,
        pagesize=A4,
        rightMargin=2*cm,
        leftMargin=2*cm,
        topMargin=2*cm,
        bottomMargin=2*cm
    )

    styles = get_custom_styles()
    story = []

    # Header
    story.append(Paragraph("Gutachten zur Abiturklausur", styles['GutachtenTitle']))
    story.append(Paragraph(f"{klausur_data.get('subject', 'Deutsch')} - {klausur_data.get('title', '')}", styles['GutachtenSubtitle']))
    story.append(Spacer(1, 0.5*cm))

    # Meta information table
    meta_data = [
        ["Pruefling:", student_data.get('student_name', 'Anonym')],
        ["Schuljahr:", f"{klausur_data.get('year', 2025)}"],
        ["Kurs:", klausur_data.get('semester', 'Abitur')],
        ["Datum:", datetime.now().strftime("%d.%m.%Y")]
    ]

    meta_table = Table(meta_data, colWidths=[4*cm, 10*cm])
    meta_table.setStyle(TableStyle([
        ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 10),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 4),
        ('TOPPADDING', (0, 0), (-1, -1), 4),
    ]))
    story.append(meta_table)
    story.append(Spacer(1, 0.5*cm))
    story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor('#e2e8f0')))
    story.append(Spacer(1, 0.5*cm))

    # Gutachten content
    gutachten = student_data.get('gutachten', {})

    if gutachten:
        # Einleitung
        if gutachten.get('einleitung'):
            story.append(Paragraph("Einleitung", styles['SectionHeader']))
            story.append(Paragraph(gutachten['einleitung'], styles['GutachtenBody']))
            story.append(Spacer(1, 0.3*cm))

        # Hauptteil
        if gutachten.get('hauptteil'):
            story.append(Paragraph("Hauptteil", styles['SectionHeader']))
            story.append(Paragraph(gutachten['hauptteil'], styles['GutachtenBody']))
            story.append(Spacer(1, 0.3*cm))

        # Fazit
        if gutachten.get('fazit'):
            story.append(Paragraph("Fazit", styles['SectionHeader']))
            story.append(Paragraph(gutachten['fazit'], styles['GutachtenBody']))
            story.append(Spacer(1, 0.3*cm))

        # Staerken und Schwaechen
        if gutachten.get('staerken') or gutachten.get('schwaechen'):
            story.append(Spacer(1, 0.3*cm))

            if gutachten.get('staerken'):
                story.append(Paragraph("Staerken:", styles['SectionHeader']))
                for s in gutachten['staerken']:
                    story.append(Paragraph(f"• {s}", styles['ListItem']))

            if gutachten.get('schwaechen'):
                story.append(Paragraph("Verbesserungspotenzial:", styles['SectionHeader']))
                for s in gutachten['schwaechen']:
                    story.append(Paragraph(f"• {s}", styles['ListItem']))
    else:
        story.append(Paragraph("<i>Kein Gutachten-Text vorhanden.</i>", styles['GutachtenBody']))

    story.append(Spacer(1, 0.5*cm))
    story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor('#e2e8f0')))
    story.append(Spacer(1, 0.5*cm))

    # Bewertungstabelle
    story.append(Paragraph("Bewertung nach Kriterien", styles['SectionHeader']))
    story.append(Spacer(1, 0.2*cm))

    criteria_scores = student_data.get('criteria_scores', {})

    # Build criteria table data
    table_data = [["Kriterium", "Gewichtung", "Erreicht", "Punkte"]]
    total_weighted = 0
    total_weight = 0

    for key, display_name in CRITERIA_DISPLAY_NAMES.items():
        weight = CRITERIA_WEIGHTS.get(key, 0)
        score_data = criteria_scores.get(key, {})
        score = score_data.get('score', 0) if isinstance(score_data, dict) else score_data

        # Calculate weighted contribution
        weighted_score = (score / 100) * weight if score else 0
        total_weighted += weighted_score
        total_weight += weight

        table_data.append([
            display_name,
            f"{weight}%",
            f"{score}%",
            f"{weighted_score:.1f}"
        ])

    # Add total row
    table_data.append([
        "Gesamt",
        f"{total_weight}%",
        "",
        f"{total_weighted:.1f}"
    ])

    criteria_table = Table(table_data, colWidths=[8*cm, 2.5*cm, 2.5*cm, 2.5*cm])
    criteria_table.setStyle(TableStyle([
        # Header row
        ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#2c5282')),
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, 0), 10),
        ('ALIGN', (1, 0), (-1, -1), 'CENTER'),
        # Body rows
        ('FONTSIZE', (0, 1), (-1, -1), 9),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 6),
        ('TOPPADDING', (0, 0), (-1, -1), 6),
        # Grid
        ('GRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#e2e8f0')),
        # Total row
        ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#f7fafc')),
        ('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),
        # Alternating row colors
        ('ROWBACKGROUNDS', (0, 1), (-1, -2), [colors.white, colors.HexColor('#f7fafc')]),
    ]))
    story.append(criteria_table)

    story.append(Spacer(1, 0.5*cm))

    # Final grade box
    grade_points = student_data.get('grade_points', 0)
    grade_note = GRADE_POINTS_TO_NOTE.get(grade_points, "?")
    raw_points = student_data.get('raw_points', 0)

    grade_data = [
        ["Rohpunkte:", f"{raw_points} / 100"],
        ["Notenpunkte:", f"{grade_points} Punkte"],
        ["Note:", grade_note]
    ]

    grade_table = Table(grade_data, colWidths=[4*cm, 4*cm])
    grade_table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#ebf8ff')),
        ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
        ('FONTNAME', (1, -1), (1, -1), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 11),
        ('FONTSIZE', (1, -1), (1, -1), 14),
        ('TEXTCOLOR', (1, -1), (1, -1), colors.HexColor('#2c5282')),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
        ('TOPPADDING', (0, 0), (-1, -1), 8),
        ('LEFTPADDING', (0, 0), (-1, -1), 12),
        ('BOX', (0, 0), (-1, -1), 1, colors.HexColor('#2c5282')),
        ('ALIGN', (1, 0), (1, -1), 'RIGHT'),
    ]))

    story.append(KeepTogether([
        Paragraph("Endergebnis", styles['SectionHeader']),
        Spacer(1, 0.2*cm),
        grade_table
    ]))

    # Examiner workflow information
    if workflow_data:
        story.append(Spacer(1, 0.5*cm))
        story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor('#e2e8f0')))
        story.append(Spacer(1, 0.3*cm))
        story.append(Paragraph("Korrekturverlauf", styles['SectionHeader']))

        workflow_rows = []

        if workflow_data.get('erst_korrektor'):
            ek = workflow_data['erst_korrektor']
            workflow_rows.append([
                "Erstkorrektor:",
                ek.get('name', 'Unbekannt'),
                f"{ek.get('grade_points', '-')} Punkte"
            ])

        if workflow_data.get('zweit_korrektor'):
            zk = workflow_data['zweit_korrektor']
            workflow_rows.append([
                "Zweitkorrektor:",
                zk.get('name', 'Unbekannt'),
                f"{zk.get('grade_points', '-')} Punkte"
            ])

        if workflow_data.get('dritt_korrektor'):
            dk = workflow_data['dritt_korrektor']
            workflow_rows.append([
                "Drittkorrektor:",
                dk.get('name', 'Unbekannt'),
                f"{dk.get('grade_points', '-')} Punkte"
            ])

        if workflow_data.get('final_grade_source'):
            workflow_rows.append([
                "Endnote durch:",
                workflow_data['final_grade_source'],
                ""
            ])

        if workflow_rows:
            workflow_table = Table(workflow_rows, colWidths=[4*cm, 6*cm, 4*cm])
            workflow_table.setStyle(TableStyle([
                ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
                ('FONTSIZE', (0, 0), (-1, -1), 9),
                ('BOTTOMPADDING', (0, 0), (-1, -1), 4),
                ('TOPPADDING', (0, 0), (-1, -1), 4),
            ]))
            story.append(workflow_table)

    # Annotation summary (if any)
    if annotations:
        story.append(Spacer(1, 0.5*cm))
        story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor('#e2e8f0')))
        story.append(Spacer(1, 0.3*cm))
        story.append(Paragraph("Anmerkungen (Zusammenfassung)", styles['SectionHeader']))

        # Group annotations by type
        by_type = {}
        for ann in annotations:
            ann_type = ann.get('type', 'comment')
            if ann_type not in by_type:
                by_type[ann_type] = []
            by_type[ann_type].append(ann)

        for ann_type, anns in by_type.items():
            type_name = CRITERIA_DISPLAY_NAMES.get(ann_type, ann_type.replace('_', ' ').title())
            story.append(Paragraph(f"{type_name} ({len(anns)} Anmerkungen)", styles['ListItem']))

    # Footer with generation info
    story.append(Spacer(1, 1*cm))
    story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#cbd5e0')))
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph(
        f"Erstellt am {datetime.now().strftime('%d.%m.%Y um %H:%M Uhr')} | BreakPilot Abiturkorrektur-System",
        styles['MetaText']
    ))

    # Build PDF
    doc.build(story)
    buffer.seek(0)
    return buffer.getvalue()


def generate_klausur_overview_pdf(
    klausur_data: Dict[str, Any],
    students: List[Dict[str, Any]],
    fairness_data: Optional[Dict[str, Any]] = None
) -> bytes:
    """
    Generate an overview PDF for an entire Klausur with all student grades.

    Args:
        klausur_data: Klausur metadata
        students: List of all student work data
        fairness_data: Optional fairness analysis data

    Returns:
        PDF as bytes
    """
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(
        buffer,
        pagesize=A4,
        rightMargin=1.5*cm,
        leftMargin=1.5*cm,
        topMargin=2*cm,
        bottomMargin=2*cm
    )

    styles = get_custom_styles()
    story = []

    # Header
    story.append(Paragraph("Notenuebersicht", styles['GutachtenTitle']))
    story.append(Paragraph(f"{klausur_data.get('subject', 'Deutsch')} - {klausur_data.get('title', '')}", styles['GutachtenSubtitle']))
    story.append(Spacer(1, 0.5*cm))

    # Meta information
    meta_data = [
        ["Schuljahr:", f"{klausur_data.get('year', 2025)}"],
        ["Kurs:", klausur_data.get('semester', 'Abitur')],
        ["Anzahl Arbeiten:", str(len(students))],
        ["Stand:", datetime.now().strftime("%d.%m.%Y")]
    ]

    meta_table = Table(meta_data, colWidths=[4*cm, 10*cm])
    meta_table.setStyle(TableStyle([
        ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 10),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 4),
        ('TOPPADDING', (0, 0), (-1, -1), 4),
    ]))
    story.append(meta_table)
    story.append(Spacer(1, 0.5*cm))

    # Statistics (if fairness data available)
    if fairness_data and fairness_data.get('statistics'):
        stats = fairness_data['statistics']
        story.append(Paragraph("Statistik", styles['SectionHeader']))

        stats_data = [
            ["Durchschnitt:", f"{stats.get('average_grade', 0):.1f} Punkte"],
            ["Minimum:", f"{stats.get('min_grade', 0)} Punkte"],
            ["Maximum:", f"{stats.get('max_grade', 0)} Punkte"],
            ["Standardabweichung:", f"{stats.get('standard_deviation', 0):.2f}"],
        ]

        stats_table = Table(stats_data, colWidths=[4*cm, 4*cm])
        stats_table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, -1), 9),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 4),
            ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#f7fafc')),
            ('BOX', (0, 0), (-1, -1), 0.5, colors.HexColor('#e2e8f0')),
        ]))
        story.append(stats_table)
        story.append(Spacer(1, 0.5*cm))

    story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor('#e2e8f0')))
    story.append(Spacer(1, 0.5*cm))

    # Student grades table
    story.append(Paragraph("Einzelergebnisse", styles['SectionHeader']))
    story.append(Spacer(1, 0.2*cm))

    # Sort students by grade (descending)
    sorted_students = sorted(students, key=lambda s: s.get('grade_points', 0), reverse=True)

    # Build table header
    table_data = [["#", "Name", "Rohpunkte", "Notenpunkte", "Note", "Status"]]

    for idx, student in enumerate(sorted_students, 1):
        grade_points = student.get('grade_points', 0)
        grade_note = GRADE_POINTS_TO_NOTE.get(grade_points, "-")
        raw_points = student.get('raw_points', 0)
        status = student.get('status', 'unknown')

        # Format status
        status_display = {
            'completed': 'Abgeschlossen',
            'first_examiner': 'In Korrektur',
            'second_examiner': 'Zweitkorrektur',
            'uploaded': 'Hochgeladen',
            'ocr_complete': 'OCR fertig',
            'analyzing': 'Wird analysiert'
        }.get(status, status)

        table_data.append([
            str(idx),
            student.get('student_name', 'Anonym'),
            f"{raw_points}/100",
            str(grade_points),
            grade_note,
            status_display
        ])

    # Create table
    student_table = Table(table_data, colWidths=[1*cm, 5*cm, 2.5*cm, 3*cm, 2*cm, 3*cm])
    student_table.setStyle(TableStyle([
        # Header
        ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#2c5282')),
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, 0), 9),
        ('ALIGN', (0, 0), (-1, 0), 'CENTER'),
        # Body
        ('FONTSIZE', (0, 1), (-1, -1), 9),
        ('ALIGN', (0, 1), (0, -1), 'CENTER'),
        ('ALIGN', (2, 1), (4, -1), 'CENTER'),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 6),
        ('TOPPADDING', (0, 0), (-1, -1), 6),
        # Grid
        ('GRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#e2e8f0')),
        # Alternating rows
        ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#f7fafc')]),
    ]))
    story.append(student_table)

    # Grade distribution
    story.append(Spacer(1, 0.5*cm))
    story.append(Paragraph("Notenverteilung", styles['SectionHeader']))
    story.append(Spacer(1, 0.2*cm))

    # Count grades
    grade_counts = {}
    for student in sorted_students:
        gp = student.get('grade_points', 0)
        grade_counts[gp] = grade_counts.get(gp, 0) + 1

    # Build grade distribution table
    dist_data = [["Punkte", "Note", "Anzahl"]]
    for points in range(15, -1, -1):
        if points in grade_counts:
            note = GRADE_POINTS_TO_NOTE.get(points, "-")
            count = grade_counts[points]
            dist_data.append([str(points), note, str(count)])

    if len(dist_data) > 1:
        dist_table = Table(dist_data, colWidths=[2.5*cm, 2.5*cm, 2.5*cm])
        dist_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#2c5282')),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, -1), 9),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 4),
            ('TOPPADDING', (0, 0), (-1, -1), 4),
            ('GRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#e2e8f0')),
        ]))
        story.append(dist_table)

    # Footer
    story.append(Spacer(1, 1*cm))
    story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#cbd5e0')))
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph(
        f"Erstellt am {datetime.now().strftime('%d.%m.%Y um %H:%M Uhr')} | BreakPilot Abiturkorrektur-System",
        styles['MetaText']
    ))

    # Build PDF
    doc.build(story)
    buffer.seek(0)
    return buffer.getvalue()


def generate_annotations_pdf(
    student_data: Dict[str, Any],
    klausur_data: Dict[str, Any],
    annotations: List[Dict[str, Any]]
) -> bytes:
    """
    Generate a PDF with all annotations for a student work.

    Args:
        student_data: Student work data
        klausur_data: Klausur metadata
        annotations: List of all annotations

    Returns:
        PDF as bytes
    """
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(
        buffer,
        pagesize=A4,
        rightMargin=2*cm,
        leftMargin=2*cm,
        topMargin=2*cm,
        bottomMargin=2*cm
    )

    styles = get_custom_styles()
    story = []

    # Header
    story.append(Paragraph("Anmerkungen zur Klausur", styles['GutachtenTitle']))
    story.append(Paragraph(f"{student_data.get('student_name', 'Anonym')}", styles['GutachtenSubtitle']))
    story.append(Spacer(1, 0.5*cm))

    if not annotations:
        story.append(Paragraph("<i>Keine Anmerkungen vorhanden.</i>", styles['GutachtenBody']))
    else:
        # Group by type
        by_type = {}
        for ann in annotations:
            ann_type = ann.get('type', 'comment')
            if ann_type not in by_type:
                by_type[ann_type] = []
            by_type[ann_type].append(ann)

        for ann_type, anns in by_type.items():
            type_name = CRITERIA_DISPLAY_NAMES.get(ann_type, ann_type.replace('_', ' ').title())
            story.append(Paragraph(f"{type_name} ({len(anns)})", styles['SectionHeader']))
            story.append(Spacer(1, 0.2*cm))

            # Sort by page then position
            sorted_anns = sorted(anns, key=lambda a: (a.get('page', 0), a.get('position', {}).get('y', 0)))

            for idx, ann in enumerate(sorted_anns, 1):
                page = ann.get('page', 1)
                text = ann.get('text', '')
                suggestion = ann.get('suggestion', '')
                severity = ann.get('severity', 'minor')

                # Build annotation text
                ann_text = f"<b>[S.{page}]</b> {text}"
                if suggestion:
                    ann_text += f" → <i>{suggestion}</i>"

                # Color code by severity
                if severity == 'critical':
                    ann_text = f"<font color='red'>{ann_text}</font>"
                elif severity == 'major':
                    ann_text = f"<font color='orange'>{ann_text}</font>"

                story.append(Paragraph(f"{idx}. {ann_text}", styles['ListItem']))

            story.append(Spacer(1, 0.3*cm))

    # Footer
    story.append(Spacer(1, 1*cm))
    story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#cbd5e0')))
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph(
        f"Erstellt am {datetime.now().strftime('%d.%m.%Y um %H:%M Uhr')} | BreakPilot Abiturkorrektur-System",
        styles['MetaText']
    ))

    # Build PDF
    doc.build(story)
    buffer.seek(0)
    return buffer.getvalue()
