import uuid
from datetime import datetime
from sqlalchemy import Column, String, DateTime, Boolean, Float, Integer, ForeignKey, Index
from sqlalchemy.orm import relationship
from utils.utils import Base
from sqlalchemy import Enum as SqlEnum
from .schema import ScheduleStatus, SeatType, SeatStatus


class Schedule(Base):
    __tablename__ = "schedules"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    bus_id = Column(String(36), ForeignKey("buses.id", ondelete="RESTRICT"), nullable=False, index=True)
    route_id = Column(String(36), ForeignKey("routes.id", ondelete="RESTRICT"), nullable=False, index=True)
    departure_datetime = Column(DateTime, nullable=False)
    arrival_datetime = Column(DateTime, nullable=False)
    base_price = Column(Float, nullable=False)
    available_seats = Column(Integer, nullable=False)
    status = Column(SqlEnum(ScheduleStatus, name="schedule_status_enum"), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    bus = relationship("Bus", back_populates="schedules")
    route = relationship("Route", back_populates="schedules")
    seats = relationship("Seat", back_populates="schedule", cascade="all, delete-orphan", passive_deletes=True)
    reservations = relationship("Reservation", back_populates="schedule")
    bookings = relationship("Booking", back_populates="schedule")

    __table_args__ = (
        Index("ix_schedules_departure_datetime", "departure_datetime"),
        Index("ix_schedules_status", "status"),
        Index("ix_schedules_route_departure", "route_id", "departure_datetime"),
    )


class Seat(Base):
    __tablename__ = "seats"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    schedule_id = Column(String(36), ForeignKey("schedules.id", ondelete="CASCADE"), nullable=False, index=True)
    seat_number = Column(String(10), nullable=False)
    seat_type = Column(SqlEnum(SeatType, name="seat_type_enum"), nullable=False)
    price_modifier = Column(Float, nullable=False)
    status = Column(SqlEnum(SeatStatus, name="seat_status_enum"), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    schedule = relationship("Schedule", back_populates="seats")
    reservation_seats = relationship("Reservationseat", back_populates="seat")
    booking_seats = relationship("Bookingseat", back_populates="seat")

    __table_args__ = (
        Index("ix_seats_schedule_status", "schedule_id", "status"),
        Index("ix_seats_schedule_number", "schedule_id", "seat_number"),
    )