"""Helper functions for child override database operations."""
import logging
from typing import Optional, List
from tinydb import Query
from db.db import child_overrides_db
from models.child_override import ChildOverride


logger = logging.getLogger(__name__)


def insert_override(override: ChildOverride) -> str:
    """
    Insert or update an override. Only one override per (child_id, entity_id).
    
    Args:
        override: ChildOverride instance to insert or update
        
    Returns:
        The override ID
    """
    try:
        OverrideQuery = Query()
        existing = child_overrides_db.get(
            (OverrideQuery.child_id == override.child_id) &
            (OverrideQuery.entity_id == override.entity_id)
        )
        
        if existing:
            # Update existing override
            override.touch()  # Update timestamp
            child_overrides_db.update(override.to_dict(), doc_ids=[existing.doc_id])
            logger.info(f"Override updated: child={override.child_id}, entity={override.entity_id}, value={override.custom_value}")
        else:
            # Insert new override
            child_overrides_db.insert(override.to_dict())
            logger.info(f"Override created: child={override.child_id}, entity={override.entity_id}, value={override.custom_value}")
        
        return override.id
    except Exception as e:
        logger.error(f"Failed to insert override: {e}")
        raise


def get_override(child_id: str, entity_id: str) -> Optional[ChildOverride]:
    """
    Get override for a specific child and entity.
    
    Args:
        child_id: Child ID
        entity_id: Entity ID (task or reward)
        
    Returns:
        ChildOverride instance or None if not found
    """
    OverrideQuery = Query()
    result = child_overrides_db.get(
        (OverrideQuery.child_id == child_id) &
        (OverrideQuery.entity_id == entity_id)
    )
    return ChildOverride.from_dict(result) if result else None


def get_overrides_for_child(child_id: str) -> List[ChildOverride]:
    """
    Get all overrides for a specific child.
    
    Args:
        child_id: Child ID
        
    Returns:
        List of ChildOverride instances
    """
    OverrideQuery = Query()
    results = child_overrides_db.search(OverrideQuery.child_id == child_id)
    return [ChildOverride.from_dict(r) for r in results]


def delete_override(child_id: str, entity_id: str) -> bool:
    """
    Delete a specific override.
    
    Args:
        child_id: Child ID
        entity_id: Entity ID
        
    Returns:
        True if deleted, False if not found
    """
    try:
        OverrideQuery = Query()
        deleted = child_overrides_db.remove(
            (OverrideQuery.child_id == child_id) &
            (OverrideQuery.entity_id == entity_id)
        )
        if deleted:
            logger.info(f"Override deleted: child={child_id}, entity={entity_id}")
            return True
        return False
    except Exception as e:
        logger.error(f"Failed to delete override: {e}")
        raise


def delete_overrides_for_child(child_id: str) -> int:
    """
    Delete all overrides for a child.
    
    Args:
        child_id: Child ID
        
    Returns:
        Count of deleted overrides
    """
    try:
        OverrideQuery = Query()
        deleted = child_overrides_db.remove(OverrideQuery.child_id == child_id)
        count = len(deleted)
        if count > 0:
            logger.info(f"Overrides cascade deleted for child: child_id={child_id}, count={count}")
        return count
    except Exception as e:
        logger.error(f"Failed to delete overrides for child: {e}")
        raise


def delete_overrides_for_entity(entity_id: str) -> int:
    """
    Delete all overrides for an entity.
    
    Args:
        entity_id: Entity ID (task or reward)
        
    Returns:
        Count of deleted overrides
    """
    try:
        OverrideQuery = Query()
        deleted = child_overrides_db.remove(OverrideQuery.entity_id == entity_id)
        count = len(deleted)
        if count > 0:
            logger.info(f"Overrides cascade deleted for entity: entity_id={entity_id}, count={count}")
        return count
    except Exception as e:
        logger.error(f"Failed to delete overrides for entity: {e}")
        raise
