"""
Centralized database initialization module.

This module provides a single entry point for database initialization,
using Alembic for schema migrations and version control.
"""

from typing import Any, Optional
from loguru import logger
from sqlalchemy import Engine, inspect
from sqlalchemy.orm import Session

from ..database.models import Base
from .alembic_runner import run_migrations


def initialize_database(
    engine: Engine,
    db_session: Optional[Session] = None,
) -> None:
    """
    Initialize database tables if they don't exist.

    Uses Alembic migrations to create and update the database schema.

    Args:
        engine: SQLAlchemy engine for the database
        db_session: Optional database session for settings initialization
    """
    inspector = inspect(engine)
    existing_tables = inspector.get_table_names()

    logger.info(
        f"Initializing database with {len(existing_tables)} existing tables"
    )
    logger.debug(
        f"Base.metadata has {len(Base.metadata.tables)} tables defined"
    )

    # Run Alembic migrations (creates tables and applies schema changes)
    run_migrations(engine)

    # Check what was created (need new inspector to avoid caching)
    new_inspector = inspect(engine)
    new_tables = new_inspector.get_table_names()
    logger.info(f"After initialization: {len(new_tables)} tables exist")

    # Initialize default settings if session provided
    if db_session:
        try:
            _initialize_default_settings(db_session)
        except Exception:
            logger.warning("Could not initialize default settings")

    logger.info("Database initialization complete")


def _initialize_default_settings(db_session: Session) -> None:
    """
    Initialize default settings from the defaults file.

    Args:
        db_session: Database session to use for settings initialization
    """
    from ..settings.manager import SettingsManager

    try:
        settings_mgr = SettingsManager(db_session)

        # Check if we need to update settings
        if settings_mgr.db_version_matches_package():
            logger.debug("Settings version matches package, skipping update")
            return

        logger.info("Loading default settings into database")

        # Load settings from defaults file
        # This will not overwrite existing settings but will add new ones
        settings_mgr.load_from_defaults_file(overwrite=False, delete_extra=True)

        # Update the saved version
        settings_mgr.update_db_version()

        logger.info("Default settings initialized successfully")

    except Exception:
        logger.exception("Error initializing default settings")


def check_database_schema(engine: Engine) -> dict:
    """
    Check the current database schema and return information about tables.

    Args:
        engine: SQLAlchemy engine for the database

    Returns:
        Dictionary with schema information including tables and their columns
    """
    inspector = inspect(engine)
    schema_info: dict[str, Any] = {
        "tables": {},
        "missing_tables": [],
        "has_news_tables": False,
    }

    # Tables that only exist in the auth database, not per-user databases
    auth_only_tables = {"users"}

    # Check core tables
    for table_name in Base.metadata.tables.keys():
        if table_name in auth_only_tables:
            continue
        if inspector.has_table(table_name):
            columns = [col["name"] for col in inspector.get_columns(table_name)]
            schema_info["tables"][table_name] = columns
        else:
            schema_info["missing_tables"].append(table_name)

    # Check if news tables exist
    news_tables = ["news_subscription", "news_card", "news_interest"]
    for table_name in news_tables:
        if table_name in schema_info["tables"]:
            schema_info["has_news_tables"] = True
            break

    return schema_info
