"""Slot finding and formatting utilities."""
import os
from datetime import datetime, timedelta
from typing import List, Tuple, Dict, Optional


def find_available_slots(calendar_client, preferences: Dict = None, 
                        max_slots: int = 3) -> List[Tuple[datetime, datetime]]:
    """
    Znajduje dostępne sloty zgodnie z preferencjami.
    
    Args:
        calendar_client: Instance CalendarClient
        preferences: Preferencje z extract_meeting_preferences()
        max_slots: Maksymalna liczba slotów do zwrócenia
    
    Returns:
        Lista tupli (start, end) z dostępnymi slotami
    """
    if not calendar_client or not calendar_client.is_available():
        return []
    
    # Default preferences
    if preferences is None:
        preferences = {}
    
    # Get configuration from .env
    default_duration = int(os.getenv('MEETING_DEFAULT_DURATION', '30'))
    days_ahead = int(os.getenv('MEETING_DAYS_AHEAD', '7'))
    work_start = os.getenv('MEETING_WORK_START', '09:00')
    work_end = os.getenv('MEETING_WORK_END', '17:00')
    exclude_weekends = os.getenv('MEETING_EXCLUDE_WEEKENDS', 'true').lower() == 'true'
    
    # Override with email preferences
    duration = preferences.get('duration') or default_duration
    
    # If urgent, search only next 2-3 days
    if preferences.get('urgent'):
        days_ahead = min(days_ahead, 3)
    
    # Adjust work hours based on preferred time
    preferred_time = preferences.get('preferred_time')
    if preferred_time == 'morning':
        work_end = '12:00'
    elif preferred_time == 'afternoon':
        work_start = '12:00'
        work_end = '17:00'
    elif preferred_time == 'evening':
        work_start = '17:00'
        work_end = '20:00'
    
    # Get all free slots
    all_slots = calendar_client.find_free_slots(
        duration_minutes=duration,
        days_ahead=days_ahead,
        work_start=work_start,
        work_end=work_end,
        exclude_weekends=exclude_weekends
    )
    
    # Filter by preferred days if specified
    preferred_days = preferences.get('preferred_days', [])
    if preferred_days:
        day_map = {
            'monday': 0, 'tuesday': 1, 'wednesday': 2, 
            'thursday': 3, 'friday': 4, 'saturday': 5, 'sunday': 6
        }
        preferred_weekdays = [day_map[d] for d in preferred_days if d in day_map]
        
        if preferred_weekdays:
            all_slots = [slot for slot in all_slots 
                        if slot[0].weekday() in preferred_weekdays]
    
    # Return first max_slots
    return all_slots[:max_slots]


def format_slot_proposal(slots: List[Tuple[datetime, datetime]], lang: str = 'en') -> str:
    """
    Formatuje propozycje terminów w odpowiednim języku.
    
    Args:
        slots: Lista slotów (start, end)
        lang: Kod języka
    
    Returns:
        Sformatowany tekst z propozycjami
    """
    if not slots:
        # No slots available
        messages = {
            'pl': '\n\nNiestety, w najbliższym czasie nie mam wolnych terminów. Czy możemy umówić się za 2 tygodnie?',
            'en': '\n\nUnfortunately, I don\'t have any available slots in the near future. Can we schedule for 2 weeks from now?',
            'de': '\n\nLeider habe ich in nächster Zeit keine freien Termine. Können wir uns in 2 Wochen treffen?',
            'fr': '\n\nMalheureusement, je n\'ai pas de créneaux disponibles dans un avenir proche. Peut-on programmer dans 2 semaines?',
            'es': '\n\nDesafortunadamente, no tengo espacios disponibles en el futuro cercano. ¿Podemos programar en 2 semanas?',
        }
        return messages.get(lang, messages['en'])
    
    # Format introduction
    intros = {
        'pl': '\n\nProponuję następujące terminy spotkania:',
        'en': '\n\nI propose the following meeting times:',
        'de': '\n\nIch schlage folgende Besprechungstermine vor:',
        'fr': '\n\nJe propose les horaires de réunion suivants:',
        'es': '\n\nPropongo los siguientes horarios de reunión:',
    }
    
    intro = intros.get(lang, intros['en'])
    
    # Format slots
    formatted_slots = []
    
    for i, (start, end) in enumerate(slots, 1):
        # Day name in language
        day_names = {
            'pl': ['Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota', 'Niedziela'],
            'en': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
            'de': ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'],
            'fr': ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche'],
            'es': ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo'],
        }
        
        days = day_names.get(lang, day_names['en'])
        day_name = days[start.weekday()]
        
        # Format date and time
        date_str = start.strftime('%d.%m.%Y')
        time_str = f"{start.strftime('%H:%M')} - {end.strftime('%H:%M')}"
        
        duration = int((end - start).total_seconds() / 60)
        
        duration_labels = {
            'pl': f'{duration} min',
            'en': f'{duration} min',
            'de': f'{duration} Min.',
            'fr': f'{duration} min',
            'es': f'{duration} min',
        }
        
        duration_label = duration_labels.get(lang, f'{duration} min')
        
        formatted_slots.append(
            f"{i}. {day_name}, {date_str}, {time_str} ({duration_label})"
        )
    
    # Confirmation text
    confirmations = {
        'pl': '\n\nProszę o potwierdzenie, który termin Ci odpowiada.',
        'en': '\n\nPlease confirm which time works best for you.',
        'de': '\n\nBitte bestätigen Sie, welcher Termin Ihnen passt.',
        'fr': '\n\nVeuillez confirmer quel horaire vous convient le mieux.',
        'es': '\n\nPor favor confirme qué hora funciona mejor para usted.',
    }
    
    confirmation = confirmations.get(lang, confirmations['en'])
    
    return intro + '\n' + '\n'.join(formatted_slots) + confirmation


def parse_slot_selection(email_body: str, proposed_slots: List[Tuple[datetime, datetime]]) -> Optional[int]:
    """
    Parsuje odpowiedź użytkownika wybierającego slot.
    
    Args:
        email_body: Treść emaila z odpowiedzią
        proposed_slots: Lista zaproponowanych slotów
    
    Returns:
        Index wybranego slotu (0-based) lub None
    """
    body_lower = email_body.lower()
    
    # Look for numbers 1, 2, 3, etc.
    for i in range(len(proposed_slots)):
        slot_num = i + 1
        patterns = [
            f'opcja {slot_num}',
            f'option {slot_num}',
            f'termin {slot_num}',
            f'slot {slot_num}',
            f'{slot_num}.',
            f'#{slot_num}',
        ]
        
        for pattern in patterns:
            if pattern in body_lower:
                return i
    
    # Look for confirmation keywords
    confirm_keywords = [
        'first', 'pierwszy', 'erste', 'premier', 'primero',
        'drugi', 'second', 'zweite', 'deuxième', 'segundo',
        'trzeci', 'third', 'dritte', 'troisième', 'tercero',
    ]
    
    keyword_to_index = {
        'first': 0, 'pierwszy': 0, 'erste': 0, 'premier': 0, 'primero': 0,
        'drugi': 1, 'second': 1, 'zweite': 1, 'deuxième': 1, 'segundo': 1,
        'trzeci': 2, 'third': 2, 'dritte': 2, 'troisième': 2, 'tercero': 2,
    }
    
    for keyword, index in keyword_to_index.items():
        if keyword in body_lower and index < len(proposed_slots):
            return index
    
    return None
