"""
PPM Infrastructure — Django Cross-Project Dependency Repository.

پیاده‌سازی ریپازیتوری وابستگی بین پروژه‌ای با Django ORM.
"""

from typing import List, Optional
from uuid import UUID

from django.db.models import Q

from ...domain.entities.dependency import CrossProjectDependency
from ...domain.repositories.interfaces import CrossProjectDependencyRepository
from ..persistence.models import CrossProjectDependencyModel
from .mappers import CrossProjectDependencyMapper


class DjangoCrossProjectDependencyRepository(CrossProjectDependencyRepository):
    """پیاده‌سازی Django ORM ریپازیتوری وابستگی بین پروژه‌ای."""

    def save(self, entity: CrossProjectDependency) -> CrossProjectDependency:
        try:
            model = CrossProjectDependencyModel.objects.get(pk=entity.id)
            model = CrossProjectDependencyMapper.to_model(entity, model)
        except CrossProjectDependencyModel.DoesNotExist:
            model = CrossProjectDependencyMapper.to_model(entity)
        model.save()
        return CrossProjectDependencyMapper.to_entity(model)

    def get_by_id(self, id: UUID) -> Optional[CrossProjectDependency]:
        try:
            model = CrossProjectDependencyModel.objects.get(pk=id)
            return CrossProjectDependencyMapper.to_entity(model)
        except CrossProjectDependencyModel.DoesNotExist:
            return None

    def find(self, **filters) -> List[CrossProjectDependency]:
        qs = CrossProjectDependencyModel.objects.filter(**filters)
        return [CrossProjectDependencyMapper.to_entity(m) for m in qs]

    def delete(self, id: UUID) -> None:
        CrossProjectDependencyModel.objects.filter(pk=id).delete()

    def find_by_predecessor(self, project_id: UUID) -> List[CrossProjectDependency]:
        qs = CrossProjectDependencyModel.objects.filter(predecessor_project_id=project_id)
        return [CrossProjectDependencyMapper.to_entity(m) for m in qs]

    def find_by_successor(self, project_id: UUID) -> List[CrossProjectDependency]:
        qs = CrossProjectDependencyModel.objects.filter(successor_project_id=project_id)
        return [CrossProjectDependencyMapper.to_entity(m) for m in qs]

    def find_by_project(self, project_id: UUID) -> List[CrossProjectDependency]:
        qs = CrossProjectDependencyModel.objects.filter(
            Q(predecessor_project_id=project_id) | Q(successor_project_id=project_id)
        )
        return [CrossProjectDependencyMapper.to_entity(m) for m in qs]

    def find_active(self) -> List[CrossProjectDependency]:
        qs = CrossProjectDependencyModel.objects.filter(status="active")
        return [CrossProjectDependencyMapper.to_entity(m) for m in qs]
