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 ..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

def get_predefined_amenities() -> List[str]:
    return ['Free WiFi', 'WiFi', 'High-Speed Internet', 'WiFi in Room', 'Flat-Screen TV', 'TV', 'Cable TV', 'Satellite TV', 'Smart TV', 'Netflix', 'Streaming Services', 'DVD Player', 'Stereo System', 'Radio', 'iPod Dock', 'Air Conditioning', 'AC', 'Heating', 'Climate Control', 'Ceiling Fan', 'Air Purifier', 'Private Bathroom', 'Ensuite Bathroom', 'Bathtub', 'Jacuzzi Bathtub', 'Hot Tub', 'Shower', 'Rain Shower', 'Walk-in Shower', 'Bidet', 'Hair Dryer', 'Hairdryer', 'Bathrobes', 'Slippers', 'Toiletries', 'Premium Toiletries', 'Towels', 'Mini Bar', 'Minibar', 'Refrigerator', 'Fridge', 'Microwave', 'Coffee Maker', 'Electric Kettle', 'Tea Making Facilities', 'Coffee Machine', 'Nespresso Machine', 'Kitchenette', 'Dining Table', 'Room Service', 'Breakfast Included', 'Breakfast', 'Complimentary Water', 'Bottled Water', 'Desk', 'Writing Desk', 'Office Desk', 'Work Desk', 'Sofa', 'Sitting Area', 'Lounge Area', 'Dining Area', 'Separate Living Area', 'Wardrobe', 'Closet', 'Dresser', 'Mirror', 'Full-Length Mirror', 'Seating Area', 'King Size Bed', 'Queen Size Bed', 'Double Bed', 'Twin Beds', 'Single Bed', 'Extra Bedding', 'Pillow Menu', 'Premium Bedding', 'Blackout Curtains', 'Soundproofing', 'Safe', 'In-Room Safe', 'Safety Deposit Box', 'Smoke Detector', 'Fire Extinguisher', 'Security System', 'Key Card Access', 'Door Lock', 'Pepper Spray', 'USB Charging Ports', 'USB Ports', 'USB Outlets', 'Power Outlets', 'Charging Station', 'Laptop Safe', 'HDMI Port', 'Phone', 'Desk Phone', 'Wake-Up Service', 'Alarm Clock', 'Digital Clock', 'Balcony', 'Private Balcony', 'Terrace', 'Patio', 'City View', 'Ocean View', 'Sea View', 'Mountain View', 'Garden View', 'Pool View', 'Park View', 'Window', 'Large Windows', 'Floor-to-Ceiling Windows', '24-Hour Front Desk', '24 Hour Front Desk', '24/7 Front Desk', 'Concierge Service', 'Butler Service', 'Housekeeping', 'Daily Housekeeping', 'Turndown Service', 'Laundry Service', 'Dry Cleaning', 'Ironing Service', 'Luggage Storage', 'Bell Service', 'Valet Parking', 'Parking', 'Free Parking', 'Airport Shuttle', 'Shuttle Service', 'Car Rental', 'Taxi Service', 'Gym Access', 'Fitness Center', 'Fitness Room', 'Spa Access', 'Spa', 'Sauna', 'Steam Room', 'Hot Tub', 'Massage Service', 'Beauty Services', 'Swimming Pool', 'Pool', 'Indoor Pool', 'Outdoor Pool', 'Infinity Pool', 'Pool Access', 'Golf Course', 'Tennis Court', 'Beach Access', 'Water Sports', 'Business Center', 'Meeting Room', 'Conference Room', 'Fax Service', 'Photocopying', 'Printing Service', 'Secretarial Services', 'Wheelchair Accessible', 'Accessible Room', 'Elevator Access', 'Ramp Access', 'Accessible Bathroom', 'Lowered Sink', 'Grab Bars', 'Hearing Accessible', 'Visual Alarm', 'Family Room', 'Kids Welcome', 'Baby Crib', 'Extra Bed', 'Crib', 'Childcare Services', 'Pets Allowed', 'Pet Friendly', 'Smoking Room', 'Non-Smoking Room', 'No Smoking', 'Interconnecting Rooms', 'Adjoining Rooms', 'Suite', 'Separate Bedroom', 'Kitchen', 'Full Kitchen', 'Dishwasher', 'Oven', 'Stove', 'Washing Machine', 'Dryer', 'Iron', 'Ironing Board', 'Clothes Rack', 'Umbrella', 'Shoe Shine Service', 'Fireplace', 'Jacuzzi', 'Steam Shower', 'Spa Bath', 'Bidet Toilet', 'Smart Home System', 'Lighting Control', 'Curtain Control', 'Automated Systems', 'Personalized Service', 'VIP Treatment', 'Butler', 'Private Entrance', 'Private Elevator', 'Panic Button', 'Blu-ray Player', 'Gaming Console', 'PlayStation', 'Xbox', 'Sound System', 'Surround Sound', 'Music System', 'Library', 'Reading Room', 'Study Room', 'Private Pool', 'Private Garden', 'Yard', 'Courtyard', 'Outdoor Furniture', 'BBQ Facilities', 'Picnic Area']

async def get_amenities_list(db: Session) -> List[str]:
    all_amenities = set(get_predefined_amenities())
    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()])
    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))