"""파이프라인 진행률 추적 — UI에서 폴링하여 표시."""

import uuid
from datetime import datetime, timezone
from typing import Optional

from sqlalchemy.orm import Session as OrmSession

from app.models.project import PipelineProgress


def _now() -> str:
    return datetime.now(timezone.utc).isoformat()


class ProgressTracker:
    """파이프라인 진행률 추적 — UI에서 폴링하여 표시.

    Usage::

        tracker = ProgressTracker(db, episode_id, "analysis", project_id)
        tracker.update("엔티티 추출 중", 0, 2)
        # ... work ...
        tracker.update("씬 스틸 추출 중", 1, 2)
        # ... work ...
        tracker.complete()
    """

    def __init__(
        self,
        db_session: OrmSession,
        episode_id: str,
        operation: str,
        project_id: str = "",
    ) -> None:
        self._db = db_session
        now = _now()
        self._progress = PipelineProgress(
            id=str(uuid.uuid4()),
            project_id=project_id,
            episode_id=episode_id,
            operation=operation,
            status="running",
            current_step="",
            total_steps=0,
            completed_steps=0,
            started_at=now,
            updated_at=now,
        )
        self._db.add(self._progress)
        self._db.commit()

    @property
    def progress_id(self) -> str:
        return self._progress.id

    def update(
        self,
        step: str,
        completed: Optional[int] = None,
        total: Optional[int] = None,
    ) -> None:
        """진행 단계 업데이트. 즉시 커밋하여 폴링에 반영."""
        self._progress.current_step = step
        if completed is not None:
            self._progress.completed_steps = completed
        if total is not None:
            self._progress.total_steps = total
        self._progress.updated_at = _now()
        self._db.commit()

    def complete(self) -> None:
        """작업 완료 표시."""
        now = _now()
        self._progress.status = "completed"
        self._progress.completed_at = now
        self._progress.updated_at = now
        self._db.commit()

    def fail(self, error: str) -> None:
        """작업 실패 표시."""
        now = _now()
        self._progress.status = "error"
        self._progress.error_message = str(error)[:2000]
        self._progress.updated_at = now
        self._db.commit()
