"""SQLAlchemy implementation of EditPlanClipRepository."""

from __future__ import annotations

from typing import List, Optional

from sqlalchemy.orm import Session

from packages.adapters.sqlalchemy_impl.models import EditPlanClipModel
from packages.domain.edit_plan_clip import EditPlanClip, EditPlanClipStatus


class SQLAlchemyEditPlanClipRepository:
    """SQLAlchemy 剪辑计划片段仓储"""

    def __init__(self, session: Session) -> None:
        self.session = session

    def list_by_plan(
        self,
        plan_id: str,
        *,
        status: Optional[EditPlanClipStatus] = None,
        skip: int = 0,
        limit: int = 100,
    ) -> List[EditPlanClip]:
        """按计划列出片段，按 order 排序"""
        query = self.session.query(EditPlanClipModel).filter(
            EditPlanClipModel.plan_id == plan_id,
        )
        if status:
            query = query.filter(EditPlanClipModel.status == status)
        query = query.order_by(EditPlanClipModel.order)
        models = query.offset(skip).limit(limit).all()
        return [self._model_to_entity(m) for m in models]

    def get(self, clip_id: str) -> Optional[EditPlanClip]:
        """根据 ID 获取片段"""
        model = self.session.query(EditPlanClipModel).filter(EditPlanClipModel.id == clip_id).first()
        if model is None:
            return None
        return self._model_to_entity(model)

    def create(self, clip: EditPlanClip) -> EditPlanClip:
        """创建片段"""
        model = EditPlanClipModel(
            id=clip.id,
            plan_id=clip.plan_id,
            clip_type=clip.clip_type,
            order=clip.order,
            template_clip_config_id=clip.template_clip_config_id,
            asset_id=clip.asset_id,
            text_content=clip.text_content,
            start_time=clip.start_time,
            duration=clip.duration,
            transition_effect=clip.transition_effect,
            status=clip.status,
            config=clip.config,
        )
        self.session.add(model)
        self.session.commit()
        self.session.refresh(model)
        return self._model_to_entity(model)

    def update(self, clip: EditPlanClip) -> EditPlanClip:
        """更新片段"""
        model = self.session.query(EditPlanClipModel).filter(EditPlanClipModel.id == clip.id).first()
        if model is None:
            raise ValueError(f"EditPlanClip {clip.id} not found")
        model.plan_id = clip.plan_id
        model.clip_type = clip.clip_type
        model.order = clip.order
        model.template_clip_config_id = clip.template_clip_config_id
        model.asset_id = clip.asset_id
        model.text_content = clip.text_content
        model.start_time = clip.start_time
        model.duration = clip.duration
        model.transition_effect = clip.transition_effect
        model.status = clip.status
        model.config = clip.config
        model.updated_at = clip.updated_at
        self.session.commit()
        self.session.refresh(model)
        return self._model_to_entity(model)

    def delete(self, clip_id: str) -> bool:
        """删除片段"""
        model = self.session.query(EditPlanClipModel).filter(EditPlanClipModel.id == clip_id).first()
        if model is None:
            return False
        self.session.delete(model)
        self.session.commit()
        return True

    def delete_by_plan(self, plan_id: str) -> int:
        """删除计划下所有片段，返回删除数量"""
        count = self.session.query(EditPlanClipModel).filter(EditPlanClipModel.plan_id == plan_id).delete()
        self.session.commit()
        return count

    def count(self, *, plan_id: Optional[str] = None, status: Optional[EditPlanClipStatus] = None) -> int:
        """统计片段数量"""
        query = self.session.query(EditPlanClipModel)
        if plan_id:
            query = query.filter(EditPlanClipModel.plan_id == plan_id)
        if status:
            query = query.filter(EditPlanClipModel.status == status)
        return query.count()

    @staticmethod
    def _model_to_entity(model: EditPlanClipModel) -> EditPlanClip:
        return EditPlanClip(
            id=model.id,
            plan_id=model.plan_id,
            clip_type=model.clip_type,
            order=model.order,
            template_clip_config_id=model.template_clip_config_id or "",
            asset_id=model.asset_id or "",
            text_content=model.text_content or "",
            start_time=model.start_time or 0.0,
            duration=model.duration or 0.0,
            transition_effect=model.transition_effect or "cut",
            status=EditPlanClipStatus(model.status) if model.status else EditPlanClipStatus.PENDING,
            config=model.config or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )
