from datetime import datetime, timezone

from core.config import get_db
from core.security.exceptions import GenericError
from models import TimeSlot, Course
from schema.time_slot import TimeSlotResponseSchema


class TimeSlotService:

    def create_new_time_slot(self, request):
        payload = request.model_dump()
        with get_db() as db:
            new_slot = TimeSlot(**payload)
            db.add(new_slot)
            db.commit()
            db.refresh(new_slot)
            return new_slot

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

    def fetch_time_slot_details(self, time_slot_id: int):
        with get_db() as db:
            record = db.query(TimeSlot).where(
                TimeSlot.id == time_slot_id,
                TimeSlot.deleted_at.is_(None)
            ).first()

            if not record:
                raise GenericError(status_code=404, exc="Time slot not found")
            return TimeSlotResponseSchema.model_validate(record).model_dump()

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

    def delete_time_slot(self, time_slot_id):
        with get_db() as db:
            if db.query(Course).where(Course.time_slot_id == time_slot_id).count() > 0:
                raise GenericError(status_code=422, exc="Time slot is associated with course. Cannot delete.")
            time_slot = db.query(TimeSlot).where(
                TimeSlot.id == time_slot_id,
                TimeSlot.deleted_at.is_(None)
            ).first()

            if not time_slot:
                raise GenericError(status_code=404, exc="Time slot not found")

            time_slot.deleted_at = datetime.now(timezone.utc)
            db.commit()
            return {"message": "Time slot deleted successfully"}
