"""Project signals.

- pre_save ProjectFund: ensure a Company donor exists for the funding source
  (matched by name iexact). Auto-tags it as a project donor and links the FK.
- post_save/post_delete Project + ProjectFinance: invalidate dashboard cache.
"""

from django.core.cache import cache
from django.db.models.signals import post_delete, post_save, pre_save
from django.dispatch import receiver

from .models import Project, ProjectFinance, ProjectFund


def _invalidate_dashboard_cache(*_args, **_kwargs):
    cache.delete_many(["projects:dashboard", "projects:finance_summary"])


for _model in (Project, ProjectFinance):
    post_save.connect(_invalidate_dashboard_cache, sender=_model, weak=False)
    post_delete.connect(_invalidate_dashboard_cache, sender=_model, weak=False)


@receiver(pre_save, sender=ProjectFund)
def link_or_create_donor(sender, instance: ProjectFund, **kwargs):
    from apps.companies.models import Company

    source = (instance.source or "").strip()
    if not source:
        return

    if instance.donor_id and instance.donor and instance.donor.company_type == "donor":
        return  # already linked

    donor = Company.objects.filter(name__iexact=source, company_type="donor").first()
    if donor is None:
        donor = Company.objects.create(
            name=source,
            company_type="donor",
            donor_category="project",
        )
    elif donor.donor_category != "project":
        # Promote regular donors that fund a project to project donors.
        donor.donor_category = "project"
        donor.save(update_fields=["donor_category", "updated_at"])

    instance.donor = donor
