"""SQLite schema management for VibeDB internal tables."""

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from vibedb.storage.engine import StorageEngine


# VibeDB internal table schemas
META_TABLE_SQL = """
CREATE TABLE IF NOT EXISTS _vibedb_meta (
    key TEXT PRIMARY KEY,
    value JSON NOT NULL
)
"""

COLLECTIONS_TABLE_SQL = """
CREATE TABLE IF NOT EXISTS _vibedb_collections (
    name TEXT PRIMARY KEY,
    created_at INTEGER NOT NULL,
    document_count INTEGER DEFAULT 0,
    schema JSON,
    config JSON
)
"""

INDEXES_TABLE_SQL = """
CREATE TABLE IF NOT EXISTS _vibedb_indexes (
    id TEXT PRIMARY KEY,
    collection TEXT NOT NULL,
    name TEXT NOT NULL,
    fields JSON NOT NULL,
    unique_index INTEGER DEFAULT 0,
    created_at INTEGER NOT NULL,
    UNIQUE(collection, name)
)
"""

SLOW_QUERIES_TABLE_SQL = """
CREATE TABLE IF NOT EXISTS _vibedb_slow_queries (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    collection TEXT NOT NULL,
    query JSON NOT NULL,
    execution_time_ms REAL NOT NULL,
    timestamp INTEGER NOT NULL,
    suggested_indexes JSON
)
"""


def get_collection_table_sql(collection_name: str) -> str:
    """
    Get SQL to create a collection's document table.

    Args:
        collection_name: Name of the collection

    Returns:
        str: CREATE TABLE SQL statement
    """
    # Sanitize collection name (basic protection)
    safe_name = collection_name.replace('"', '""')

    return f"""
    CREATE TABLE IF NOT EXISTS "{safe_name}_docs" (
        _id TEXT PRIMARY KEY,
        _createdAt INTEGER NOT NULL,
        _updatedAt INTEGER NOT NULL,
        _doc JSON NOT NULL
    )
    """


def init_database_schema(engine: "StorageEngine"):
    """
    Initialize VibeDB internal schema.

    Creates all metadata tables needed for VibeDB operation.

    Args:
        engine: Storage engine instance

    Raises:
        DatabaseError: If schema initialization fails
    """
    # Create metadata table
    engine.execute(META_TABLE_SQL)

    # Create collections registry
    engine.execute(COLLECTIONS_TABLE_SQL)

    # Create indexes registry
    engine.execute(INDEXES_TABLE_SQL)

    # Create slow queries log
    engine.execute(SLOW_QUERIES_TABLE_SQL)

    # Set database version in metadata
    from vibedb.__version__ import __version__
    engine.execute(
        "INSERT OR REPLACE INTO _vibedb_meta (key, value) VALUES (?, ?)",
        ('version', f'"{__version__}"')
    )

    # Commit changes
    engine.commit()


def create_collection_table(engine: "StorageEngine", collection_name: str):
    """
    Create table for a new collection.

    Args:
        engine: Storage engine instance
        collection_name: Name of the collection

    Raises:
        DatabaseError: If table creation fails
    """
    from vibedb.utils import current_timestamp

    # Create document table
    sql = get_collection_table_sql(collection_name)
    engine.execute(sql)

    # Register collection in metadata
    engine.execute(
        """
        INSERT OR IGNORE INTO _vibedb_collections
        (name, created_at, document_count, schema, config)
        VALUES (?, ?, 0, NULL, NULL)
        """,
        (collection_name, current_timestamp())
    )

    engine.commit()


def drop_collection_table(engine: "StorageEngine", collection_name: str):
    """
    Drop a collection's table and remove from registry.

    Args:
        engine: Storage engine instance
        collection_name: Name of the collection

    Raises:
        DatabaseError: If table drop fails
    """
    # Sanitize collection name
    safe_name = collection_name.replace('"', '""')

    # Drop document table
    engine.execute(f'DROP TABLE IF EXISTS "{safe_name}_docs"')

    # Remove from collections registry
    engine.execute(
        "DELETE FROM _vibedb_collections WHERE name = ?",
        (collection_name,)
    )

    # Remove associated indexes from registry
    engine.execute(
        "DELETE FROM _vibedb_indexes WHERE collection = ?",
        (collection_name,)
    )

    engine.commit()


def collection_exists(engine: "StorageEngine", collection_name: str) -> bool:
    """
    Check if a collection exists.

    Args:
        engine: Storage engine instance
        collection_name: Name of the collection

    Returns:
        bool: True if collection exists, False otherwise
    """
    result = engine.execute(
        "SELECT 1 FROM _vibedb_collections WHERE name = ? LIMIT 1",
        (collection_name,),
        fetch='one'
    )
    return result is not None


def list_collections(engine: "StorageEngine") -> list[str]:
    """
    List all collections in the database.

    Args:
        engine: Storage engine instance

    Returns:
        list[str]: List of collection names
    """
    results = engine.execute(
        "SELECT name FROM _vibedb_collections ORDER BY name",
        fetch='all'
    )
    return [row['name'] for row in results] if results else []


def get_collection_info(engine: "StorageEngine", collection_name: str) -> dict:
    """
    Get metadata about a collection.

    Args:
        engine: Storage engine instance
        collection_name: Name of the collection

    Returns:
        dict: Collection metadata or None if not found
    """
    return engine.execute(
        "SELECT * FROM _vibedb_collections WHERE name = ?",
        (collection_name,),
        fetch='one'
    )


def update_document_count(
    engine: "StorageEngine",
    collection_name: str,
    delta: int
):
    """
    Update the document count for a collection.

    Args:
        engine: Storage engine instance
        collection_name: Name of the collection
        delta: Change in document count (+1 for insert, -1 for delete)
    """
    engine.execute(
        """
        UPDATE _vibedb_collections
        SET document_count = document_count + ?
        WHERE name = ?
        """,
        (delta, collection_name)
    )


def set_collection_schema(
    engine: "StorageEngine",
    collection_name: str,
    schema: str  # JSON string
):
    """
    Set validation schema for a collection.

    Args:
        engine: Storage engine instance
        collection_name: Name of the collection
        schema: JSON schema as string
    """
    engine.execute(
        "UPDATE _vibedb_collections SET schema = ? WHERE name = ?",
        (schema, collection_name)
    )
    engine.commit()


def get_collection_schema(engine: "StorageEngine", collection_name: str) -> str:
    """
    Get validation schema for a collection.

    Args:
        engine: Storage engine instance
        collection_name: Name of the collection

    Returns:
        str: JSON schema string or None
    """
    result = engine.execute(
        "SELECT schema FROM _vibedb_collections WHERE name = ?",
        (collection_name,),
        fetch='one'
    )
    return result['schema'] if result else None
