"""
Event Storage Module for U-ITE
================================
Handles persistence and retrieval of network events in the SQLite database.
Events are generated by the event detector and stored for historical analysis,
alerting, and troubleshooting.

Features:
- Store events with complete metadata
- Retrieve events by network
- Automatic timestamp ordering
- Support for event correlation
- Integration with main database

Event Schema:
- event_id: Unique identifier (UUID)
- timestamp: When the event occurred
- event_type: Type of event (e.g., INTERNET_DOWN)
- category: Event category (e.g., CONNECTIVITY)
- severity: Severity level (INFO/WARNING/CRITICAL)
- device_id: Source device
- network_id: Affected network
- verdict: Current network verdict
- summary: Short description
- description: Detailed information
- duration: How long the event lasted
- resolved: Whether the issue is resolved
- correlation_id: Group related events
"""

import sqlite3
from pathlib import Path
from typing import Dict, Any, List, Optional

from uite.storage.db import DB_PATH


class EventStore:
    """
    Event storage and retrieval operations.
    
    This class provides static methods for all event-related database
    operations. It uses the main database connection from db.py.
    
    Example:
        >>> from uite.tracking.event_store import EventStore
        >>> EventStore.save_event(event_dict)
        >>> events = EventStore.get_events("a1b2c3d4")
    """
    
    @staticmethod
    def save_event(event: Dict[str, Any]) -> None:
        """
        Persist an event into the database.
        
        Stores a complete event record with all metadata. The event dictionary
        should contain all fields expected by the events table schema.
        
        Args:
            event (dict): Event data containing:
                - event_id: Unique identifier
                - timestamp: ISO format timestamp
                - type: Event type string
                - category: Event category
                - severity: Severity level
                - device_id: Source device ID
                - network_id: Network identifier
                - verdict: Current network verdict
                - summary: Short description
                - description: Detailed description
                - duration: Optional duration in seconds
                - resolved: Optional resolution status
                - correlation_id: Optional correlation ID
                
        Returns:
            None
            
        Example:
            >>> event = {
            ...     "event_id": "123e4567-e89b-12d3-a456-426614174000",
            ...     "timestamp": "2026-02-23T15:30:00.123",
            ...     "type": "INTERNET_DOWN",
            ...     "category": "CONNECTIVITY",
            ...     "severity": "CRITICAL",
            ...     "device_id": "dev-001",
            ...     "network_id": "a1b2c3d4",
            ...     "verdict": "🌍 ISP Outage",
            ...     "summary": "Internet connection lost",
            ...     "description": "No internet connectivity for 5 minutes",
            ...     "duration": 300,
            ...     "resolved": False
            ... }
            >>> EventStore.save_event(event)
        """
        with sqlite3.connect(DB_PATH) as conn:
            conn.execute(
                """
                INSERT INTO events (
                    event_id,
                    timestamp,
                    event_type,
                    category,
                    severity,
                    device_id,
                    network_id,
                    verdict,
                    summary,
                    description,
                    duration,
                    resolved,
                    correlation_id
                )
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                """,
                (
                    event["event_id"],
                    event["timestamp"],
                    event["type"],           # Note: 'type' in dict maps to 'event_type' in DB
                    event["category"],
                    event["severity"],
                    event["device_id"],
                    event["network_id"],
                    event["verdict"],
                    event["summary"],
                    event["description"],
                    event.get("duration"),    # Optional field
                    int(event.get("resolved", False)),  # Convert bool to int (0/1)
                    event.get("correlation_id"),         # Optional field
                ),
            )

    @staticmethod
    def get_events(network_id: str, limit: int = 100, include_resolved: bool = True) -> List[Dict[str, Any]]:
        """
        Retrieve events for a specific network.
        
        Returns events in reverse chronological order (most recent first).
        
        Args:
            network_id (str): Network identifier to filter by
            limit (int): Maximum number of events to return (default: 100)
            include_resolved (bool): Whether to include resolved events
            
        Returns:
            List[dict]: List of event dictionaries with the same structure
                       as used in save_event()
                       
        Example:
            >>> events = EventStore.get_events("a1b2c3d4", limit=50)
            >>> for event in events:
            ...     print(f"{event['timestamp']}: {event['summary']}")
        """
        with sqlite3.connect(DB_PATH) as conn:
            # Use row_factory to get dictionary-like rows
            conn.row_factory = sqlite3.Row
            
            # Build query
            query = """
                SELECT * FROM events
                WHERE network_id = ?
            """
            params = [network_id]
            
            if not include_resolved:
                query += " AND resolved = 0"
            
            query += " ORDER BY timestamp DESC LIMIT ?"
            params.append(limit)
            
            cursor = conn.execute(query, params)
            
            # Convert rows to dictionaries
            events = []
            for row in cursor.fetchall():
                event = dict(row)
                # Convert resolved back to bool if needed
                event['resolved'] = bool(event['resolved'])
                events.append(event)
            
            return events

    @staticmethod
    def get_events_by_type(network_id: str, event_type: str, limit: int = 50) -> List[Dict[str, Any]]:
        """
        Retrieve events of a specific type for a network.
        
        Args:
            network_id (str): Network identifier
            event_type (str): Type of event to filter by
            limit (int): Maximum number of events to return
            
        Returns:
            List[dict]: Filtered event list
        """
        with sqlite3.connect(DB_PATH) as conn:
            conn.row_factory = sqlite3.Row
            cursor = conn.execute(
                """
                SELECT * FROM events
                WHERE network_id = ? AND event_type = ?
                ORDER BY timestamp DESC
                LIMIT ?
                """,
                (network_id, event_type, limit),
            )
            
            events = [dict(row) for row in cursor.fetchall()]
            for event in events:
                event['resolved'] = bool(event['resolved'])
            return events

    @staticmethod
    def get_unresolved_events(network_id: str = None) -> List[Dict[str, Any]]:
        """
        Get all unresolved events, optionally filtered by network.
        
        Args:
            network_id (str, optional): Network to filter by
            
        Returns:
            List[dict]: Unresolved events
        """
        with sqlite3.connect(DB_PATH) as conn:
            conn.row_factory = sqlite3.Row
            
            if network_id:
                cursor = conn.execute(
                    """
                    SELECT * FROM events
                    WHERE network_id = ? AND resolved = 0
                    ORDER BY timestamp DESC
                    """,
                    (network_id,),
                )
            else:
                cursor = conn.execute(
                    """
                    SELECT * FROM events
                    WHERE resolved = 0
                    ORDER BY timestamp DESC
                    """
                )
            
            events = [dict(row) for row in cursor.fetchall()]
            for event in events:
                event['resolved'] = bool(event['resolved'])
            return events

    @staticmethod
    def mark_resolved(event_id: str) -> bool:
        """
        Mark an event as resolved.
        
        Args:
            event_id (str): ID of the event to resolve
            
        Returns:
            bool: True if event was found and updated, False otherwise
        """
        with sqlite3.connect(DB_PATH) as conn:
            cursor = conn.execute(
                """
                UPDATE events
                SET resolved = 1
                WHERE event_id = ?
                """,
                (event_id,),
            )
            return cursor.rowcount > 0

    @staticmethod
    def get_event_summary(network_id: str, days: int = 7) -> Dict[str, Any]:
        """
        Get a summary of events for a network over a time period.
        
        Args:
            network_id (str): Network to analyze
            days (int): Number of days to look back
            
        Returns:
            dict: Summary containing:
                - total_events: Total event count
                - by_type: Count per event type
                - by_severity: Count per severity
                - unresolved: Number of unresolved events
        """
        from datetime import datetime, timedelta
        
        end_date = datetime.now()
        start_date = end_date - timedelta(days=days)
        
        with sqlite3.connect(DB_PATH) as conn:
            conn.row_factory = sqlite3.Row
            
            # Get all events in the time range
            cursor = conn.execute(
                """
                SELECT event_type, severity, resolved
                FROM events
                WHERE network_id = ? 
                    AND datetime(timestamp) BETWEEN datetime(?) AND datetime(?)
                """,
                (network_id, start_date.isoformat(), end_date.isoformat()),
            )
            
            events = cursor.fetchall()
            
            # Build summary
            summary = {
                'total_events': len(events),
                'by_type': {},
                'by_severity': {},
                'unresolved': 0,
                'period_days': days
            }
            
            for event in events:
                # Count by type
                event_type = event['event_type']
                summary['by_type'][event_type] = summary['by_type'].get(event_type, 0) + 1
                
                # Count by severity
                severity = event['severity']
                summary['by_severity'][severity] = summary['by_severity'].get(severity, 0) + 1
                
                # Count unresolved
                if not event['resolved']:
                    summary['unresolved'] += 1
            
            return summary

    @staticmethod
    def delete_old_events(days: int = 30) -> int:
        """
        Delete events older than the specified number of days.
        
        Args:
            days (int): Age threshold in days
            
        Returns:
            int: Number of events deleted
        """
        from datetime import datetime, timedelta
        
        cutoff_date = datetime.now() - timedelta(days=days)
        
        with sqlite3.connect(DB_PATH) as conn:
            cursor = conn.execute(
                """
                DELETE FROM events
                WHERE datetime(timestamp) < datetime(?)
                """,
                (cutoff_date.isoformat(),),
            )
            return cursor.rowcount


# Export public interface
__all__ = ['EventStore']
