"""
Strategy Infrastructure — Objective Repository Implementation.
"""

from typing import List, Optional
from uuid import UUID

from ...domain.entities.objective import Objective
from ...domain.repositories.interfaces import ObjectiveRepository
from ..persistence.models import ObjectiveModel
from .mappers import ObjectiveMapper


class DjangoObjectiveRepository(ObjectiveRepository):
    """پیاده‌سازی Django ریپازیتوری هدف."""

    def find_by_id(self, objective_id: UUID) -> Optional[Objective]:
        try:
            model = ObjectiveModel.objects.get(id=objective_id)
            return ObjectiveMapper.to_entity(model)
        except ObjectiveModel.DoesNotExist:
            return None

    def find_by_tenant(self, tenant_id: UUID) -> List[Objective]:
        qs = ObjectiveModel.objects.filter(tenant_id=tenant_id)
        return [ObjectiveMapper.to_entity(m) for m in qs]

    def find_by_theme(self, theme_id: UUID) -> List[Objective]:
        qs = ObjectiveModel.objects.filter(theme_id=theme_id)
        return [ObjectiveMapper.to_entity(m) for m in qs]

    def find_children(self, parent_id: UUID) -> List[Objective]:
        qs = ObjectiveModel.objects.filter(parent_id=parent_id)
        return [ObjectiveMapper.to_entity(m) for m in qs]

    def find_active_by_tenant(self, tenant_id: UUID) -> List[Objective]:
        qs = ObjectiveModel.objects.filter(
            tenant_id=tenant_id,
            status=ObjectiveModel.Status.ACTIVE,
        )
        return [ObjectiveMapper.to_entity(m) for m in qs]

    def save(self, entity: Objective) -> Objective:
        try:
            model = ObjectiveModel.objects.get(id=entity.id)
            model = ObjectiveMapper.to_model(entity, model)
        except ObjectiveModel.DoesNotExist:
            model = ObjectiveMapper.to_model(entity)
        model.save()
        return ObjectiveMapper.to_entity(model)

    def delete(self, objective_id: UUID) -> bool:
        deleted, _ = ObjectiveModel.objects.filter(id=objective_id).delete()
        return deleted > 0
