"""
PDF Export - Individual Gutachten PDF generation.

Generates a single student's Gutachten with criteria table,
workflow info, and annotation summary.
"""

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

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


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
    _add_gutachten_content(story, styles, student_data)

    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
    _add_criteria_table(story, styles, student_data)

    # Final grade box
    _add_grade_box(story, styles, student_data)

    # Examiner workflow information
    if workflow_data:
        _add_workflow_info(story, styles, workflow_data)

    # Annotation summary
    if annotations:
        _add_annotation_summary(story, styles, annotations)

    # Footer
    _add_footer(story, styles)

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


def _add_gutachten_content(story, styles, student_data):
    """Add gutachten text sections to the story."""
    gutachten = student_data.get('gutachten', {})

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

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

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

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


def _add_criteria_table(story, styles, student_data):
    """Add criteria scoring table to the story."""
    story.append(Paragraph("Bewertung nach Kriterien", styles['SectionHeader']))
    story.append(Spacer(1, 0.2*cm))

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

    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

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

    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([
        ('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'),
        ('FONTSIZE', (0, 1), (-1, -1), 9),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 6),
        ('TOPPADDING', (0, 0), (-1, -1), 6),
        ('GRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#e2e8f0')),
        ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#f7fafc')),
        ('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),
        ('ROWBACKGROUNDS', (0, 1), (-1, -2), [colors.white, colors.HexColor('#f7fafc')]),
    ]))
    story.append(criteria_table)
    story.append(Spacer(1, 0.5*cm))


def _add_grade_box(story, styles, student_data):
    """Add final grade box to the story."""
    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
    ]))


def _add_workflow_info(story, styles, workflow_data):
    """Add examiner workflow information to the story."""
    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)


def _add_annotation_summary(story, styles, annotations):
    """Add annotation summary to the story."""
    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']))

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


def _add_footer(story, styles):
    """Add generation footer to the story."""
    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']
    ))
