from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
from ...shared.config.database import get_db
from ...shared.config.logging_config import get_logger
from ...security.middleware.auth import authorize_roles, get_current_user
from ...auth.models.user import User
from ..models.booking import Booking, BookingStatus
from ...hotel_services.models.service_usage import ServiceUsage
from ...hotel_services.models.service import Service
from ...rooms.models.room import Room
from pydantic import BaseModel

logger = get_logger(__name__)
router = APIRouter(prefix='/bookings', tags=['upsells'])


class AddServiceUsageRequest(BaseModel):
    booking_id: int
    service_id: int
    quantity: int = 1
    unit_price: Optional[float] = None
    notes: Optional[str] = None


@router.post('/service-usage')
async def add_service_usage(
    request: AddServiceUsageRequest,
    current_user: User = Depends(authorize_roles('admin', 'staff')),
    db: Session = Depends(get_db)
):
    """Add a service usage to an existing booking"""
    try:
        # Verify booking exists and is checked in
        booking = db.query(Booking).filter(Booking.id == request.booking_id).first()
        if not booking:
            raise HTTPException(status_code=404, detail='Booking not found')
        
        if booking.status != BookingStatus.checked_in:
            raise HTTPException(
                status_code=400,
                detail='Services can only be added to checked-in bookings'
            )
        
        # Verify service exists and is active
        service = db.query(Service).filter(Service.id == request.service_id).first()
        if not service:
            raise HTTPException(status_code=404, detail='Service not found')
        
        if not service.is_active:
            raise HTTPException(status_code=400, detail='Service is not active')
        
        # Use provided unit_price or service price
        unit_price = request.unit_price if request.unit_price is not None else float(service.price)
        total_price = unit_price * request.quantity
        
        # Create service usage
        service_usage = ServiceUsage(
            booking_id=request.booking_id,
            service_id=request.service_id,
            quantity=request.quantity,
            unit_price=unit_price,
            total_price=total_price,
            notes=request.notes,
            usage_date=datetime.utcnow()
        )
        
        db.add(service_usage)
        
        # Update booking total price
        booking.total_price = (float(booking.total_price) if booking.total_price else 0) + total_price
        
        db.commit()
        db.refresh(service_usage)
        
        return {
            'status': 'success',
            'message': 'Service added to booking successfully',
            'data': {
                'id': service_usage.id,
                'service_name': service.name,
                'quantity': service_usage.quantity,
                'total_price': float(service_usage.total_price)
            }
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f'Error adding service usage: {str(e)}', exc_info=True)
        db.rollback()
        raise HTTPException(status_code=500, detail=f'Failed to add service: {str(e)}')

