import graphene
from graphene_django import DjangoObjectType
from offers.models import Offer
from suppliers.models import Supplier
from ..services import OdooService


class Product(graphene.ObjectType):
    uuid = graphene.String()
    name = graphene.String()
    category_id = graphene.Int()
    category_name = graphene.String()
    terminus_schema_id = graphene.String()


class SupplierType(DjangoObjectType):
    offers_count = graphene.Int()
    country_code = graphene.String()

    class Meta:
        model = Supplier
        fields = "__all__"

    def resolve_offers_count(self, info):
        return Offer.objects.filter(team_uuid=self.team_uuid, status='active').count()

    def resolve_country_code(self, info):
        return getattr(self, 'country_code', '')


class OfferType(DjangoObjectType):
    class Meta:
        model = Offer
        fields = "__all__"


class PublicQuery(graphene.ObjectType):
    """Public schema - no authentication required"""
    get_products = graphene.List(Product)
    get_suppliers = graphene.List(
        SupplierType,
        country=graphene.String(),
        is_verified=graphene.Boolean(),
        limit=graphene.Int(),
        offset=graphene.Int(),
    )
    get_suppliers_count = graphene.Int(
        country=graphene.String(),
        is_verified=graphene.Boolean(),
    )
    get_supplier = graphene.Field(SupplierType, uuid=graphene.String(required=True))
    get_offers = graphene.List(
        OfferType,
        status=graphene.String(),
        product_uuid=graphene.String(),
        location_uuid=graphene.String(),
        category_name=graphene.String(),
        team_uuid=graphene.String(),
        limit=graphene.Int(),
        offset=graphene.Int(),
    )
    get_offers_count = graphene.Int(
        status=graphene.String(),
        product_uuid=graphene.String(),
        location_uuid=graphene.String(),
        category_name=graphene.String(),
        team_uuid=graphene.String(),
    )
    get_offer = graphene.Field(OfferType, uuid=graphene.String(required=True))

    def resolve_get_products(self, info):
        odoo_service = OdooService()
        products_data = odoo_service.get_products()
        return [Product(**product) for product in products_data]

    @staticmethod
    def _get_suppliers_queryset(country=None, is_verified=None):
        queryset = Supplier.objects.filter(is_active=True)
        if country:
            queryset = queryset.filter(country__icontains=country)
        if is_verified is not None:
            queryset = queryset.filter(is_verified=is_verified)
        return queryset

    def resolve_get_suppliers(self, info, country=None, is_verified=None, limit=None, offset=None):
        queryset = PublicQuery._get_suppliers_queryset(country=country, is_verified=is_verified)
        if offset is not None:
            queryset = queryset[offset:]
        if limit is not None:
            queryset = queryset[:limit]
        return queryset

    def resolve_get_suppliers_count(self, info, country=None, is_verified=None):
        return PublicQuery._get_suppliers_queryset(country=country, is_verified=is_verified).count()

    def resolve_get_supplier(self, info, uuid):
        try:
            return Supplier.objects.get(uuid=uuid)
        except Supplier.DoesNotExist:
            return None

    @staticmethod
    def _get_offers_queryset(status=None, product_uuid=None, location_uuid=None, category_name=None, team_uuid=None):
        queryset = Offer.objects.all()
        if status:
            queryset = queryset.filter(status=status)
        else:
            queryset = queryset.filter(status='active')
        if team_uuid:
            queryset = queryset.filter(team_uuid=team_uuid)
        if location_uuid:
            queryset = queryset.filter(location_uuid=location_uuid)
        if product_uuid:
            queryset = queryset.filter(product_uuid=product_uuid)
        if category_name:
            queryset = queryset.filter(category_name__icontains=category_name)
        return queryset

    def resolve_get_offers(self, info, status=None, product_uuid=None, location_uuid=None, category_name=None, team_uuid=None, limit=None, offset=None):
        queryset = PublicQuery._get_offers_queryset(
            status=status,
            product_uuid=product_uuid,
            location_uuid=location_uuid,
            category_name=category_name,
            team_uuid=team_uuid,
        )
        if offset is not None:
            queryset = queryset[offset:]
        if limit is not None:
            queryset = queryset[:limit]
        return queryset

    def resolve_get_offers_count(self, info, status=None, product_uuid=None, location_uuid=None, category_name=None, team_uuid=None):
        return PublicQuery._get_offers_queryset(
            status=status,
            product_uuid=product_uuid,
            location_uuid=location_uuid,
            category_name=category_name,
            team_uuid=team_uuid,
        ).count()

    def resolve_get_offer(self, info, uuid):
        try:
            return Offer.objects.get(uuid=uuid)
        except Offer.DoesNotExist:
            return None


public_schema = graphene.Schema(query=PublicQuery)
