"""
PDF Export - Klausur overview and annotations PDF generation.

Generates:
- Klausur overview with grade distribution for all students
- Annotations PDF for a single student
"""

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.units import cm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable
)

from .pdf_export_styles import (
    GRADE_POINTS_TO_NOTE,
    CRITERIA_DISPLAY_NAMES,
    get_custom_styles,
)


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'):
        _add_statistics(story, styles, fairness_data['statistics'])

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

    # Student grades table
    sorted_students = sorted(students, key=lambda s: s.get('grade_points', 0), reverse=True)
    _add_student_table(story, styles, sorted_students)

    # Grade distribution
    _add_grade_distribution(story, styles, sorted_students)

    # 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 _add_statistics(story, styles, stats):
    """Add statistics section."""
    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))


def _add_student_table(story, styles, sorted_students):
    """Add student grades table."""
    story.append(Paragraph("Einzelergebnisse", styles['SectionHeader']))
    story.append(Spacer(1, 0.2*cm))

    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')

        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
        ])

    student_table = Table(table_data, colWidths=[1*cm, 5*cm, 2.5*cm, 3*cm, 2*cm, 3*cm])
    student_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, 0), 9),
        ('ALIGN', (0, 0), (-1, 0), 'CENTER'),
        ('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', (0, 0), (-1, -1), 0.5, colors.HexColor('#e2e8f0')),
        ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#f7fafc')]),
    ]))
    story.append(student_table)


def _add_grade_distribution(story, styles, sorted_students):
    """Add grade distribution table."""
    story.append(Spacer(1, 0.5*cm))
    story.append(Paragraph("Notenverteilung", styles['SectionHeader']))
    story.append(Spacer(1, 0.2*cm))

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

    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)


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))

            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')

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

                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()
