import requests
import urllib3
import os
import logging
from django.db import transaction
from django.core.files.base import ContentFile
from .models import Hotel, RoomType

# Disable insecure request warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

logger = logging.getLogger(__name__)

def sync_one_hotel(hotel, api_url, token, pms_hotel_id=None, pms_branch_id=None):
    """
    Fetches hotel details from the PMS API and updates the local Hotel instance.
    """
    headers = {
        "Authorization": token,
        "X-API-Key": token,
        "Content-Type": "application/json"
    }

    try:
        logger.info(f"Fetching details for hotel {hotel.name} from {api_url}")
        response = requests.get(api_url, headers=headers, verify=False)
        
        if response.status_code != 200:
            logger.error(f"Failed to fetch hotel details. Status: {response.status_code}")
            return False, f"Failed to fetch. Status: {response.status_code}"

        detail = response.json()
        
        # Handle if API returns a list (e.g. user provided list URL instead of detail URL)
        if isinstance(detail, list):
            if pms_hotel_id is not None or pms_branch_id is not None:
                filtered = detail
                if pms_hotel_id is not None:
                    filtered = [h for h in filtered if str(h.get('hotel_id')) == str(pms_hotel_id)]
                if pms_branch_id is not None:
                    filtered = [h for h in filtered if str(h.get('branch_id')) == str(pms_branch_id)]
                
                if len(filtered) == 1:
                    detail = filtered[0]
                elif len(filtered) > 1:
                    return False, "API returned multiple hotels matching the provided filters. Please be more specific."
                else:
                    return False, "API returned no hotels matching the provided hotel_id and branch_id."
            elif len(detail) == 1:
                detail = detail[0]
            elif len(detail) > 1:
                return False, "API returned multiple hotels. Please provide pms_hotel_id and pms_branch_id to filter, or the specific Hotel URL."
            else:
                return False, "API returned an empty list. No hotel found."

        # PMS ID check
        pms_id = detail.get('id')
        if not pms_id:
             return False, "No ID found in PMS response"

        with transaction.atomic():
            # Update Hotel Fields
            hotel.pms_id = pms_id
            hotel.name = detail.get('name', hotel.name)
            hotel.phone = detail.get('phone')
            hotel.email = detail.get('email')
            hotel.branch = detail.get('branch', 'Main')
            hotel.city = detail.get('city', hotel.city)
            hotel.address = detail.get('address', hotel.address)
            hotel.state = detail.get('state', hotel.state)
            hotel.country = detail.get('country', hotel.country or 'India')
            hotel.description = detail.get('description', '')
            hotel.rating = detail.get('rating', 0.0)
            
            # Tax Info
            hotel.gstin = detail.get('gstin', detail.get('gst_no')) # Handle potential key variance
            hotel.pan = detail.get('pan')

            # Times
            checkin = detail.get('checkin_time')
            if checkin: hotel.checkin_time = checkin
            
            checkout = detail.get('checkout_time')
            if checkout: hotel.checkout_time = checkout
                
            hotel.is_active = detail.get('is_active', True)

            # Amenities
            amenities = detail.get('amenities', [])
            features = detail.get('features', [])
            
            if isinstance(amenities, list):
                amenities_list = amenities
            else:
                 # split by comma if string
                 amenities_list = [a.strip() for a in str(amenities).split(',')] if amenities else []
            
            if isinstance(features, list):
                # filters out duplicates
                amenities_list.extend([f for f in features if f not in amenities_list])
            
            hotel.amenities = ", ".join(amenities_list)

            # Image
            image_path = detail.get('image')
            if image_path:
                try:
                    # Construct absolute URL if relative
                    if image_path.startswith('/'):
                        # Try to deduce base URL from api_url
                        # api_url: https://host/path/to/api...
                        from urllib.parse import urlparse
                        parsed = urlparse(api_url)
                        base_url = f"{parsed.scheme}://{parsed.netloc}"
                        img_url = f"{base_url}{image_path}"
                    else:
                        img_url = image_path
                    
                    logger.info(f"Downloading image from {img_url}")
                    img_resp = requests.get(img_url, verify=False, stream=True)
                    if img_resp.status_code == 200:
                        filename = os.path.basename(image_path)
                        # Only save if we don't have an image or if checking changes (simplified: always save for now if different)
                        # For now, let's update if it's a new hotel or just do it.
                        hotel.images.save(filename, ContentFile(img_resp.content), save=False)
                except Exception as e:
                    logger.warning(f"Failed to download image: {e}")

            hotel.save()

            # Sync Room Types
            room_types = detail.get('room_types', [])
            synced_rt_count = 0
            
            for rt in room_types:
                rt_pms_id = rt.get('id')
                if not rt_pms_id: continue

                # Look for existing room type by pms_id
                rt_obj = RoomType.objects.filter(pms_id=rt_pms_id).first()
                
                if not rt_obj:
                    # Look for existing by logic (hotel + name) to link
                    rt_obj = RoomType.objects.filter(
                        hotel=hotel,
                        name=rt.get('name'),
                        branch=rt.get('branch', hotel.branch)
                    ).first()
                    if rt_obj:
                        logger.info(f"Linking existing RoomType {rt_obj.id} to PMS ID {rt_pms_id}")
                        rt_obj.pms_id = rt_pms_id
                
                # Update or Create
                defaults = {
                     'name': rt.get('name'),
                     'branch': rt.get('branch', hotel.branch),
                     'price': rt.get('price'),
                     'total_rooms': rt.get('total_rooms', 0)
                }

                if rt_obj:
                    for k, v in defaults.items():
                        setattr(rt_obj, k, v)
                    rt_obj.save()
                else:
                    RoomType.objects.create(hotel=hotel, pms_id=rt_pms_id, **defaults)
                
                synced_rt_count += 1

            return True, f"Successfully synced hotel and {synced_rt_count} room types."

    except Exception as e:
        logger.error(f"Exception during sync: {e}")
        return False, str(e)
