"""Celery task: refresh developer_registry materialized view (#1088 «GG-форсайт»).

Вызывает ``fn_refresh_developer_registry()`` (миграция 149,
``data/sql/149_developer_attribution.sql``) — REFRESH MATERIALIZED VIEW CONCURRENTLY
``developer_registry`` (реестр застройщиков по норм-ИНН: канон-имя + track-record
permits+domrf). CONCURRENTLY не блокирует SELECT-читателей (analyze) во время refresh.

Scheduled via hardcoded beat entry в workers/beat_schedule.py:
  'developer-registry-refresh-monthly' — ежемесячно 1-го числа в 05:30 МСК,
  через 30 мин после 'ekburg-permits-monthly' (05:00 МСК), чтобы permits-сторона
  реестра обновлялась на свежих РНС/РВЭ. domrf-сторона обновляется ежедневно
  (scrape_kn), но ИНН/track-record застройщиков меняются редко — monthly refresh
  реестра с запасом достаточно (резолвер всё равно читает domrf-quarter напрямую).

Issue: #1088.
"""

from __future__ import annotations

import logging
from typing import Any

from sqlalchemy import text

from app.core.db import SessionLocal
from app.workers.celery_app import celery_app

logger = logging.getLogger(__name__)


@celery_app.task(
    bind=True,
    name="tasks.developer_registry_refresh.refresh_developer_registry",
    max_retries=2,
)
def refresh_developer_registry(self: Any) -> dict[str, Any]:
    """REFRESH MATERIALIZED VIEW CONCURRENTLY developer_registry.

    Лёгкая задача (реестр ~1024 застройщика). CONCURRENTLY — non-blocking для
    читателей analyze; требует unique-индекс uq_developer_registry_inn (создан
    миграцией 149). Возвращает row-count реестра после refresh для observability.

    Returns:
        dict для Celery result store / логирования.
    """
    db = SessionLocal()
    try:
        db.execute(text("SELECT fn_refresh_developer_registry()"))
        db.commit()
        row = db.execute(text("SELECT COUNT(*) FROM developer_registry")).first()
        count = int(row[0]) if row else 0
        logger.info("refresh_developer_registry: completed, developers=%d", count)
        return {"status": "ok", "developer_registry_rows": count}
    except Exception as e:
        logger.exception("refresh_developer_registry failed: %s", e)
        raise
    finally:
        db.close()
