from django.core.exceptions import ObjectDoesNotExist
from django.db import models


class ItemManager(models.Manager):
    def active(self):
        return self.filter(is_active=True, deleted=False)

    def featured_items(self):
        return self.active().filter(featured=True)


class SubscriptionManager(ItemManager):
    def __init__(self, *args, **kwargs):
        super(SubscriptionManager, self).__init__(*args, **kwargs)

    def valid_options(self, shipping_type=None, shipping_method=None):
        """
        :param type: INSTATE, OUTSTATE, FOREIGN
        :returns: Only valid subscriptions related to the specific first class
            option
        """
        q = self.active()
        if shipping_type:
            q.filter(shipping_type=shipping_type)
        if shipping_method:
            q = q.filter(shipping_method=shipping_method)
        return q.order_by("title", "duration")

    def _valid_value_list(self, value, shipping_type=None, shipping_method=None):
        return (
            self.valid_options(shipping_type, shipping_method)
            .distinct()
            .values_list(value, flat=True)
        )

    def titles_value_list(self, shipping_type, shipping_method=None):
        return self._valid_value_list(
            "title", shipping_type, shipping_method=shipping_method
        )

    def durations_value_list(self, shipping_type, shipping_method=None):
        return self._valid_value_list(
            "duration", shipping_type, shipping_method=shipping_method
        )

    def shipping_method_value_list(self, shipping_type):
        return self._valid_value_list("shipping_method", shipping_type)

    def title_images(self):
        return (
            self.active()
            .exclude(image__isnull=True)
            .exclude(image="")
            .values("title", "image")
        )

    def find_price(self, shipping_type, title, duration, shipping_method):
        try:
            price = self.get(
                shipping_type=shipping_type,
                title=title,
                duration=duration,
                shipping_method=shipping_method,
            ).price
        except ObjectDoesNotExist:
            price = None
        return price


class ZipCodeManager(models.Manager):
    def active(self):
        return self.filter(is_active=True, deleted=False)


class PersonManager(models.Manager):
    def get_queryset(self):
        return super(PersonManager, self).get_query_set().active()

    def active(self):
        return self.filter(is_active=True, deleted=False)
