"""Automatic booking management for confirmed meetings."""
import json
import os
from datetime import datetime
from typing import Dict, List, Tuple, Optional


class BookingManager:
    """Manages proposed slots and automatic booking."""
    
    def __init__(self, storage_path: str = None):
        """
        Inicjalizacja menedżera bookingów.
        
        Args:
            storage_path: Ścieżka do pliku z zaproponowanymi slotami
        """
        self.storage_path = storage_path or os.path.join(
            os.getcwd(), '.llmass_proposed_slots.json'
        )
        self.proposed_slots = self._load_proposed_slots()
    
    def _load_proposed_slots(self) -> Dict:
        """Wczytuje zaproponowane sloty z pliku."""
        if os.path.exists(self.storage_path):
            try:
                with open(self.storage_path, 'r') as f:
                    data = json.load(f)
                    # Convert string dates back to datetime
                    for email_key in data:
                        if 'slots' in data[email_key]:
                            slots = []
                            for slot in data[email_key]['slots']:
                                start = datetime.fromisoformat(slot['start'])
                                end = datetime.fromisoformat(slot['end'])
                                slots.append((start, end))
                            data[email_key]['slots'] = slots
                    return data
            except Exception as e:
                print(f"⚠️  Błąd wczytywania proposed slots: {e}")
                return {}
        return {}
    
    def _save_proposed_slots(self):
        """Zapisuje zaproponowane sloty do pliku."""
        try:
            # Convert datetime to string for JSON serialization
            data = {}
            for email_key, info in self.proposed_slots.items():
                data[email_key] = {
                    'sender': info['sender'],
                    'subject': info['subject'],
                    'proposed_at': info['proposed_at'],
                    'slots': [
                        {
                            'start': slot[0].isoformat(),
                            'end': slot[1].isoformat()
                        }
                        for slot in info['slots']
                    ]
                }
            
            with open(self.storage_path, 'w') as f:
                json.dump(data, f, indent=2)
        except Exception as e:
            print(f"⚠️  Błąd zapisywania proposed slots: {e}")
    
    def store_proposed_slots(self, sender_email: str, subject: str, 
                           slots: List[Tuple[datetime, datetime]]) -> str:
        """
        Przechowuje zaproponowane sloty dla danego emaila.
        
        Args:
            sender_email: Email nadawcy
            subject: Temat emaila
            slots: Lista zaproponowanych slotów
        
        Returns:
            Klucz identyfikujący propozycję
        """
        # Generate unique key
        email_key = f"{sender_email}:{subject}"
        
        self.proposed_slots[email_key] = {
            'sender': sender_email,
            'subject': subject,
            'proposed_at': datetime.now().isoformat(),
            'slots': slots,
            'booked': False,
            'booked_slot_index': None
        }
        
        self._save_proposed_slots()
        return email_key
    
    def get_proposed_slots(self, sender_email: str, subject: str = None) -> Optional[Dict]:
        """
        Pobiera zaproponowane sloty dla danego nadawcy.
        
        Args:
            sender_email: Email nadawcy
            subject: Opcjonalny temat emaila (dla doprecyzowania)
        
        Returns:
            Słownik z informacjami o zaproponowanych slotach lub None
        """
        if subject:
            email_key = f"{sender_email}:{subject}"
            return self.proposed_slots.get(email_key)
        
        # Search by sender only
        for key, info in self.proposed_slots.items():
            if info['sender'] == sender_email:
                return info
        
        return None
    
    def book_slot(self, calendar_client, sender_email: str, slot_index: int,
                 subject: str = None, attendee_name: str = None) -> Optional[str]:
        """
        Bookuje wybrany slot w kalendarzu.
        
        Args:
            calendar_client: Instance CalendarClient
            sender_email: Email nadawcy
            slot_index: Index wybranego slotu (0-based)
            subject: Temat spotkania
            attendee_name: Opcjonalna nazwa uczestnika
        
        Returns:
            UID utworzonego wydarzenia lub None
        """
        if not calendar_client or not calendar_client.is_available():
            print("⚠️  Kalendarz niedostępny - nie można zabookować")
            return None
        
        # Get proposed slots
        proposal = self.get_proposed_slots(sender_email, subject)
        if not proposal:
            print(f"⚠️  Brak zaproponowanych slotów dla {sender_email}")
            return None
        
        if proposal.get('booked'):
            print(f"⚠️  Slot już został zabookowany")
            return None
        
        slots = proposal['slots']
        if slot_index < 0 or slot_index >= len(slots):
            print(f"⚠️  Nieprawidłowy index slotu: {slot_index}")
            return None
        
        # Get selected slot
        start, end = slots[slot_index]
        
        # Create meeting title
        meeting_subject = subject or proposal['subject']
        if attendee_name:
            meeting_title = f"Meeting: {attendee_name} - {meeting_subject}"
        else:
            meeting_title = f"Meeting: {sender_email} - {meeting_subject}"
        
        # Book in calendar
        event_uid = calendar_client.create_event(
            summary=meeting_title,
            start=start,
            end=end,
            description=f"Automatic booking from email: {meeting_subject}",
            location=""
        )
        
        if event_uid:
            # Mark as booked
            email_key = f"{sender_email}:{proposal['subject']}"
            if email_key in self.proposed_slots:
                self.proposed_slots[email_key]['booked'] = True
                self.proposed_slots[email_key]['booked_slot_index'] = slot_index
                self.proposed_slots[email_key]['event_uid'] = event_uid
                self._save_proposed_slots()
            
            print(f"✅ Zabookowano termin: {start.strftime('%d.%m.%Y %H:%M')} dla {sender_email}")
            return event_uid
        
        return None
    
    def cancel_booking(self, calendar_client, sender_email: str, subject: str = None) -> bool:
        """
        Anuluje zabookowany termin.
        
        Args:
            calendar_client: Instance CalendarClient
            sender_email: Email nadawcy
            subject: Temat emaila
        
        Returns:
            True jeśli anulowano
        """
        if not calendar_client or not calendar_client.is_available():
            return False
        
        proposal = self.get_proposed_slots(sender_email, subject)
        if not proposal or not proposal.get('booked'):
            return False
        
        event_uid = proposal.get('event_uid')
        if event_uid:
            success = calendar_client.delete_event(event_uid)
            if success:
                # Mark as not booked
                email_key = f"{sender_email}:{proposal['subject']}"
                if email_key in self.proposed_slots:
                    self.proposed_slots[email_key]['booked'] = False
                    self.proposed_slots[email_key]['booked_slot_index'] = None
                    del self.proposed_slots[email_key]['event_uid']
                    self._save_proposed_slots()
                
                print(f"✅ Anulowano booking dla {sender_email}")
                return True
        
        return False
    
    def cleanup_old_proposals(self, days_old: int = 30):
        """
        Usuwa stare propozycje terminów.
        
        Args:
            days_old: Usuń propozycje starsze niż X dni
        """
        cutoff = datetime.now().timestamp() - (days_old * 24 * 60 * 60)
        
        keys_to_remove = []
        for key, info in self.proposed_slots.items():
            proposed_at = datetime.fromisoformat(info['proposed_at'])
            if proposed_at.timestamp() < cutoff:
                keys_to_remove.append(key)
        
        for key in keys_to_remove:
            del self.proposed_slots[key]
        
        if keys_to_remove:
            self._save_proposed_slots()
            print(f"🧹 Usunięto {len(keys_to_remove)} starych propozycji")
