"""
Passenger Routes
Passenger profile, ride history, and saved places
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from sqlalchemy.orm import selectinload

from app.database import get_db
from app.models.user import User, UserRole
from app.models.driver import Driver
from app.models.ride import Ride, RideStatus
from app.schemas.user import UserProfileUpdate, UserResponse
from app.schemas.ride import RideListResponse, ActiveRideResponse
from app.schemas.common import MessageResponse, PaginatedResponse
from app.utils.dependencies import get_current_user, require_role
from app.utils.helpers import build_order_by
from app.media.profile_picture import save_profile_picture_from_base64

router = APIRouter()


@router.get("/profile", response_model=UserResponse)
async def get_passenger_profile(
    current_user: User = Depends(require_role(UserRole.PASSENGER)),
    db: AsyncSession = Depends(get_db)
):
    """Get passenger profile"""
    wallet_balance = current_user.wallet.balance if current_user.wallet else 0
    
    return UserResponse.from_orm_with_extras(
        current_user,
        wallet_balance=wallet_balance
    )


@router.put("/profile", response_model=UserResponse)
async def update_passenger_profile(
    data: UserProfileUpdate,
    current_user: User = Depends(require_role(UserRole.PASSENGER)),
    db: AsyncSession = Depends(get_db)
):
    """Update passenger profile"""
    # Update fields
    update_data = data.model_dump(exclude_unset=True)
    if "profile_picture_base64" in update_data:
        b64 = update_data.pop("profile_picture_base64")
        try:
            current_user.profile_picture = save_profile_picture_from_base64(current_user.id, b64)
        except ValueError as e:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
    if "fcm_token" in update_data:
        current_user.device_token = update_data.pop("fcm_token")
    for field, value in update_data.items():
        if hasattr(current_user, field):
            setattr(current_user, field, value)
    
    await db.commit()
    await db.refresh(current_user)
    
    return UserResponse.from_orm_with_extras(current_user)


@router.get("/rides", response_model=PaginatedResponse[RideListResponse])
async def get_ride_history(
    status_filter: Optional[RideStatus] = Query(None, description="Filter by ride status"),
    page: int = Query(1, ge=1),
    limit: int = Query(20, ge=1, le=100),
    sort_by: str = Query("created_at", description="Field to sort by"),
    order: str = Query("desc", description="Sort order: asc or desc"),
    current_user: User = Depends(require_role(UserRole.PASSENGER)),
    db: AsyncSession = Depends(get_db)
):
    """Get passenger's ride history"""
    passenger_filter = Ride.passenger_id == current_user.id
    count_query = select(func.count(Ride.id)).where(passenger_filter)
    if status_filter:
        count_query = count_query.where(Ride.status == status_filter)
    count_result = await db.execute(count_query)
    total = count_result.scalar() or 0

    offset = (page - 1) * limit
    query = select(Ride).where(passenger_filter)
    if status_filter:
        query = query.where(Ride.status == status_filter)
    order_clause = build_order_by(Ride, sort_by, order, {"created_at", "updated_at", "requested_at", "id"})
    query = query.options(
        selectinload(Ride.vehicle_category),
        selectinload(Ride.driver).selectinload(Driver.user),
        selectinload(Ride.rating)
    ).order_by(order_clause).offset(offset).limit(limit)
    result = await db.execute(query)
    rides = result.scalars().all()
    
    items = [
        RideListResponse(
            id=ride.id,
            ride_code=ride.ride_code,
            status=ride.status,
            pickup_address=ride.pickup_address,
            dropoff_address=ride.dropoff_address,
            estimated_fare=ride.estimated_fare,
            final_fare=ride.final_fare,
            payment_method=ride.payment_method,
            vehicle_category_name=ride.vehicle_category.display_name if ride.vehicle_category else "",
            driver_name=ride.driver.user.full_name if ride.driver else None,
            driver_rating=ride.driver.average_rating if ride.driver else None,
            rating_given=ride.rating.driver_rating if ride.rating else None,
            requested_at=ride.requested_at,
            completed_at=ride.completed_at
        )
        for ride in rides
    ]
    
    return PaginatedResponse.create(items, total, page, limit)


@router.get("/rides/active", response_model=ActiveRideResponse)
async def get_active_ride(
    current_user: User = Depends(require_role(UserRole.PASSENGER)),
    db: AsyncSession = Depends(get_db)
):
    """Get current active ride (if any)"""
    query = select(Ride).where(
        Ride.passenger_id == current_user.id,
        Ride.status.in_([
            RideStatus.REQUESTED,
            RideStatus.SEARCHING,
            RideStatus.BIDDING,
            RideStatus.ACCEPTED,
            RideStatus.DRIVER_ARRIVED,
            RideStatus.STARTED
        ])
    ).order_by(Ride.created_at.desc()).limit(1)
    
    result = await db.execute(query)
    ride = result.scalars().first()
    
    if not ride:
        return ActiveRideResponse(active_ride=None, ride_code=None, status=None)
    
    return ActiveRideResponse(
        active_ride=ride.id,
        ride_code=ride.ride_code,
        status=ride.status.value if hasattr(ride.status, "value") else str(ride.status)
    )
