# -*- coding: utf-8 -*-
"""
@File    : __init__.py
@Author  : Jay
@Date    : 2025/3/16 14:37
@Desc    : Redis client registry and default instance setup
"""
import asyncio

# Set Windows event loop policy to avoid runtime errors on Windows
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

from collections import defaultdict
from typing import Optional, Union

from .rxcore import RedisXsync

# Registry of Redis instances keyed by label
_redis_registry: defaultdict[str, RedisXsync] = defaultdict(RedisXsync)

# Global default Redis instance
redisXsync: Optional[RedisXsync] = RedisXsync(host="localhost", port=6379, db=-1)


class RedisNotInstantiatedError(Exception):
    """Raised when trying to access a Redis instance that hasn't been registered."""
    pass


def register_redis(label: str, host: str = None, port: int = None, db: Union[str, int] = None,
                   password: Optional[str] = None, decode_responses: bool = None, **kwargs) -> RedisXsync:
    """Register a Redis instance in the global registry.

    If no global default exists, the first registered instance becomes the default.

    Args:
        label (str): Unique identifier for the Redis instance.
        host (str, optional): Redis server host.
        port (int, optional): Redis server port.
        db (int|str, optional): Redis database index.
        password (str, optional): Redis password.
        decode_responses (bool, optional): Whether to decode byte responses.
        **kwargs: Additional Redis configuration parameters.

    Returns:
        RedisXsync: The registered Redis client instance.
    """
    global redisXsync
    rx = RedisXsync(
        host=host, port=port,
        db=db, password=password,
        decode_responses=decode_responses,
        **kwargs
    )
    # Set the first registered instance as the default if none exists
    if not _redis_registry:
        redisXsync.rxs = rx.rxs
    _redis_registry.setdefault(label, rx)
    return _redis_registry[label]


def resolve_redis(label: str = None) -> RedisXsync:
    """Resolve a registered Redis instance by label.

    Args:
        label (str, optional): The label of the Redis instance. If None, returns the first registered instance.

    Returns:
        RedisXsync: The resolved Redis client instance.

    Raises:
        RedisNotInstantiatedError: If no instance with the given label is registered.
    """
    if label is None and _redis_registry:
        return next(iter(_redis_registry.values()))
    r = _redis_registry.get(label)
    if r:
        return r
    raise RedisNotInstantiatedError(f"No Redis instance registered with label '{label}'")


__all__ = ["register_redis", "resolve_redis", "RedisXsync", "redisXsync"]
