import uuid
from datetime import datetime
from sqlalchemy import Column, String, DateTime, Float, ForeignKey, Index
from sqlalchemy import Enum as SqlEnum
from sqlalchemy.orm import relationship
from utils.utils import Base
from .schema import ReservationStatus


class Reservation(Base):
    __tablename__ = "reservations"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    user_id = Column(String(36), ForeignKey("users.id", ondelete="RESTRICT"), nullable=False, index=True)
    schedule_id = Column(String(36), ForeignKey("schedules.id", ondelete="RESTRICT"), nullable=False, index=True)
    reservation_datetime = Column(DateTime, nullable=False)
    expiry_datetime = Column(DateTime, nullable=False)
    status = Column(SqlEnum(ReservationStatus, name="reservation_status_enum"), nullable=False)
    total_amount = Column(Float, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    user = relationship("User", back_populates="reservations")
    schedule = relationship("Schedule", back_populates="reservations")
    reservation_seats = relationship("Reservationseat", back_populates="reservation", cascade="all, delete-orphan", passive_deletes=True)
    bookings = relationship("Booking", back_populates="reservation")

    __table_args__ = (
        Index("ix_reservations_status_expiry", "status", "expiry_datetime"),
        Index("ix_reservations_user_schedule", "user_id", "schedule_id"),
    )


class Reservationseat(Base):
    __tablename__ = "reservation_seats"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    reservation_id = Column(String(36), ForeignKey("reservations.id", ondelete="CASCADE"), nullable=False, index=True)
    seat_id = Column(String(36), ForeignKey("seats.id", ondelete="RESTRICT"), nullable=False, index=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    reservation = relationship("Reservation", back_populates="reservation_seats")
    seat = relationship("Seat", back_populates="reservation_seats")

    __table_args__ = (
        Index("ix_reservation_seats_reservation", "reservation_id"),
        Index("ix_reservation_seats_seat", "seat_id"),
    )