"""
IMemoryProvider - 記憶體提供者介面
===================================

定義資料存取的標準介面

記憶層級:
- Working Memory (Redis): 7 天 TTL，快速存取
- Episodic Memory (PG/SQLite): 永久保存，可查詢

統帥鐵律:
- 禁止直接存取底層資料庫
- 所有存取必須透過 Provider 抽象
- 雙層寫入：Working + Episodic 同步
"""

from abc import ABC, abstractmethod
from typing import Any, TypeVar, Generic
from pydantic import BaseModel


T = TypeVar("T", bound=BaseModel)


class IMemoryProvider(ABC, Generic[T]):
    """
    記憶體提供者介面

    職責:
    1. 提供統一的資料存取抽象
    2. 隱藏底層實作細節 (Redis/PG/SQLite)
    3. 支援 TTL 與永久保存

    使用方式:
        class RedisMemory(IMemoryProvider[Incident]):
            async def load(self, key: str) -> Incident | None:
                # 實作 Redis 存取
                pass

        class PgMemory(IMemoryProvider[Incident]):
            async def load(self, key: str) -> Incident | None:
                # 實作 PostgreSQL 存取
                pass
    """

    @abstractmethod
    async def load(self, key: str) -> T | None:
        """
        載入資料

        Args:
            key: 資料鍵值

        Returns:
            T | None: 資料物件或 None
        """
        ...

    @abstractmethod
    async def save(self, key: str, data: T, ttl_seconds: int | None = None) -> bool:
        """
        儲存資料

        Args:
            key: 資料鍵值
            data: 資料物件
            ttl_seconds: 過期時間 (秒)，None 表示永久

        Returns:
            bool: 是否成功
        """
        ...

    @abstractmethod
    async def delete(self, key: str) -> bool:
        """
        刪除資料

        Args:
            key: 資料鍵值

        Returns:
            bool: 是否成功
        """
        ...

    @abstractmethod
    async def exists(self, key: str) -> bool:
        """
        檢查資料是否存在

        Args:
            key: 資料鍵值

        Returns:
            bool: 是否存在
        """
        ...

    @abstractmethod
    async def update(self, key: str, updates: dict[str, Any]) -> bool:
        """
        部分更新資料

        Args:
            key: 資料鍵值
            updates: 要更新的欄位

        Returns:
            bool: 是否成功
        """
        ...


class IDualMemoryProvider(ABC, Generic[T]):
    """
    雙層記憶體提供者介面

    統帥鐵律：Working + Episodic 同步寫入

    使用方式:
        class DualMemory(IDualMemoryProvider[Incident]):
            def __init__(self):
                self.working = RedisMemory()
                self.episodic = PgMemory()

            async def save(self, key: str, data: Incident) -> bool:
                # 同時寫入 Redis + PG
                pass
    """

    @property
    @abstractmethod
    def working(self) -> IMemoryProvider[T]:
        """Working Memory Provider (Redis)"""
        ...

    @property
    @abstractmethod
    def episodic(self) -> IMemoryProvider[T]:
        """Episodic Memory Provider (PG/SQLite)"""
        ...

    @abstractmethod
    async def load(self, key: str) -> T | None:
        """
        載入資料 (Working 優先，Episodic 備援)

        Args:
            key: 資料鍵值

        Returns:
            T | None: 資料物件或 None
        """
        ...

    @abstractmethod
    async def save(self, key: str, data: T) -> bool:
        """
        雙層儲存 (Working + Episodic 同步)

        Args:
            key: 資料鍵值
            data: 資料物件

        Returns:
            bool: 是否成功
        """
        ...
