from sqlalchemy.orm import Session
from sqlalchemy import func, and_, or_
from typing import Optional, List, Dict
from datetime import datetime
import os
from ..models.room import Room, RoomStatus
from ..models.room_type import RoomType
from ...reviews.models.review import Review, ReviewStatus

def normalize_images(images, base_url: str) -> List[str]:
    if not images:
        return []
    imgs = images
    if isinstance(images, str):
        try:
            import json
            imgs = json.loads(images)
        except:
            imgs = [s.strip() for s in images.split(',') if s.strip()]
    if not isinstance(imgs, list):
        return []
    result = []
    for img in imgs:
        if not img:
            continue
        if img.startswith('http://') or img.startswith('https://'):
            result.append(img)
        else:
            path_part = img if img.startswith('/') else f'/{img}'
            result.append(f'{base_url}{path_part}')
    return result

def get_base_url(request) -> str:
    server_url = os.getenv('SERVER_URL')
    if server_url:
        return server_url.rstrip('/')
    host = request.headers.get('host', 'localhost:8000')
    if ':' not in host:
        host = f'{host}:8000'
    scheme = request.url.scheme if hasattr(request.url, 'scheme') else 'http'
    return f'{scheme}://{host}'

async def get_rooms_with_ratings(db: Session, rooms: List[Room], base_url: str) -> List[Dict]:
    result = []
    for room in rooms:
        review_stats = db.query(func.avg(Review.rating).label('average_rating'), func.count(Review.id).label('total_reviews')).filter(and_(Review.room_id == room.id, Review.status == ReviewStatus.approved)).first()
        room_dict = {'id': room.id, 'room_type_id': room.room_type_id, 'room_number': room.room_number, 'floor': room.floor, 'status': room.status.value if isinstance(room.status, RoomStatus) else room.status, 'price': float(room.price) if room.price else 0.0, 'featured': room.featured, 'description': room.description, 'capacity': room.capacity, 'room_size': room.room_size, 'view': room.view, 'amenities': room.amenities, 'created_at': room.created_at.isoformat() if room.created_at else None, 'updated_at': room.updated_at.isoformat() if room.updated_at else None, 'average_rating': round(float(review_stats.average_rating or 0), 1) if review_stats and review_stats.average_rating else None, 'total_reviews': review_stats.total_reviews or 0 if review_stats else 0}
        try:
            room_dict['images'] = normalize_images(room.images, base_url)
        except:
            room_dict['images'] = []
        if room.room_type:
            room_dict['room_type'] = {'id': room.room_type.id, 'name': room.room_type.name, 'description': room.room_type.description, 'base_price': float(room.room_type.base_price) if room.room_type.base_price else 0.0, 'capacity': room.room_type.capacity, 'amenities': room.room_type.amenities, 'images': []}
        result.append(room_dict)
    return result

async def get_amenities_list(db: Session) -> List[str]:
    """
    Get all unique amenities from the database only.
    Aggregates amenities from room_types and rooms tables.
    """
    all_amenities = set()
    
    # Get amenities from room types
    room_types = db.query(RoomType.amenities).all()
    for rt in room_types:
        if rt.amenities:
            if isinstance(rt.amenities, list):
                all_amenities.update([str(a).strip() for a in rt.amenities if str(a).strip()])
            elif isinstance(rt.amenities, str):
                try:
                    import json
                    parsed = json.loads(rt.amenities)
                    if isinstance(parsed, list):
                        all_amenities.update([str(a).strip() for a in parsed if str(a).strip()])
                    else:
                        all_amenities.update([s.strip() for s in rt.amenities.split(',') if s.strip()])
                except:
                    all_amenities.update([s.strip() for s in rt.amenities.split(',') if s.strip()])
    
    # Get amenities from rooms
    rooms = db.query(Room.amenities).all()
    for r in rooms:
        if r.amenities:
            if isinstance(r.amenities, list):
                all_amenities.update([str(a).strip() for a in r.amenities if str(a).strip()])
            elif isinstance(r.amenities, str):
                try:
                    import json
                    parsed = json.loads(r.amenities)
                    if isinstance(parsed, list):
                        all_amenities.update([str(a).strip() for a in parsed if str(a).strip()])
                    else:
                        all_amenities.update([s.strip() for s in r.amenities.split(',') if s.strip()])
                except:
                    all_amenities.update([s.strip() for s in r.amenities.split(',') if s.strip()])
    
    return sorted(list(all_amenities))