"""SQLAlchemy implementation of EditPlanRepository."""

from __future__ import annotations

from typing import List, Optional

from sqlalchemy.orm import Session

from packages.adapters.sqlalchemy_impl.models import EditPlanModel
from packages.domain.edit_plan import EditPlan, EditPlanStatus


class SQLAlchemyEditPlanRepository:
    """SQLAlchemy 剪辑计划仓储"""

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

    def list_by_template(
        self,
        template_id: str,
        *,
        status: Optional[EditPlanStatus] = None,
        skip: int = 0,
        limit: int = 50,
    ) -> List[EditPlan]:
        """按模板列出剪辑计划"""
        query = self.session.query(EditPlanModel).filter(
            EditPlanModel.template_id == template_id,
        )
        if status:
            query = query.filter(EditPlanModel.status == status)
        query = query.order_by(EditPlanModel.created_at.desc())
        models = query.offset(skip).limit(limit).all()
        return [self._model_to_entity(m) for m in models]

    def list_all(
        self,
        *,
        status: Optional[EditPlanStatus] = None,
        skip: int = 0,
        limit: int = 50,
    ) -> List[EditPlan]:
        """列出所有剪辑计划"""
        query = self.session.query(EditPlanModel)
        if status:
            query = query.filter(EditPlanModel.status == status)
        query = query.order_by(EditPlanModel.created_at.desc())
        models = query.offset(skip).limit(limit).all()
        return [self._model_to_entity(m) for m in models]

    def get(self, plan_id: str) -> Optional[EditPlan]:
        """根据 ID 获取计划"""
        model = self.session.query(EditPlanModel).filter(EditPlanModel.id == plan_id).first()
        if model is None:
            return None
        return self._model_to_entity(model)

    def list_by_project(
        self,
        project_id: str,
        *,
        status: Optional[EditPlanStatus] = None,
        skip: int = 0,
        limit: int = 50,
    ) -> List[EditPlan]:
        """按项目列出剪辑计划"""
        query = self.session.query(EditPlanModel).filter(
            EditPlanModel.project_id == project_id,
        )
        if status:
            query = query.filter(EditPlanModel.status == status)
        query = query.order_by(EditPlanModel.created_at.desc())
        models = query.offset(skip).limit(limit).all()
        return [self._model_to_entity(m) for m in models]

    def list_by_user(
        self,
        user_id: str,
        *,
        status: Optional[EditPlanStatus] = None,
        skip: int = 0,
        limit: int = 50,
    ) -> List[EditPlan]:
        """列出用户创建的剪辑计划"""
        query = self.session.query(EditPlanModel).filter(
            EditPlanModel.created_by_user_id == user_id,
        )
        if status:
            query = query.filter(EditPlanModel.status == status)
        query = query.order_by(EditPlanModel.created_at.desc())
        models = query.offset(skip).limit(limit).all()
        return [self._model_to_entity(m) for m in models]

    def create(self, plan: EditPlan) -> EditPlan:
        """创建计划"""
        model = EditPlanModel(
            id=plan.id,
            template_id=plan.template_id,
            name=plan.name,
            status=plan.status,
            total_duration=plan.total_duration,
            source_edit_plan_id=plan.source_edit_plan_id or None,
            project_id=plan.project_id or "",
            created_by_user_id=plan.created_by_user_id or "",
            config=plan.config,
        )
        self.session.add(model)
        self.session.commit()
        self.session.refresh(model)
        return self._model_to_entity(model)

    def update(self, plan: EditPlan) -> EditPlan:
        """更新计划"""
        model = self.session.query(EditPlanModel).filter(EditPlanModel.id == plan.id).first()
        if model is None:
            raise ValueError(f"EditPlan {plan.id} not found")
        model.template_id = plan.template_id
        model.name = plan.name
        model.status = plan.status
        model.total_duration = plan.total_duration
        model.source_edit_plan_id = plan.source_edit_plan_id or None
        model.project_id = plan.project_id or ""
        model.created_by_user_id = plan.created_by_user_id or ""
        model.config = plan.config
        model.updated_at = plan.updated_at
        self.session.commit()
        self.session.refresh(model)
        return self._model_to_entity(model)

    def delete(self, plan_id: str) -> bool:
        """删除计划"""
        model = self.session.query(EditPlanModel).filter(EditPlanModel.id == plan_id).first()
        if model is None:
            return False
        self.session.delete(model)
        self.session.commit()
        return True

    def count(self, *, status: Optional[EditPlanStatus] = None) -> int:
        """统计计划数量"""
        query = self.session.query(EditPlanModel)
        if status:
            query = query.filter(EditPlanModel.status == status)
        return query.count()

    @staticmethod
    def _model_to_entity(model: EditPlanModel) -> EditPlan:
        return EditPlan(
            id=model.id,
            template_id=model.template_id,
            name=model.name,
            status=EditPlanStatus(model.status) if model.status else EditPlanStatus.DRAFT,
            total_duration=model.total_duration or 0.0,
            source_edit_plan_id=model.source_edit_plan_id or "",
            project_id=model.project_id or "",
            created_by_user_id=model.created_by_user_id or "",
            config=model.config or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )
