"""
Certificates Models - Pydantic models and enums for Zeugnisverwaltung.
"""
from datetime import datetime
from typing import Optional, List, Dict
from enum import Enum

from pydantic import BaseModel, Field


# =============================================================================
# Enums
# =============================================================================

class CertificateType(str, Enum):
    """Typen von Zeugnissen."""
    HALBJAHR = "halbjahr"
    JAHRES = "jahres"
    ABSCHLUSS = "abschluss"
    ABGANG = "abgang"
    UEBERGANG = "uebergang"


class CertificateStatus(str, Enum):
    """Status eines Zeugnisses."""
    DRAFT = "draft"
    REVIEW = "review"
    APPROVED = "approved"
    ISSUED = "issued"
    ARCHIVED = "archived"


class GradeType(str, Enum):
    """Notentyp."""
    NUMERIC = "numeric"
    POINTS = "points"
    TEXT = "text"


class BehaviorGrade(str, Enum):
    """Verhaltens-/Arbeitsnoten."""
    A = "A"
    B = "B"
    C = "C"
    D = "D"


# =============================================================================
# Pydantic Models
# =============================================================================

class SchoolInfoModel(BaseModel):
    """Schulinformationen fuer Zeugnis."""
    name: str
    address: str
    phone: str
    email: str
    website: Optional[str] = None
    principal: Optional[str] = None
    logo_path: Optional[str] = None


class SubjectGrade(BaseModel):
    """Note fuer ein Fach."""
    name: str = Field(..., description="Fachname")
    grade: str = Field(..., description="Note (1-6 oder A-D)")
    points: Optional[int] = Field(None, description="Punkte (Oberstufe, 0-15)")
    note: Optional[str] = Field(None, description="Bemerkung zum Fach")


class AttendanceInfo(BaseModel):
    """Anwesenheitsinformationen."""
    days_absent: int = Field(0, description="Fehlende Tage gesamt")
    days_excused: int = Field(0, description="Entschuldigte Tage")
    days_unexcused: int = Field(0, description="Unentschuldigte Tage")
    hours_absent: Optional[int] = Field(None, description="Fehlstunden gesamt")


class CertificateCreateRequest(BaseModel):
    """Request zum Erstellen eines neuen Zeugnisses."""
    student_id: str = Field(..., description="ID des Schuelers")
    student_name: str = Field(..., description="Name des Schuelers")
    student_birthdate: str = Field(..., description="Geburtsdatum")
    student_class: str = Field(..., description="Klasse")
    school_year: str = Field(..., description="Schuljahr (z.B. '2024/2025')")
    certificate_type: CertificateType = Field(..., description="Art des Zeugnisses")
    subjects: List[SubjectGrade] = Field(..., description="Fachnoten")
    attendance: AttendanceInfo = Field(default_factory=AttendanceInfo)
    remarks: Optional[str] = Field(None, description="Bemerkungen")
    class_teacher: str = Field(..., description="Klassenlehrer/in")
    principal: str = Field(..., description="Schulleiter/in")
    school_info: Optional[SchoolInfoModel] = Field(None)
    issue_date: Optional[str] = Field(None, description="Ausstellungsdatum")
    social_behavior: Optional[BehaviorGrade] = Field(None)
    work_behavior: Optional[BehaviorGrade] = Field(None)


class CertificateUpdateRequest(BaseModel):
    """Request zum Aktualisieren eines Zeugnisses."""
    subjects: Optional[List[SubjectGrade]] = None
    attendance: Optional[AttendanceInfo] = None
    remarks: Optional[str] = None
    class_teacher: Optional[str] = None
    principal: Optional[str] = None
    social_behavior: Optional[BehaviorGrade] = None
    work_behavior: Optional[BehaviorGrade] = None
    status: Optional[CertificateStatus] = None


class CertificateResponse(BaseModel):
    """Response mit Zeugnisdaten."""
    id: str
    student_id: str
    student_name: str
    student_birthdate: str
    student_class: str
    school_year: str
    certificate_type: CertificateType
    subjects: List[SubjectGrade]
    attendance: AttendanceInfo
    remarks: Optional[str]
    class_teacher: str
    principal: str
    school_info: Optional[SchoolInfoModel]
    issue_date: Optional[str]
    social_behavior: Optional[BehaviorGrade]
    work_behavior: Optional[BehaviorGrade]
    status: CertificateStatus
    average_grade: Optional[float]
    pdf_path: Optional[str]
    dsms_cid: Optional[str]
    created_at: datetime
    updated_at: datetime


class CertificateListResponse(BaseModel):
    """Response mit Liste von Zeugnissen."""
    certificates: List[CertificateResponse]
    total: int
    page: int
    page_size: int


class GradeStatistics(BaseModel):
    """Notenstatistiken fuer eine Klasse."""
    class_name: str
    school_year: str
    certificate_type: CertificateType
    student_count: int
    average_grade: float
    grade_distribution: Dict[str, int]
    subject_averages: Dict[str, float]


# =============================================================================
# Helper Functions
# =============================================================================

def get_type_label(cert_type: CertificateType) -> str:
    """Gibt menschenlesbare Labels fuer Zeugnistypen zurueck."""
    labels = {
        CertificateType.HALBJAHR: "Halbjahreszeugnis",
        CertificateType.JAHRES: "Jahreszeugnis",
        CertificateType.ABSCHLUSS: "Abschlusszeugnis",
        CertificateType.ABGANG: "Abgangszeugnis",
        CertificateType.UEBERGANG: "Uebergangszeugnis",
    }
    return labels.get(cert_type, cert_type.value)


def calculate_average(subjects: List[Dict]) -> Optional[float]:
    """Berechnet Notendurchschnitt."""
    numeric_grades = []
    for subject in subjects:
        grade = subject.get("grade", "")
        try:
            numeric = float(grade)
            if 1 <= numeric <= 6:
                numeric_grades.append(numeric)
        except (ValueError, TypeError):
            pass
    if numeric_grades:
        return round(sum(numeric_grades) / len(numeric_grades), 2)
    return None
