# #region PreviewSessionManager [C:3] [TYPE Class] [SEMANTICS preview, session, review, approve]
# @BRIEF Manage preview session row-level actions: approve/edit/reject rows.
# @RELATION DEPENDS_ON -> [TranslationPreviewSession]
# @RELATION DEPENDS_ON -> [TranslationPreviewRecord]
# @RELATION DEPENDS_ON -> [TranslationPreviewLanguage]
# @RELATION DEPENDS_ON -> [preview_session_ops]
# @RATIONALE Session accept/get and serialization extracted to preview_session_ops module for INV_7 compliance.

from typing import Any

from sqlalchemy.orm import Session

from ...core.logger import belief_scope
from ...models.translate import (
    TranslationPreviewLanguage,
    TranslationPreviewRecord,
    TranslationPreviewSession,
)
from .preview_session_ops import (
    accept_preview_session as _accept_preview_session,
    apply_language_action as _apply_language_action,
    apply_record_action as _apply_record_action,
    get_preview_session as _get_preview_session,
)


class PreviewSessionManager:
    """Manage preview session lifecycle: row actions, accept, query."""

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

    # region update_preview_row [TYPE Function]
    # @PURPOSE: Approve, edit, or reject an individual preview row (optionally per language).
    def update_preview_row(
        self,
        job_id: str,
        row_id: str,
        action: str,
        translation: str | None = None,
        feedback: str | None = None,
        language_code: str | None = None,
    ) -> dict[str, Any]:
        with belief_scope("PreviewSessionManager.update_preview_row"):
            session = (
                self.db.query(TranslationPreviewSession)
                .filter(
                    TranslationPreviewSession.job_id == job_id,
                    TranslationPreviewSession.status == "ACTIVE",
                )
                .order_by(TranslationPreviewSession.created_at.desc())
                .first()
            )
            if not session:
                raise ValueError(f"No active preview session for job '{job_id}'")

            record = (
                self.db.query(TranslationPreviewRecord)
                .filter(
                    TranslationPreviewRecord.id == row_id,
                    TranslationPreviewRecord.session_id == session.id,
                )
                .first()
            )
            if not record:
                raise ValueError(f"Preview record '{row_id}' not found in active session")

            if language_code:
                lang_entry = (
                    self.db.query(TranslationPreviewLanguage)
                    .filter(
                        TranslationPreviewLanguage.preview_record_id == row_id,
                        TranslationPreviewLanguage.language_code == language_code,
                    )
                    .first()
                )
                if not lang_entry:
                    raise ValueError(
                        f"Language entry '{language_code}' not found for record '{row_id}'"
                    )
                _apply_language_action(lang_entry, action, translation)

                all_langs = (
                    self.db.query(TranslationPreviewLanguage)
                    .filter(TranslationPreviewLanguage.preview_record_id == row_id)
                    .all()
                )
                if all(le.status in ("approved", "edited") for le in all_langs):
                    record.status = "APPROVED"
                if action == "edit" and translation is not None and all_langs:
                    record.target_sql = all_langs[0].final_value or all_langs[0].translated_value
            else:
                _apply_record_action(record, action, translation)

            if feedback is not None:
                record.feedback = feedback

            self.db.commit()
            self.db.refresh(record)

            return {
                "id": record.id,
                "source_sql": record.source_sql,
                "target_sql": record.target_sql,
                "status": record.status,
                "feedback": record.feedback,
                "languages": [
                    {
                        "language_code": le.language_code,
                        "source_language_detected": le.source_language_detected,
                        "translated_value": le.translated_value,
                        "final_value": le.final_value,
                        "user_edit": le.user_edit,
                        "status": le.status,
                        "needs_review": le.needs_review,
                    }
                    for le in (record.languages or [])
                ],
            }
    # endregion update_preview_row

    # region accept_preview_session [TYPE Function]
    # @PURPOSE: Mark a preview session as accepted, which gates full execution.
    def accept_preview_session(self, job_id: str) -> dict[str, Any]:
        with belief_scope("PreviewSessionManager.accept_preview_session"):
            return _accept_preview_session(self.db, job_id)
    # endregion accept_preview_session

    # region get_preview_session [TYPE Function]
    # @PURPOSE: Get the latest preview session for a job with its records.
    def get_preview_session(self, job_id: str) -> dict[str, Any]:
        with belief_scope("PreviewSessionManager.get_preview_session"):
            return _get_preview_session(self.db, job_id)
    # endregion get_preview_session

# #endregion PreviewSessionManager
