"""
Abstract Base Classes (Protocols) for Dependency Injection
Defines interfaces that can be mocked for testing.
"""

from typing import List, Dict, Any, Optional, Protocol


class PlayerData(Dict):
    """Player data structure matching Peewee model."""
    pass


class TeamData(Dict):
    """Team data structure matching Peewee model."""
    pass


class QueryResult(Protocol):
    """Protocol for query-like objects."""
    
    def where(self, *conditions) -> 'QueryResult':
        ...
    
    def order_by(self, *fields) -> 'QueryResult':
        ...
    
    def count(self) -> int:
        ...
    
    def __iter__(self):
        ...
    
    def __len__(self) -> int:
        ...


class CacheProtocol(Protocol):
    """Protocol for cache operations."""
    
    def get(self, key: str) -> Optional[str]:
        ...
    
    def setex(self, key: str, ttl: int, value: str) -> bool:
        ...
    
    def keys(self, pattern: str) -> List[str]:
        ...
    
    def delete(self, *keys: str) -> int:
        ...


class AbstractPlayerRepository(Protocol):
    """Abstract interface for player data access."""
    
    def select_season(self, season: int) -> QueryResult:
        ...
    
    def get_by_id(self, player_id: int) -> Optional[PlayerData]:
        ...
    
    def get_or_none(self, *conditions) -> Optional[PlayerData]:
        ...
    
    def update(self, data: Dict, *conditions) -> int:
        ...
    
    def insert_many(self, data: List[Dict]) -> int:
        ...
    
    def delete_by_id(self, player_id: int) -> int:
        ...


class AbstractTeamRepository(Protocol):
    """Abstract interface for team data access."""
    
    def select_season(self, season: int) -> QueryResult:
        ...
    
    def get_by_id(self, team_id: int) -> Optional[TeamData]:
        ...
    
    def get_or_none(self, *conditions) -> Optional[TeamData]:
        ...
    
    def update(self, data: Dict, *conditions) -> int:
        ...
    
    def insert_many(self, data: List[Dict]) -> int:
        ...
    
    def delete_by_id(self, team_id: int) -> int:
        ...


class AbstractCacheService(Protocol):
    """Abstract interface for cache operations."""
    
    def get(self, key: str) -> Optional[str]:
        ...
    
    def set(self, key: str, value: str, ttl: int = 300) -> bool:
        ...
    
    def invalidate_pattern(self, pattern: str) -> int:
        ...
    
    def exists(self, key: str) -> bool:
        ...
