"""
Waitlist model for managing booking requests when hotel is full.
"""
import enum
from sqlalchemy import Column, Integer, String, Date, Enum, ForeignKey, Text, Boolean
from sqlalchemy.orm import relationship

from app.models.base import BaseModel


class WaitlistStatus(str, enum.Enum):
    """Waitlist entry status."""
    PENDING = "pending"  # En attente
    CONTACTED = "contacted"  # Client contacté
    CONVERTED = "converted"  # Converti en réservation
    CANCELLED = "cancelled"  # Annulé
    EXPIRED = "expired"  # Expiré


class WaitlistPriority(str, enum.Enum):
    """Priority levels for waitlist entries."""
    LOW = "low"
    NORMAL = "normal"
    HIGH = "high"
    VIP = "vip"


class Waitlist(BaseModel):
    """
    Waitlist for managing booking requests when rooms are unavailable.

    When a client requests dates that are fully booked, they can be added
    to the waitlist. Staff can then contact them if rooms become available.

    Attributes:
        establishment_id: Associated establishment
        client_id: Associated client (optional if walk-in request)
        check_in_date: Requested check-in date
        check_out_date: Requested check-out date
        room_type_id: Requested room type (optional)
        adults: Number of adults
        children: Number of children
        priority: Priority level
        status: Current status
        notes: Staff notes
        contact_name: Contact name (if no client_id)
        contact_email: Contact email
        contact_phone: Contact phone
        contacted_at: When client was contacted
        contacted_by_id: User who contacted the client
        converted_reservation_id: Created reservation if converted
    """
    __tablename__ = "waitlist"

    establishment_id = Column(Integer, ForeignKey("establishments.id", ondelete="CASCADE"), nullable=False, index=True)
    client_id = Column(Integer, ForeignKey("clients.id", ondelete="SET NULL"), nullable=True, index=True)

    # Stay details
    check_in_date = Column(Date, nullable=False, index=True)
    check_out_date = Column(Date, nullable=False, index=True)
    room_type_id = Column(Integer, ForeignKey("room_types.id", ondelete="SET NULL"), nullable=True)
    adults = Column(Integer, default=1, nullable=False)
    children = Column(Integer, default=0, nullable=False)

    # Priority and status
    priority = Column(Enum(WaitlistPriority), default=WaitlistPriority.NORMAL, nullable=False, index=True)
    status = Column(Enum(WaitlistStatus), default=WaitlistStatus.PENDING, nullable=False, index=True)

    # Contact information (if no client_id)
    contact_name = Column(String(200), nullable=True)
    contact_email = Column(String(255), nullable=True, index=True)
    contact_phone = Column(String(50), nullable=True)

    # Notes and tracking
    notes = Column(Text, nullable=True)
    contacted_at = Column(Date, nullable=True)
    contacted_by_id = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
    converted_reservation_id = Column(Integer, ForeignKey("reservations.id", ondelete="SET NULL"), nullable=True)

    # Relationships
    establishment = relationship("Establishment", back_populates="waitlist")
    client = relationship("Client", back_populates="waitlist_entries")
    room_type = relationship("RoomType")
    contacted_by = relationship("User", foreign_keys=[contacted_by_id])
    converted_reservation = relationship("Reservation", foreign_keys=[converted_reservation_id])

    @property
    def display_name(self) -> str:
        """Return display name (client name or contact name)."""
        if self.client:
            return self.client.full_name
        return self.contact_name or "Unknown"

    @property
    def display_contact(self) -> str:
        """Return primary contact method."""
        if self.client:
            return self.client.email or self.client.phone or ""
        return self.contact_email or self.contact_phone or ""

    def __repr__(self) -> str:
        return f"<Waitlist {self.display_name} ({self.check_in_date} - {self.check_out_date})>"
