"""Coffee types, descriptions, and time-of-day recommendations."""

import random
from datetime import datetime
from typing import Any, Dict, List, Optional

# ---------------------------------------------------------------------------
# Coffee type definitions
# ---------------------------------------------------------------------------

COFFEE_TYPES: Dict[str, Dict[str, Any]] = {
    "espresso": {
        "name": "Espresso",
        "emoji": "☕",
        "caffeine_mg": 63,
        "description": "A concentrated shot of pure coffee magic. No nonsense, no fluff.",
        "brew_time": "25-30 seconds",
        "brew_seconds": 30,
        "intensity": "espresso",
        "best_time": "morning",
        "notes": "The foundation of all great coffee drinks.",
    },
    "americano": {
        "name": "Americano",
        "emoji": "☕",
        "caffeine_mg": 63,
        "description": "Espresso diluted with hot water. Strong but approachable.",
        "brew_time": "1-2 minutes",
        "brew_seconds": 90,
        "intensity": "strong",
        "best_time": "morning",
        "notes": "Great for slow sipping without sacrificing strength.",
    },
    "latte": {
        "name": "Latte",
        "emoji": "🥛",
        "caffeine_mg": 63,
        "description": "Espresso with steamed milk. Smooth, comforting, civilized.",
        "brew_time": "3-4 minutes",
        "brew_seconds": 210,
        "intensity": "mild",
        "best_time": "morning",
        "notes": "The drink of choice for morning meetings.",
    },
    "cappuccino": {
        "name": "Cappuccino",
        "emoji": "☕",
        "caffeine_mg": 63,
        "description": "Equal parts espresso, steamed milk, and foam. The holy trinity.",
        "brew_time": "3-4 minutes",
        "brew_seconds": 210,
        "intensity": "strong",
        "best_time": "morning",
        "notes": "Italians don't drink cappuccino after 11 AM. Are you Italian?",
    },
    "cold-brew": {
        "name": "Cold Brew",
        "emoji": "🧊",
        "caffeine_mg": 155,
        "description": "Slow-steeped, smooth, and dangerously drinkable. High caffeine.",
        "brew_time": "12-24 hours",
        "brew_seconds": 43200,
        "intensity": "espresso",
        "best_time": "afternoon",
        "notes": "Plan ahead. Very, very ahead.",
    },
    "pour-over": {
        "name": "Pour Over",
        "emoji": "☕",
        "caffeine_mg": 100,
        "description": "Patient, precise, pour. A meditation in coffee form.",
        "brew_time": "3-4 minutes",
        "brew_seconds": 240,
        "intensity": "strong",
        "best_time": "morning",
        "notes": "For when you want to feel like a coffee artisan.",
    },
    "french-press": {
        "name": "French Press",
        "emoji": "☕",
        "caffeine_mg": 80,
        "description": "Immersion brewing. Bold, full-bodied, no paper filter nonsense.",
        "brew_time": "4 minutes",
        "brew_seconds": 240,
        "intensity": "strong",
        "best_time": "morning",
        "notes": "Don't forget to set a timer. Seriously.",
    },
    "mocha": {
        "name": "Mocha",
        "emoji": "🍫",
        "caffeine_mg": 63,
        "description": "Espresso + chocolate + milk. A hug in a cup.",
        "brew_time": "3-4 minutes",
        "brew_seconds": 210,
        "intensity": "mild",
        "best_time": "afternoon",
        "notes": "Dessert disguised as a beverage. We're okay with that.",
    },
    "macchiato": {
        "name": "Macchiato",
        "emoji": "☕",
        "caffeine_mg": 63,
        "description": "Espresso 'stained' with a touch of milk foam. Bold and tiny.",
        "brew_time": "1-2 minutes",
        "brew_seconds": 90,
        "intensity": "espresso",
        "best_time": "afternoon",
        "notes": "Don't confuse with the giant caramel thing at chain cafes.",
    },
    "flat-white": {
        "name": "Flat White",
        "emoji": "☕",
        "caffeine_mg": 130,
        "description": "Double espresso with microfoam. An Aussie export. Dangerously smooth.",
        "brew_time": "3-4 minutes",
        "brew_seconds": 210,
        "intensity": "espresso",
        "best_time": "morning",
        "notes": "More caffeine than a latte, more milk than a macchiato. Perfect.",
    },
}

# Time-of-day recommendations (by intensity preference, not guaranteed available)
_TIME_RECOMMENDATIONS: Dict[str, List[str]] = {
    "morning":   ["espresso", "americano", "pour-over", "cappuccino", "flat-white"],
    "midday":    ["latte", "cappuccino", "americano", "flat-white"],
    "afternoon": ["cold-brew", "macchiato", "mocha", "latte"],
    "evening":   ["mocha", "latte"],
}


def get_coffee_info(coffee_type: str) -> Optional[Dict[str, Any]]:
    """
    Get information about a specific coffee type.

    Args:
        coffee_type: Key for the coffee type (e.g. 'espresso', 'latte').

    Returns:
        The info dict, or None if the type is not recognised.
    """
    return COFFEE_TYPES.get(coffee_type)


def get_recommendation(intensity: Optional[str] = None) -> Dict[str, Any]:
    """
    Recommend a coffee based on time of day, optionally filtered by intensity.

    Args:
        intensity: One of 'mild', 'strong', or 'espresso'.

    Returns:
        A coffee info dict.
    """
    hour = datetime.now().hour
    if 5 <= hour < 11:
        time_period = "morning"
    elif 11 <= hour < 14:
        time_period = "midday"
    elif 14 <= hour < 20:
        time_period = "afternoon"
    else:
        time_period = "evening"

    candidates = list(_TIME_RECOMMENDATIONS.get(time_period, list(COFFEE_TYPES.keys())))

    if intensity:
        filtered = [c for c in candidates if COFFEE_TYPES.get(c, {}).get("intensity") == intensity]
        if not filtered:
            # No match in the time-period pool — widen to all types with that intensity.
            filtered = [k for k, v in COFFEE_TYPES.items() if v["intensity"] == intensity]
        if filtered:
            candidates = filtered

    chosen = random.choice(candidates)
    return COFFEE_TYPES.get(chosen, COFFEE_TYPES["latte"])


def get_all_types() -> List[str]:
    """Return all coffee type keys."""
    return list(COFFEE_TYPES.keys())
