"""Celery task: refresh the sales-tracker MVs (Issue #61).

Scheduled via hardcoded beat entry in workers/beat_schedule.py:
  'mv-sales-tracker-refresh-weekly' — weekly on Monday at 04:30 MSK.

Refreshes (both CONCURRENTLY, non-blocking):
  - mv_sales_tracker_velocity_by_district  (Site Finder Velocity Score, 4th criterion)
  - mv_sales_tracker_absorption_curves     (recommend_mix + sellout forecast foundation)

Both MVs are built from the Объектив sales-tracker ("шахматки") snapshots
(objective_lots / objective_lots_history). Source data refreshes via the
objective_sync beat job, so a weekly MV refresh keeps the aggregates current.

MV-source migration: data/sql/164_mv_sales_tracker_velocity_absorption.sql.
"""

from __future__ import annotations

import logging
from typing import Any

from app.core.db import SessionLocal
from app.services.site_finder.sales_tracker_mv_refresh import refresh_sales_tracker_mvs
from app.workers.celery_app import celery_app

logger = logging.getLogger(__name__)


@celery_app.task(
    bind=True,
    name="tasks.mv_sales_tracker_refresh.refresh_sales_tracker_mvs",
    max_retries=2,
)
def refresh_sales_tracker_mvs_task(self: Any) -> dict[str, Any]:
    """REFRESH both sales-tracker MVs (#61).

    Both MVs are refreshed CONCURRENTLY (non-blocking, require their UNIQUE
    indexes created by migration 161); the service falls back to non-concurrent
    if an MV is found unpopulated (first-run edge case).

    Returns result dict for the Celery task result store / logging.
    """
    db = SessionLocal()
    try:
        counts = refresh_sales_tracker_mvs(db, concurrently=True)
        logger.info("refresh_sales_tracker_mvs: completed, rows=%s", counts)
        return {"status": "ok", "rows": counts}
    except Exception as e:
        logger.exception("refresh_sales_tracker_mvs failed: %s", e)
        raise
    finally:
        db.close()
