from datetime import date
from typing import List, Any
from typing import Optional

from pydantic import BaseModel, Field, ConfigDict, model_validator
from sqlalchemy.orm import joinedload

from core.config import get_db
from models import Participant, User, Course
from schema import GenericResponse


class BursaryDiscountInfo(BaseModel):
    academic_year_id: int
    start_date: date
    end_date: date
    is_enabled: bool = Field(default=False)


class AcademicYear(BaseModel):
    title: str
    model_config = ConfigDict(from_attributes=True)


class BursaryDiscountInstance(BaseModel):
    id: int
    academic_year_id: int
    start_date: date
    end_date: date
    is_enabled: bool = Field(default=False)
    academic_year: AcademicYear
    model_config = ConfigDict(from_attributes=True)


class BursaryDiscountInfoListResponse(GenericResponse):
    data: List[BursaryDiscountInstance]


class BursaryDiscountInfoResponse(BursaryDiscountInstance):
    id: int
    model_config = ConfigDict(from_attributes=True)


class BursaryDiscountInfoUpdateSchema(BursaryDiscountInfo):
    id: int


class CreateBursaryApplication(BaseModel):
    academic_year_id: int
    participant_id: List[int]

class ApplicationParticipant(BaseModel):
    first_name: str
    last_name: str
    email: Optional[str] = None
    id:int
    dob:Optional[date] = None

class ApplicationInstance(BaseModel):
    application_number:str
    id: int
    academic_year_id: int
    participant_id: int
    is_parent_user: bool
    is_fully_allocated: Optional[bool]
    is_approved: Optional[bool] =False
    created_by: int
    academic_year: AcademicYear
    participant: Optional[ApplicationParticipant] = None
    model_config = ConfigDict(from_attributes=True)



class ApplicationListResponse(GenericResponse):
    data: List[ApplicationInstance]




class BursaryCourseAllocationBase(BaseModel):
    course_id: int
    discount_price: float = 0.0

class BursaryCourseAllocationCreate(BaseModel):
    course:List[BursaryCourseAllocationBase]
    bursary_discount_application_id:int
    is_fully_allocated: bool
    @model_validator(mode='after')
    def validate(self):
        with get_db() as db:
            for row in self.course:
                course_instance=db.query(Course).get(row.course_id)
                if not course_instance.is_bursary_product:
                    raise ValueError("Course not a bursary product")

                if course_instance.amount < row.discount_price:
                    raise ValueError(f"Discount amount must be less than or equal to course amount {course_instance.amount}")

        return self



