"""
Database Read Helper
Provides utilities for reading data that may be in the write queue (pending writes).
This ensures reads see the latest data even if it hasn't been written to the database yet.
"""

from typing import List, Optional, Dict, Any
from datetime import datetime
from ws_package.utils.db_write_queue import db_write_queue, WriteOperationType
from ws_package.entities.activity_entity import ActivityIntervalEntity
from ws_package.log.writer import LogWriter

logger = LogWriter.file(__name__)


def get_pending_activity_intervals(
    start_date: Optional[datetime] = None,
    end_date: Optional[datetime] = None
) -> List[ActivityIntervalEntity]:
    """
    Get pending ActivityInterval items from the write queue.
    
    This is useful when you need to read data that may not have been
    written to the database yet (e.g., for API calls that need latest data).
    
    Args:
        start_date: Filter by start_time >= start_date
        end_date: Filter by end_time <= end_date
        
    Returns:
        List of ActivityIntervalEntity objects from the queue
    """
    try:
        pending_items = db_write_queue.get_pending_items(
            WriteOperationType.ACTIVITY_INTERVAL,
            limit=1000  # Get all pending items
        )
        
        if not pending_items:
            return []
        
        # Convert queue items to entities
        entities = []
        for item in pending_items:
            try:
                # Reconstruct entity from queue data
                entity = ActivityIntervalEntity(**item.data)
                
                # Apply date filters
                if start_date and entity.start_time < start_date:
                    continue
                if end_date and entity.end_time > end_date:
                    continue
                
                entities.append(entity)
            except Exception as e:
                logger.warning("Error converting queue item to entity: %s", e)
                continue
        
        return entities
        
    except Exception as e:
        logger.error("Error getting pending activity intervals: %s", e, exc_info=True)
        return []


def merge_activity_intervals(
    db_intervals: List[Any],
    queue_intervals: List[ActivityIntervalEntity]
) -> List[ActivityIntervalEntity]:
    """
    Merge database intervals with queue intervals, removing duplicates.
    
    Args:
        db_intervals: Intervals from database (can be ORM objects or entities)
        queue_intervals: Intervals from write queue
        
    Returns:
        Merged and deduplicated list of ActivityIntervalEntity objects
    """
    try:
        # Convert database intervals to entities if needed
        db_entities = []
        for interval in db_intervals:
            if isinstance(interval, ActivityIntervalEntity):
                db_entities.append(interval)
            else:
                # Convert ORM object to entity
                try:
                    entity = ActivityIntervalEntity(
                        start_time=interval.start_time,
                        end_time=interval.end_time,
                        is_uploaded=interval.is_uploaded,
                        activityLevel=interval.activityLevel,
                        counter=interval.counter,
                        weekday=interval.weekday
                    )
                    db_entities.append(entity)
                except Exception as e:
                    logger.warning("Error converting DB interval to entity: %s", e)
                    continue
        
        # Combine and deduplicate by (start_time, end_time)
        seen = set()
        merged = []
        
        # Add queue intervals first (they're newer)
        for entity in queue_intervals:
            key = (entity.start_time, entity.end_time)
            if key not in seen:
                seen.add(key)
                merged.append(entity)
        
        # Add database intervals (skip duplicates)
        for entity in db_entities:
            key = (entity.start_time, entity.end_time)
            if key not in seen:
                seen.add(key)
                merged.append(entity)
        
        # Sort by start_time
        merged.sort(key=lambda x: x.start_time)
        
        return merged
        
    except Exception as e:
        logger.error("Error merging activity intervals: %s", e, exc_info=True)
        # Return database intervals as fallback
        return db_entities if 'db_entities' in locals() else []

