"""
Dashboard utility functions for Aimantis hotel management platform.

Provides reusable helper functions for:
- Occupancy night calculations
- Channel name normalization
- Date utilities
- Query optimization helpers
"""

from datetime import date, timedelta, timezone
from decimal import Decimal
from typing import Optional, List

from django.utils import timezone as django_timezone

from dashboard.constants import CHANNEL_DISPLAY_NAMES, DEFAULT_CHANNEL_NAME


def normalize_channel_name(platform: Optional[str]) -> str:
    """
    Normalize platform/channel name to user-friendly display name.
    
    Args:
        platform: Raw platform string from booking (e.g., "airbnb", "Booking")
        
    Returns:
        Normalized display name (e.g., "Airbnb", "Booking.com", "Direct")
    """
    if not platform:
        return DEFAULT_CHANNEL_NAME
    
    platform_lower = platform.lower().strip()
    
    # Check for common typo first
    if "experia" in platform_lower:
        return "Expedia"
    
    # Check exact matches first
    if platform_lower in CHANNEL_DISPLAY_NAMES:
        return CHANNEL_DISPLAY_NAMES[platform_lower]
    
    # Check partial matches
    for key, display_name in CHANNEL_DISPLAY_NAMES.items():
        if key in platform_lower:
            return display_name
    
    return DEFAULT_CHANNEL_NAME


def calculate_overlapping_nights(
    check_in: date,
    check_out: date,
    window_start: date,
    window_end: date,
) -> int:
    """
    Calculate number of nights a booking overlaps with a given date window.
    
    This is the core occupancy calculation function used across all
    occupancy metrics.
    
    Args:
        check_in: Booking check-in date
        check_out: Booking check-out date
        window_start: Start of the analysis window (inclusive)
        window_end: End of the analysis window (exclusive)
        
    Returns:
        Number of overlapping nights (0 if no overlap)
    """
    # Calculate effective overlap
    effective_start = max(check_in, window_start)
    effective_end = min(check_out, window_end)
    
    overlap_days = (effective_end - effective_start).days
    
    return max(0, overlap_days)


def get_date_range(start: date, end: date) -> List[date]:
    """
    Generate a list of dates from start to end (exclusive).
    
    Args:
        start: Start date (inclusive)
        end: End date (exclusive)
        
    Returns:
        List of date objects
    """
    dates = []
    current = start
    while current < end:
        dates.append(current)
        current += timedelta(days=1)
    return dates


def get_today() -> date:
    """
    Get today's date using Django's timezone utilities.
    
    Returns:
        Current date in the active timezone
    """
    return django_timezone.localdate()


def safe_divide(numerator: float, denominator: float, default: float = 0.0) -> float:
    """
    Safely divide two numbers, returning default if denominator is zero.
    
    Args:
        numerator: The dividend
        denominator: The divisor
        default: Value to return if denominator is zero
        
    Returns:
        Division result or default value
    """
    if denominator == 0:
        return default
    return numerator / denominator


def round_occupancy(value: float, decimals: int = 0) -> int:
    """
    Round occupancy percentage to specified decimal places.
    
    Args:
        value: Occupancy percentage
        decimals: Number of decimal places (default: 0 for integer)
        
    Returns:
        Rounded occupancy percentage
    """
    return round(value, decimals)


def decimal_to_float(value: Optional[Decimal], decimals: int = 2) -> float:
    """
    Safely convert Decimal to float with rounding.
    
    Args:
        value: Decimal value
        decimals: Number of decimal places
        
    Returns:
        Rounded float value
    """
    if value is None:
        return 0.0
    return float(round(value, decimals))
