import os
import json
import logging
from datetime import datetime, timezone
from typing import Optional, Any, Dict
from config import config

from core.logging import get_logger

logger = get_logger(__name__)
_HAS_STRUCTLOG = True


def _log_info(event: str, **kwargs):
    """Log info with structlog or standard logging compatibility."""
    if _HAS_STRUCTLOG:
        logger.info(event, **kwargs)
    else:
        msg = f"{event} " + " ".join(f"{k}={v}" for k, v in kwargs.items())
        logger.info(msg)


def _log_error(event: str, **kwargs):
    """Log error with structlog or standard logging compatibility."""
    if _HAS_STRUCTLOG:
        logger.error(event, **kwargs)
    else:
        msg = f"{event} " + " ".join(f"{k}={v}" for k, v in kwargs.items())
        logger.error(msg)


# Key pattern: translation:file:{job_id}
KEY_PREFIX = "translation:file"


def _get_default_ttl() -> int:
    """Get TTL from config or default to 60 minutes."""
    try:
        return config.FILE_TTL_MINUTES * 60
    except Exception:
        return 3600  # 60 minutes default


def _get_async_redis():
    """Return shared async Redis client from core.redis."""
    from core.redis import get_async_redis

    return get_async_redis()


class StorageTracker:
    """
    Tracks file locations and metadata in Redis.
    Pattern: translation:file:{job_id} -> JSON metadata
    """

    def __init__(self):
        self._redis = None

    def _redis_client(self):
        if self._redis is None:
            self._redis = _get_async_redis()
        return self._redis

    async def track_file(
        self, job_id: str, metadata: Dict[str, Any], ttl: Optional[int] = None
    ) -> bool:
        """
        Store file metadata in Redis with TTL and log the upload.
        """
        if ttl is None:
            ttl = _get_default_ttl()

        # Ensure timestamp is present
        if "timestamp" not in metadata:
            metadata["timestamp"] = datetime.now(timezone.utc).isoformat()

        # Log metadata (no content)
        _log_info(
            "file_uploaded",
            job_id=job_id,
            original_filename=metadata.get("original_filename"),
            file_size=metadata.get("file_size"),
            file_hash=metadata.get("file_hash"),
            user_id=metadata.get("user_id"),
            timestamp=metadata.get("timestamp"),
        )

        redis_client = self._redis_client()
        if not redis_client:
            _log_error(
                "redis_not_available", job_id=job_id, hint="File tracked in logs only"
            )
            return False

        try:
            key = f"{KEY_PREFIX}:{job_id}"
            await redis_client.set(key, json.dumps(metadata), ex=ttl)
            _log_info("file_tracked_in_redis", job_id=job_id, ttl_seconds=ttl)
            return True
        except Exception as e:
            _log_error("redis_track_failed", job_id=job_id, error=str(e))
            return False

    async def get_file_metadata(self, job_id: str) -> Optional[Dict[str, Any]]:
        """
        Retrieve file metadata from Redis.
        """
        redis_client = self._redis_client()
        if not redis_client:
            return None

        try:
            key = f"{KEY_PREFIX}:{job_id}"
            data = await redis_client.get(key)
            return json.loads(data) if data else None
        except Exception as e:
            _log_error("redis_get_failed", job_id=job_id, error=str(e))
            return None


# Singleton for app use
storage_tracker = StorageTracker()
