"""
Ride Schemas
Ride booking, fare estimation, and bidding
"""
from typing import Optional, List
from pydantic import BaseModel, Field
from datetime import datetime

from app.models.ride import RideStatus, RideType, CancellationReason
from app.models.fare_bid import BidStatus
from app.schemas.common import LocationSchema


class FareEstimateRequest(BaseModel):
    """Request for fare estimation"""
    pickup: LocationSchema
    dropoff: LocationSchema
    ride_type: RideType = RideType.ONE_WAY
    vehicle_category_id: int
    passenger_count: int = Field(default=1, ge=1, le=8)
    children: int = Field(default=0, ge=0, le=8, description="Children count; total riders = passenger_count + children")
    promo_code: Optional[str] = None
    scheduled_at: Optional[datetime] = None
    duration_minutes: Optional[int] = Field(None, ge=30, le=1440, description="Required for per_hour rides")


class FareEstimateResponse(BaseModel):
    """Fare estimation response"""
    vehicle_category_id: int
    vehicle_category_name: str
    estimated_distance_km: float
    estimated_duration_minutes: int
    base_fare: int  # In cents
    distance_fare: int
    time_fare: int
    surge_multiplier: float
    promo_discount: int
    estimated_fare: int
    currency: str = "USD"
    
    class Config:
        json_schema_extra = {
            "example": {
                "vehicle_category_id": 1,
                "vehicle_category_name": "Economy",
                "estimated_distance_km": 10.5,
                "estimated_duration_minutes": 25,
                "base_fare": 5000,
                "distance_fare": 15750,
                "time_fare": 5000,
                "surge_multiplier": 1.0,
                "promo_discount": 0,
                "estimated_fare": 25750,
                "currency": "USD"
            }
        }


class RideBase(BaseModel):
    """Base ride schema"""
    pickup_address: str
    pickup_latitude: float
    pickup_longitude: float
    dropoff_address: str
    dropoff_latitude: float
    dropoff_longitude: float


class RideCreate(BaseModel):
    """Ride booking request"""
    pickup: LocationSchema
    dropoff: LocationSchema
    return_location: Optional[LocationSchema] = None
    ride_type: RideType = RideType.ONE_WAY
    vehicle_category_id: int
    payment_method: str = Field(default="cash", pattern="^(cash|wallet|card)$")
    passenger_count: int = Field(default=1, ge=1, le=8)
    children: int = Field(default=0, ge=0, le=8, description="Children count; total riders = passenger_count + children")
    promo_code: Optional[str] = None
    is_scheduled: bool = False
    scheduled_at: Optional[datetime] = None
    return_scheduled_at: Optional[datetime] = None
    duration_minutes: Optional[int] = Field(None, ge=30, le=1440, description="Required for per_hour rides")
    end_scheduled_at: Optional[datetime] = None
    passenger_notes: Optional[str] = Field(None, max_length=500)


class RideStatusUpdate(BaseModel):
    """Ride status update"""
    status: RideStatus
    driver_notes: Optional[str] = None


class RideCancelRequest(BaseModel):
    """Ride cancellation request"""
    reason: CancellationReason
    note: Optional[str] = Field(None, max_length=500)


class FareBidCreate(BaseModel):
    """Driver fare bid submission"""
    ride_id: int
    bid_amount: int = Field(..., gt=0, description="Bid amount in cents")
    message: Optional[str] = Field(None, max_length=255)
    estimated_arrival_minutes: Optional[int] = Field(None, ge=1, le=60)


class FareBidResponse(BaseModel):
    """Fare bid response"""
    id: int
    ride_id: int
    driver_id: int
    driver_name: str
    driver_photo: Optional[str] = None
    driver_rating: float
    driver_total_rides: int
    bid_amount: int
    original_fare: int
    bid_percentage: float
    status: BidStatus
    message: Optional[str] = None
    estimated_arrival_minutes: Optional[int] = None
    driver_distance_km: Optional[float] = None
    vehicle_make: Optional[str] = None
    vehicle_model: Optional[str] = None
    vehicle_color: Optional[str] = None
    vehicle_plate: Optional[str] = None
    submitted_at: datetime
    expires_at: datetime
    
    class Config:
        from_attributes = True


class FareBidAction(BaseModel):
    """Accept or reject a bid"""
    bid_id: int
    action: str = Field(..., pattern="^(accept|reject)$")


