"""
PPM Infrastructure — Scoring Model Repository

پیاده‌سازی ریپازیتوری مدل امتیازدهی.
"""
from typing import Optional, List
from uuid import UUID

from ...domain.entities.scoring import ScoringModel
from ...domain.repositories.interfaces import ScoringModelRepository
from ..persistence.models import ScoringModelModel
from .mappers import ScoringModelMapper


class DjangoScoringModelRepository(ScoringModelRepository):

    def save(self, entity: ScoringModel) -> ScoringModel:
        try:
            model = ScoringModelModel.objects.get(pk=entity.id)
            model = ScoringModelMapper.to_model(entity, model)
        except ScoringModelModel.DoesNotExist:
            model = ScoringModelMapper.to_model(entity)
        model.save()
        return ScoringModelMapper.to_entity(model)

    def get_by_id(self, id: UUID) -> Optional[ScoringModel]:
        try:
            model = ScoringModelModel.objects.get(pk=id)
            return ScoringModelMapper.to_entity(model)
        except ScoringModelModel.DoesNotExist:
            return None

    def find(self, **filters) -> List[ScoringModel]:
        qs = ScoringModelModel.objects.filter(**filters)
        return [ScoringModelMapper.to_entity(m) for m in qs]

    def delete(self, id: UUID) -> None:
        ScoringModelModel.objects.filter(pk=id).delete()

    def find_active_by_portfolio(self, portfolio_id: UUID) -> Optional[ScoringModel]:
        try:
            model = ScoringModelModel.objects.get(
                portfolio_id=portfolio_id, is_active=True,
            )
            return ScoringModelMapper.to_entity(model)
        except ScoringModelModel.DoesNotExist:
            return None
        except ScoringModelModel.MultipleObjectsReturned:
            model = ScoringModelModel.objects.filter(
                portfolio_id=portfolio_id, is_active=True,
            ).first()
            return ScoringModelMapper.to_entity(model) if model else None
