"""Custom model managers for PI FYAD."""

from django.db import models
from django.utils import timezone


class CharacterPlanetManager(models.Manager):
    """Manager for CharacterPlanet with common queries."""

    def for_character(self, character_id: int):
        """Get all planets for a character."""
        return self.filter(owner__character__character_id=character_id)

    def with_critical_alerts(self):
        """Get planets that have expired extractors or nearly-full storage."""
        now = timezone.now()
        return self.filter(
            models.Q(pins__is_extractor=True, pins__expiry_time__lt=now)
            | models.Q(pins__is_storage=True, pins__storage_fill_pct__gte=95.0)
        ).distinct()

    def for_corporation(self, corporation_id: int):
        """Get all planets for a corporation."""
        return self.filter(
            owner__character__corporation_id=corporation_id
        )

    def for_alliance(self, alliance_id: int):
        """Get all planets for an alliance."""
        return self.filter(
            owner__character__alliance_id=alliance_id
        )


class PlanetPinManager(models.Manager):
    """Manager for PlanetPin with common queries."""

    def extractors(self):
        """Get all extractor pins."""
        return self.filter(is_extractor=True)

    def factories(self):
        """Get all factory pins."""
        return self.filter(is_factory=True)

    def storage_pins(self):
        """Get all storage/launchpad pins."""
        return self.filter(is_storage=True)

    def expired_extractors(self):
        """Get extractors whose programs have expired."""
        now = timezone.now()
        return self.filter(
            is_extractor=True,
            expiry_time__lt=now,
        )

    def active_extractors(self):
        """Get extractors with active programs."""
        now = timezone.now()
        return self.filter(
            is_extractor=True,
            expiry_time__gt=now,
            install_time__isnull=False,
        )

    def highest_tier_factories(self):
        """Get factories at the highest tier on each planet."""
        return self.filter(is_factory=True).order_by("-factory_tier")

    def overfull_storage(self, threshold: float = 90.0):
        """Get storage pins above fill threshold."""
        return self.filter(
            is_storage=True,
            storage_fill_pct__gte=threshold,
        )


class StorageContentsManager(models.Manager):
    """Manager for StorageContents."""

    def for_pin(self, pin_id: int):
        """Get all contents for a specific pin."""
        return self.filter(pin_id=pin_id)

    def by_volume(self):
        """Order contents by total volume descending."""
        return self.order_by("-total_volume")


class PlanetTemplateManager(models.Manager):
    """Manager for PlanetTemplate with visibility filtering."""

    def visible_to_character(self, character):
        """Get templates visible to a character based on corp/alliance membership."""
        q = models.Q(visibility="public")
        q |= models.Q(created_by=character)

        if hasattr(character, "corporation_id") and character.corporation_id:
            q |= models.Q(
                visibility="corp",
                corporation_id=character.corporation_id,
            )

        if hasattr(character, "alliance_id") and character.alliance_id:
            q |= models.Q(
                visibility="alliance",
                alliance_id=character.alliance_id,
            )

        return self.filter(q).distinct()

    def for_planet_type(self, planet_type_id: int):
        """Get templates for a specific planet type."""
        return self.filter(planet_type_id=planet_type_id)
