"""双库：源库与目标库各自独立的连接池。"""
from __future__ import annotations

from pathlib import Path

from sqlalchemy import create_engine, text
from sqlalchemy.engine import Engine
from sqlalchemy.orm import sessionmaker

from app.core.config import settings
from app.core.logger import logger
from app.models import SourceBase, TargetBase


def _sqlite_file_url(filename: str) -> str:
    """本地 SQLite 兜底：写到 data 目录下，避免相对路径受运行目录影响。"""
    path = Path(settings.data_dir) / filename
    path.parent.mkdir(parents=True, exist_ok=True)
    return f"sqlite:///{path.as_posix()}"


def _engine_kwargs() -> dict:
    return {
        "pool_pre_ping": True,
        "pool_size": settings.db_pool_size,
        "pool_recycle": settings.db_pool_recycle,
        "echo": settings.db_echo,
    }


def _build_engine(url: str) -> Engine:
    if url.startswith("sqlite"):
        connect_args = {"check_same_thread": False}
    elif url.startswith("mssql"):
        # SQL Server 默认强制加密且校验证书；腾讯云自签证书需关闭证书校验
        connect_args = {"TrustServerCertificate": "yes", "Encrypt": "yes"}
    else:
        connect_args = {}
    return create_engine(url, connect_args=connect_args, **_engine_kwargs())


source_url = settings.source_db_url or _sqlite_file_url("source.db")
target_url = settings.target_db_url or _sqlite_file_url("target.db")

source_engine = _build_engine(source_url)
target_engine = _build_engine(target_url)

SourceSessionLocal = sessionmaker(
    bind=source_engine, autocommit=False, autoflush=False, expire_on_commit=False
)
TargetSessionLocal = sessionmaker(
    bind=target_engine, autocommit=False, autoflush=False, expire_on_commit=False
)


def init_db() -> None:
    """创建已定义的表（幂等）。

    目标库（TARGET，本系统所有）始终建表；源库（SOURCE，外部只读）仅在本地
    SQLite 兜底时建表，避免向外部库发起 DDL。
    """
    TargetBase.metadata.create_all(bind=target_engine)
    if source_url.startswith("sqlite"):
        SourceBase.metadata.create_all(bind=source_engine)


def engine_health(engine: Engine) -> dict:
    with engine.connect() as conn:
        conn.execute(text("SELECT 1"))
    return {
        "ok": True,
        "dialect": engine.dialect.name,
        "url": engine.url.render_as_string(hide_password=True),
    }


def check_connections() -> dict:
    return {
        "source": engine_health(source_engine),
        "target": engine_health(target_engine),
    }


# logger.info("源库引擎: %s", source_engine.url.drivername)
# logger.info("目标库引擎: %s", target_engine.url.drivername)
