# #region TranslationResultAggregator [C:4] [TYPE Class] [SEMANTICS sqlalchemy, translate, query, history, records]
# @BRIEF Query translation run status, records, and history.
# @PRE Database session is available.
# @POST Returns structured run data with pagination.
# @RELATION DEPENDS_ON -> [TranslationRun]
# @RELATION DEPENDS_ON -> [TranslationBatch]
# @RELATION DEPENDS_ON -> [TranslationRecord]
# @RELATION DEPENDS_ON -> [TranslationRunLanguageStats]
# @RELATION DEPENDS_ON -> [TranslationEventLog]
# @RELATION DEPENDS_ON -> [EXT:frontend:orchestrator_lang_stats]
# @RELATION DEPENDS_ON -> [orchestrator_query]
# @RATIONALE Language stats aggregation extracted to orchestrator_lang_stats; query methods to orchestrator_query.

from typing import Any

from sqlalchemy.orm import Session

from ...core.logger import belief_scope
from ...models.translate import (
    TranslationBatch,
    TranslationRun,
    TranslationRunLanguageStats,
)
from .events import TranslationEventLog
from .orchestrator_lang_stats import update_language_stats
from .orchestrator_query import get_run_history as _get_run_history, get_run_records as _get_run_records


class TranslationResultAggregator:
    """Query run status, records, history, and language statistics."""

    def __init__(self, db: Session, event_log: TranslationEventLog):
        self.db = db
        self.event_log = event_log

    # region get_run_status [TYPE Function]
    # @PURPOSE: Get run status with statistics.
    def get_run_status(self, run_id: str) -> dict[str, Any]:
        with belief_scope("TranslationResultAggregator.get_run_status"):
            run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()
            if not run:
                raise ValueError(f"Run '{run_id}' not found")

            batch_count = (
                self.db.query(TranslationBatch)
                .filter(TranslationBatch.run_id == run_id)
                .count()
            )
            event_summary = self.event_log.get_run_event_summary(run_id)

            language_stats_entries = (
                self.db.query(TranslationRunLanguageStats)
                .filter(TranslationRunLanguageStats.run_id == run_id)
                .all()
            )
            language_stats = [
                {
                    "language_code": ls.language_code,
                    "total_rows": ls.total_rows or 0,
                    "translated_rows": ls.translated_rows or 0,
                    "failed_rows": ls.failed_rows or 0,
                    "skipped_rows": ls.skipped_rows or 0,
                    "token_count": ls.token_count or 0,
                    "estimated_cost": ls.estimated_cost or 0.0,
                }
                for ls in language_stats_entries
            ]

            return {
                "id": run.id,
                "job_id": run.job_id,
                "status": run.status,
                "trigger_type": run.trigger_type,
                "started_at": run.started_at.isoformat() if run.started_at else None,
                "completed_at": run.completed_at.isoformat() if run.completed_at else None,
                "error_message": run.error_message,
                "total_records": run.total_records or 0,
                "successful_records": run.successful_records or 0,
                "failed_records": run.failed_records or 0,
                "skipped_records": run.skipped_records or 0,
                "insert_status": run.insert_status,
                "superset_execution_id": run.superset_execution_id,
                "batch_count": batch_count,
                "language_stats": language_stats,
                "event_invariants": {
                    "has_run_started": event_summary["has_run_started"],
                    "terminal_event_count": event_summary["terminal_event_count"],
                    "invariant_valid": event_summary["invariant_valid"],
                },
                "created_by": run.created_by,
                "created_at": run.created_at.isoformat() if run.created_at else None,
            }
    # endregion get_run_status

    # region get_run_records [TYPE Function]
    # @PURPOSE: Get paginated records for a run.
    def get_run_records(
        self,
        run_id: str,
        page: int = 1,
        page_size: int = 50,
        status_filter: str | None = None,
    ) -> dict[str, Any]:
        with belief_scope("TranslationResultAggregator.get_run_records"):
            return _get_run_records(self.db, run_id, page, page_size, status_filter)
    # endregion get_run_records

    # region get_run_history [TYPE Function]
    # @PURPOSE: Get run history for a job.
    def get_run_history(
        self,
        job_id: str,
        page: int = 1,
        page_size: int = 20,
    ) -> tuple[int, list[dict[str, Any]]]:
        with belief_scope("TranslationResultAggregator.get_run_history"):
            return _get_run_history(self.db, job_id, page, page_size)
    # endregion get_run_history

    # region update_language_stats [TYPE Function]
    # @PURPOSE: Aggregate TranslationLanguage entries and update TranslationRunLanguageStats.
    # @SIDE_EFFECT  DB writes on language_stats objects.
    def update_language_stats(
        self,
        run_id: str,
        language_stats_map: dict[str, TranslationRunLanguageStats],
    ) -> None:
        with belief_scope("TranslationResultAggregator.update_language_stats"):
            update_language_stats(
                db=self.db,
                event_log=self.event_log,
                run_id=run_id,
                language_stats_map=language_stats_map,
            )
    # endregion update_language_stats

# #endregion TranslationResultAggregator
