from datetime import datetime

from sqlalchemy.orm import Session

from app.models import SystemSetting

PDF_GENERATION_CONCURRENCY_KEY = "pdf_generation_concurrency_limit"
DEFAULT_PDF_GENERATION_CONCURRENCY = 2
MIN_PDF_GENERATION_CONCURRENCY = 1
MAX_PDF_GENERATION_CONCURRENCY = 10


def ensure_default_settings(db: Session) -> None:
    if not db.get(SystemSetting, PDF_GENERATION_CONCURRENCY_KEY):
        db.add(
            SystemSetting(
                key=PDF_GENERATION_CONCURRENCY_KEY,
                value=str(DEFAULT_PDF_GENERATION_CONCURRENCY),
                description="PDF证书同时生成数量限制",
            )
        )


def get_pdf_generation_concurrency_limit(db: Session) -> int:
    setting = db.get(SystemSetting, PDF_GENERATION_CONCURRENCY_KEY)
    return _coerce_limit(setting.value if setting else None)


def get_pdf_settings(db: Session) -> dict[str, object]:
    ensure_default_settings(db)
    setting = db.get(SystemSetting, PDF_GENERATION_CONCURRENCY_KEY)
    return {
        "pdf_generation_concurrency_limit": get_pdf_generation_concurrency_limit(db),
        "updated_at": setting.updated_at if setting else None,
    }


def update_pdf_generation_concurrency_limit(db: Session, value: int) -> dict[str, object]:
    limit = _coerce_limit(value)
    ensure_default_settings(db)
    setting = db.get(SystemSetting, PDF_GENERATION_CONCURRENCY_KEY)
    if setting is None:
        setting = SystemSetting(
            key=PDF_GENERATION_CONCURRENCY_KEY,
            value=str(limit),
            description="PDF证书同时生成数量限制",
        )
        db.add(setting)
    else:
        setting.value = str(limit)
        setting.updated_at = datetime.utcnow()
    db.flush()
    return {
        "pdf_generation_concurrency_limit": limit,
        "updated_at": setting.updated_at,
    }


def _coerce_limit(value: object) -> int:
    try:
        limit = int(value)
    except (TypeError, ValueError):
        limit = DEFAULT_PDF_GENERATION_CONCURRENCY
    return max(MIN_PDF_GENERATION_CONCURRENCY, min(MAX_PDF_GENERATION_CONCURRENCY, limit))
