"""标签 SQLAlchemy 仓储实现。"""

from sqlalchemy.orm import Session

from packages.adapters.sqlalchemy_impl.models import AssetTagModel, TagModel
from packages.domain import Tag


class SQLAlchemyTagRepository:
    def __init__(self, session: Session):
        self.session = session

    def create(self, tag: Tag) -> Tag:
        model = TagModel(
            id=tag.id,
            user_id=tag.user_id,
            name=tag.name,
            created_at=tag.created_at,
        )
        self.session.add(model)
        self.session.commit()
        return tag

    def get(self, tag_id: str) -> Tag | None:
        model = self.session.query(TagModel).filter(TagModel.id == tag_id).first()
        if model is None:
            return None
        return self._to_domain(model)

    def find_by_name(self, user_id: str, name: str) -> Tag | None:
        model = self.session.query(TagModel).filter(TagModel.user_id == user_id, TagModel.name == name).first()
        if model is None:
            return None
        return self._to_domain(model)

    def list_by_user(
        self,
        user_id: str,
        skip: int = 0,
        limit: int = 100,
    ) -> list[Tag]:
        models = (
            self.session.query(TagModel)
            .filter(TagModel.user_id == user_id)
            .order_by(TagModel.created_at.desc())
            .offset(skip)
            .limit(limit)
            .all()
        )
        return [self._to_domain(m) for m in models]

    def count_by_user(self, user_id: str) -> int:
        return self.session.query(TagModel).filter(TagModel.user_id == user_id).count()

    def delete(self, tag_id: str) -> bool:
        # 先清理关联表
        self.session.query(AssetTagModel).filter(AssetTagModel.tag_id == tag_id).delete(synchronize_session=False)
        model = self.session.query(TagModel).filter(TagModel.id == tag_id).first()
        if model is None:
            self.session.commit()
            return False
        self.session.delete(model)
        self.session.commit()
        return True

    @staticmethod
    def _to_domain(model: TagModel) -> Tag:
        return Tag(
            id=model.id,
            user_id=model.user_id,
            name=model.name,
            created_at=model.created_at,
        )
