import urllib.request
import json
from .logger import get_logger
from pathlib import Path
from datetime import datetime, timedelta
from ._version import __version__
import threading

logger = get_logger(f"dracula.{__name__}")

CACHE_FILE = Path.home() / ".dracula" / ".version_cache.json"


def _save_cache(latest_version: str):
    """Save the version check result to cache."""

    try:
        CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
        data = {
            "latest_version": latest_version,
            "last_checked": datetime.now().isoformat(),
        }
        CACHE_FILE.write_text(json.dumps(data, indent=4), encoding="utf-8")

    except Exception:
        pass


def _get_valid_cache() -> dict | None:
    """Return the cache if it's valid, otherwise None."""
    try:
        if CACHE_FILE.exists():
            data = json.loads(CACHE_FILE.read_text(encoding="utf-8"))
            last_checked = datetime.fromisoformat(data["last_checked"])
            if datetime.now() - last_checked < timedelta(hours=24):
                return data
    except Exception:
        pass
    return None


def _get_latest_version() -> str | None:
    """Fetch the latest version from PyPI or cache."""

    try:
        cache = _get_valid_cache
        if cache():
            logger.debug("Version check loaded from cache.")
            return cache["latest_version"]

        url = "https://pypi.org/pypi/dracula-ai/json"
        with urllib.request.urlopen(url, timeout=3) as response:
            data = json.loads(response.read().decode())
            latest_version = data["info"]["version"]

        _save_cache(latest_version)
        logger.debug(f"Version check fetched from PyPI: {latest_version}")
        return latest_version

    except Exception:
        pass


def check_latest_version(current_version: str):
    """
    Check if a newer version of Dracula is available on PyPI.
    Results are cached for 24 hours to avoid unnecessary requests.

    Args:
        current_version (str): The currently installed version.
    """

    def _run_check():
        latest_version = _get_latest_version()
        if not latest_version:
            return

        current_parts = [int(x) for x in current_version.split(".")]
        latest_parts = [int(x) for x in latest_version.split(".")]

        if latest_parts > current_parts:
            logger.warning(
                f"A new version of Dracula is available: v{latest_version} "
                f"(you have v{current_version}). "
                f"Upgrade with: pip install --upgrade dracula-ai"
            )

    thread = threading.Thread(target=_run_check, daemon=True)
    thread.start()