class DriverLocationSnapshot(BaseModel):
    """Driver location during ride"""
    latitude: float
    longitude: float
    heading: Optional[float] = None
    timestamp: datetime


class RideResponse(BaseModel):
    """Ride details response"""
    id: int
    ride_code: str
    ride_type: RideType
    status: RideStatus
    
    # Locations
    pickup_address: str
    pickup_latitude: float
    pickup_longitude: float
    dropoff_address: str
    dropoff_latitude: float
    dropoff_longitude: float
    
    # Distance and duration
    estimated_distance_km: float
    estimated_duration_minutes: int
    actual_distance_km: Optional[float] = None
    actual_duration_minutes: Optional[int] = None
    
    # Fare
    estimated_fare: int
    final_fare: Optional[int] = None
    accepted_bid_amount: Optional[int] = None
    payment_method: str
    payment_status: str
    promo_discount: int
    
    # Timestamps
    requested_at: datetime
    accepted_at: Optional[datetime] = None
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    cancelled_at: Optional[datetime] = None
    
    # Scheduling
    is_scheduled: bool
    scheduled_at: Optional[datetime] = None
    
    # Vehicle
    vehicle_category_id: int
    vehicle_category_name: Optional[str] = None
    
    # Passenger info
    passenger_id: int
    passenger_name: Optional[str] = None
    passenger_phone: Optional[str] = None
    passenger_rating: Optional[float] = None
    
    # Driver info (if assigned)
    driver_id: Optional[int] = None
    driver_name: Optional[str] = None
    driver_phone: Optional[str] = None
    driver_photo: Optional[str] = None
    driver_rating: Optional[float] = None
    driver_location: Optional[DriverLocationSnapshot] = None
    
    # Vehicle info
    vehicle_make: Optional[str] = None
    vehicle_model: Optional[str] = None
    vehicle_color: Optional[str] = None
    vehicle_plate: Optional[str] = None
    
    # Cancellation
    cancelled_by: Optional[str] = None
    cancellation_reason: Optional[CancellationReason] = None
    
    # Rating
    rating_given: Optional[float] = None
    rating_received: Optional[float] = None
    
    # Bids (for bidding state)
    pending_bids_count: Optional[int] = None
    
    created_at: datetime
    
    class Config:
        from_attributes = True


class RideListResponse(BaseModel):
    """Ride list item for history"""
    id: int
    ride_code: str
    status: RideStatus
    pickup_address: str
    dropoff_address: str
    estimated_fare: int
    final_fare: Optional[int] = None
    payment_method: str
    vehicle_category_name: str
    driver_name: Optional[str] = None
    driver_rating: Optional[float] = None
    rating_given: Optional[float] = None
    requested_at: datetime
    completed_at: Optional[datetime] = None
    
    class Config:
        from_attributes = True


class RideTrackingUpdate(BaseModel):
    """Real-time ride tracking update (for WebSocket)"""
    ride_id: int
    ride_code: str
    status: RideStatus
    driver_latitude: float
    driver_longitude: float
    driver_heading: Optional[float] = None
    eta_minutes: Optional[int] = None
    distance_remaining_km: Optional[float] = None
    timestamp: datetime


class ActiveRideResponse(BaseModel):
    """Active ride response (passenger or driver)"""
    active_ride: Optional[int] = Field(None, description="Ride ID if active, null otherwise")
    ride_code: Optional[str] = Field(None, description="Ride code for display")
    status: Optional[str] = Field(None, description="Current ride status")


class NearbyRideItem(BaseModel):
    """Nearby ride request item for drivers"""
    id: int
    ride_code: str
    pickup_address: str
    dropoff_address: str
    estimated_fare: int
    estimated_distance_km: float
    passenger_count: int
    vehicle_category_id: int


class NearbyRidesResponse(BaseModel):
    """Nearby ride requests for drivers"""
    rides: List[NearbyRideItem] = Field(default_factory=list, description="List of nearby ride requests")


class VehicleCategoryResponse(BaseModel):
    """Vehicle category for selection"""
    id: int
    name: str
    display_name: str
    description: Optional[str] = None
    icon_url: Optional[str] = None
    max_passengers: int
    max_luggage: int
    luggage_capacity: Optional[int] = None
    base_fare: int
    per_km_rate: int
    per_minute_rate: int
    minimum_fare: int
    
    class Config:
        from_attributes = True
