"""
transkripsi.py — SQLAlchemy model untuk task transkripsi.

Perubahan:
- Tambah kolom `is_cancelled` (bool) — admin/user bisa request cancel.
- Tambah kolom `partial_result` (Text) — hasil sementara per segmen (plaintext, tidak dienkripsi).
- Tambah kolom `segments_json` (Text) — JSON array segmen [{start, end, text}] untuk tampilan streaming.
- `result` tetap Fernet-encrypted (hasil final).
"""

from sqlalchemy import Column, Integer, String, Float, Text, Boolean, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from datetime import datetime, timezone

from app.core.database import Base


def _utcnow():
    return datetime.now(timezone.utc)


class TranskripsiTask(Base):
    __tablename__ = "transkripsi_tasks"

    id              = Column(Integer, primary_key=True, index=True)
    task_uuid       = Column(String, unique=True, index=True, nullable=False)
    status          = Column(String, default="pending")       # pending | processing | completed | failed | cancelled
    progress        = Column(Integer, default=0)              # 0–100

    # Hasil final — disimpan terenkripsi (Fernet). Dekripsi di task_formatter.
    result          = Column(Text, nullable=True)

    # Hasil sementara — plaintext, diupdate per batch segmen saat masih processing.
    # Tidak dienkripsi karena bersifat sementara dan akan ditimpa result terenkripsi saat selesai.
    partial_result  = Column(Text, nullable=True)

    # JSON array segmen: [{"start": 0.0, "end": 3.2, "text": "..."}, ...]
    # Diupdate saat processing, dikosongkan setelah completed (data ada di result).
    segments_json   = Column(Text, nullable=True)

    error_message   = Column(Text, nullable=True)

    model_type      = Column(String, default="base")
    audio_file      = Column(String, nullable=True)
    is_court_mode   = Column(Boolean, default=False)
    processing_time = Column(Float, nullable=True)
    audio_duration  = Column(Float, nullable=True)
    engine          = Column(String, default="local")         # local | api

    # Flag cancel — worker cek ini setiap selesai segmen.
    is_cancelled    = Column(Boolean, default=False, nullable=False)

    # Kepemilikan
    user_id         = Column(
        Integer,
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )
    owner           = relationship("User", back_populates="tasks", lazy="select")

    created_at      = Column(DateTime(timezone=True), default=_utcnow)
    updated_at      = Column(DateTime(timezone=True), default=_utcnow, onupdate=_utcnow)

    def to_dict(self, include_raw_result: bool = False) -> dict:
        return {
            "id":               self.id,
            "task_uuid":        self.task_uuid,
            "status":           self.status,
            "progress":         self.progress,
            "result":           self.result if include_raw_result else None,
            "partial_result":   self.partial_result,
            "segments_json":    self.segments_json,
            "error_message":    self.error_message,
            "model_type":       self.model_type,
            "engine":           self.engine,
            "is_court_mode":    self.is_court_mode,
            "is_cancelled":     self.is_cancelled,
            "processing_time":  self.processing_time,
            "audio_duration":   self.audio_duration,
            "user_id":          self.user_id,
            "created_at":       self.created_at.isoformat() if self.created_at else None,
            "updated_at":       self.updated_at.isoformat() if self.updated_at else None,
        }