from datetime import date, datetime
from typing import Optional

from pydantic import BaseModel, EmailStr, Field

from app.models.application import ApplicationStatus


class ApplicationCreate(BaseModel):
    # Personal Information
    firstName: str = Field(..., min_length=1, max_length=100)
    lastName: str = Field(..., min_length=1, max_length=100)
    middleName: Optional[str] = Field(None, max_length=100)
    email: EmailStr
    phone: str = Field(..., min_length=10, max_length=20)
    dateOfBirth: Optional[date] = None
    gender: Optional[str] = None
    stateOfOrigin: str = Field(..., min_length=1, max_length=100)
    lga: str = Field(..., min_length=1, max_length=100)
    
    # NIN Verification
    nin: Optional[str] = Field(None, min_length=11, max_length=11)
    ninVerified: Optional[bool] = False
    
    # WAEC/NECO Results
    waecNumber: Optional[str] = None
    waecYear: Optional[str] = None
    waecVerified: Optional[bool] = False
    waecVerificationPending: Optional[bool] = False
    
    # JAMB Information (optional)
    jambRegNumber: Optional[str] = None
    jambScore: Optional[int] = None
    jambYear: Optional[str] = None
    
    # Programme Selection
    programme: str = Field(..., min_length=1)
    
    # Additional Information
    currentOccupation: Optional[str] = None
    employer: Optional[str] = None
    address: Optional[str] = None
    parentGuardianName: Optional[str] = None
    parentGuardianPhone: Optional[str] = None

    # Waitlist ref: when user applies via invitation link /apply?ref={waitlist_id}
    waitlistRef: Optional[str] = None


class ApplicationResponse(BaseModel):
    id: str = Field(alias="id")
    applicationId: str = Field(alias="application_id")
    firstName: str = Field(alias="first_name")
    lastName: str = Field(alias="last_name")
    middleName: Optional[str] = Field(None, alias="middle_name")
    email: str
    phone: str
    dateOfBirth: Optional[date] = Field(None, alias="date_of_birth")
    gender: Optional[str] = None
    stateOfOrigin: str = Field(alias="state_of_origin")
    lga: str
    nin: Optional[str] = None
    ninVerified: bool = Field(alias="nin_verified")
    waecNumber: Optional[str] = Field(None, alias="waec_number")
    waecYear: Optional[str] = Field(None, alias="waec_year")
    waecVerified: bool = Field(alias="waec_verified")
    waecVerificationPending: bool = Field(alias="waec_verification_pending")
    jambRegNumber: Optional[str] = Field(None, alias="jamb_reg_number")
    jambScore: Optional[str] = Field(None, alias="jamb_score")
    jambYear: Optional[str] = Field(None, alias="jamb_year")
    programme: str
    currentOccupation: Optional[str] = Field(None, alias="current_occupation")
    employer: Optional[str] = None
    address: Optional[str] = None
    parentGuardianName: Optional[str] = Field(None, alias="parent_guardian_name")
    parentGuardianPhone: Optional[str] = Field(None, alias="parent_guardian_phone")
    status: ApplicationStatus
    rejectionNote: Optional[str] = Field(None, alias="rejection_note")
    rejectionDate: Optional[datetime] = Field(None, alias="rejection_date")
    matricNumber: Optional[str] = Field(None, alias="matric_number")
    admissionDate: Optional[datetime] = Field(None, alias="admission_date")
    dateApplied: datetime = Field(alias="date_applied")
    submittedAt: datetime = Field(alias="submitted_at")
    updatedAt: datetime = Field(alias="updated_at")

    model_config = {"from_attributes": True, "populate_by_name": True}


class ApplicationUpdate(BaseModel):
    status: ApplicationStatus
    rejectionNote: Optional[str] = None
    matricNumber: Optional[str] = None


class ApplicationStats(BaseModel):
    total: int
    pending: int
    approved: int
    rejected: int
