"""
Fare Bid Model
InDrive-style fare bidding system
"""
import enum
from datetime import datetime
from typing import Optional
from sqlalchemy import String, Integer, Enum, Text, DateTime, ForeignKey, Index
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import BaseModel


class BidStatus(str, enum.Enum):
    """Bid status enumeration"""
    PENDING = "pending"       # Waiting for passenger response
    ACCEPTED = "accepted"     # Passenger accepted bid
    REJECTED = "rejected"     # Passenger rejected bid
    EXPIRED = "expired"       # Bid expired without response
    CANCELLED = "cancelled"   # Driver cancelled bid


class FareBid(BaseModel):
    """
    Fare bid submitted by drivers for ride requests.
    Implements InDrive-style bidding where drivers propose fares.
    """
    __tablename__ = "fare_bids"
    
    # References
    ride_id: Mapped[int] = mapped_column(
        ForeignKey("rides.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )
    driver_id: Mapped[int] = mapped_column(
        ForeignKey("drivers.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )
    
    # Bid Details
    bid_amount: Mapped[int] = mapped_column(Integer, nullable=False)  # In cents
    original_fare: Mapped[int] = mapped_column(Integer, nullable=False)  # Reference fare
    bid_percentage: Mapped[float] = mapped_column(default=100.0, nullable=False)  # % of original
    
    # Status
    status: Mapped[BidStatus] = mapped_column(
        Enum(BidStatus),
        default=BidStatus.PENDING,
        nullable=False,
        index=True
    )
    
    # Driver's message (optional)
    message: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    
    # ETA from driver's current location
    estimated_arrival_minutes: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    driver_distance_km: Mapped[Optional[float]] = mapped_column(nullable=True)
    
    # Timestamps
    submitted_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)
    expires_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
    responded_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Relationships
    ride: Mapped["Ride"] = relationship(
        "Ride",
        back_populates="bids"
    )
    driver: Mapped["Driver"] = relationship(
        "Driver",
        lazy="joined"
    )
    
    # Indexes
    __table_args__ = (
        Index('idx_bid_ride_status', 'ride_id', 'status'),
        Index('idx_bid_driver_status', 'driver_id', 'status'),
        Index('idx_bid_expires', 'expires_at'),
    )
    
    @property
    def is_expired(self) -> bool:
        """Check if bid has expired"""
        return datetime.utcnow() > self.expires_at


# Import for type hints
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from app.models.ride import Ride
    from app.models.driver import Driver
