from datetime import datetime, timezone

from core.config import get_db
from core.security.exceptions import CoreDBError, GenericError
from models import AgeGroup, Course
from schema.age_group import AgeGroupResponse


class AgeGroupService:

    def save(self, request):
        with get_db() as db:
            payload = request.model_dump()
            try:
                new_age_group = AgeGroup(**payload)
                db.add(new_age_group)
                db.commit()
                db.refresh(new_age_group)
                return new_age_group
            except Exception as e:
                db.rollback()
                raise CoreDBError(f"Could not create new age group: {e}")

    def fetch_all_age_group(self):
        with get_db() as db:
            records = db.query(AgeGroup).where(AgeGroup.deleted_at.is_(None)).all()
            return [AgeGroupResponse.model_validate(record).model_dump() for record in records]

    def fetch_an_age_group(self, age_group_id: int):
        with get_db() as db:
            record = db.query(AgeGroup).where(
                AgeGroup.id == age_group_id,
                AgeGroup.deleted_at.is_(None)
            ).first()

            if not record:
                raise GenericError(status_code=404, exc="Age group not found")
            return AgeGroupResponse.model_validate(record).model_dump()

    def update_age_group(self, age_group_id, request):
        payload = request.model_dump(exclude=['id'])
        with get_db() as db:
            result = (
                db.query(AgeGroup)
                .filter(AgeGroup.id == age_group_id, AgeGroup.deleted_at.is_(None))
                .update(payload, synchronize_session="fetch")
            )
            db.commit()
            if result == 0:
                raise GenericError(status_code=422, exc="Could not update age group")

    def delete_age_group(self, age_group_id):

        with get_db() as db:
            if db.query(Course).where(Course.age_group_id == age_group_id).count() > 0:
                raise GenericError(status_code=422, exc="Age group is associated with course. Cannot delete.")
            age_group = db.query(AgeGroup).where(
                AgeGroup.id == age_group_id,
                AgeGroup.deleted_at.is_(None)
            ).first()

            if not age_group:
                # If no matching age group is found, raise an error
                raise GenericError(status_code=404, exc="age group not found")

            age_group.deleted_at = datetime.now(timezone.utc)
            db.commit()
            return {"message": "Age group deleted successfully"}
