"""
Check for SQLCipher availability and provide fallback options.
"""

import warnings
from typing import Optional, Tuple

from loguru import logger


def check_sqlcipher_available() -> Tuple[bool, Optional[str]]:
    """
    Check if SQLCipher is available for use.

    Returns:
        Tuple of (is_available, error_message)
    """
    try:
        # Try to import sqlcipher3 (covers both sqlcipher3 and sqlcipher3-binary)
        import importlib.util

        if importlib.util.find_spec("sqlcipher3") is not None:
            return True, None
    except ImportError:
        pass

    # Check if sqlcipher command is available
    import subprocess

    try:
        result = subprocess.run(
            ["sqlcipher", "--version"],
            capture_output=True,
            text=True,
            timeout=5,
        )
        if result.returncode == 0:
            return (
                False,
                "SQLCipher is installed but Python bindings are missing. Reinstall the project with: pdm install",
            )
    except (subprocess.TimeoutExpired, FileNotFoundError):
        pass

    return (
        False,
        "SQLCipher is not installed. See docs/SQLCIPHER_INSTALL.md for installation instructions.",
    )


def warn_if_no_encryption():
    """Warn user if encryption is not available."""
    available, message = check_sqlcipher_available()

    if not available:
        warning_msg = (
            "\n" + "=" * 60 + "\n"
            "⚠️  SECURITY WARNING: Database Encryption Not Available\n"
            + "="
            * 60
            + "\n"
            f"{message}\n\n"
            "Your data will be stored in UNENCRYPTED SQLite databases.\n"
            "This means:\n"
            "  - API keys are stored in plain text\n"
            "  - Research data is not encrypted at rest\n"
            "  - Anyone with file system access can read your data\n\n"
            "For production use, we strongly recommend installing SQLCipher.\n"
            + "="
            * 60
        )

        warnings.warn(warning_msg, category=UserWarning, stacklevel=2)
        logger.warning(
            "Running without database encryption - SQLCipher not available"
        )

    return available


def get_connection_string(db_path: str, password: Optional[str] = None) -> str:
    """
    Get the appropriate connection string based on SQLCipher availability.

    Args:
        db_path: Path to the database file
        password: Password for encryption (ignored if SQLCipher not available)

    Returns:
        SQLAlchemy connection string
    """
    available, _ = check_sqlcipher_available()

    if available and password:
        # Use encrypted connection
        return f"sqlite+pysqlcipher://:{password}@/{db_path}"
    else:
        # Fall back to regular SQLite
        if password:
            logger.warning(
                "Password provided but SQLCipher not available - using unencrypted database"
            )
        return f"sqlite:///{db_path}"
