import graphene
from graphene_django import DjangoObjectType
from offers.models import Offer, OfferLine
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 LogisticsNode(graphene.ObjectType):
    uuid = graphene.String()
    name = graphene.String()
    latitude = graphene.Float()
    longitude = graphene.Float()
    country = graphene.String()


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

    class Meta:
        model = Supplier
        fields = "__all__"

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


class OfferLineType(DjangoObjectType):
    class Meta:
        model = OfferLine
        fields = "__all__"


class OfferType(DjangoObjectType):
    lines = graphene.List(OfferLineType)
    # CamelCase поля для фронта
    locationLatitude = graphene.Float()
    locationLongitude = graphene.Float()
    locationCountry = graphene.String()
    locationCountryCode = graphene.String()

    class Meta:
        model = Offer
        fields = "__all__"

    def resolve_lines(self, info):
        return self.lines.all()


class PublicQuery(graphene.ObjectType):
    """Public schema - no authentication required"""
    get_products = graphene.List(Product)
    get_logistics_nodes = graphene.List(LogisticsNode)
    get_suppliers = graphene.List(
        SupplierType,
        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(),
    )
    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]

    def resolve_get_logistics_nodes(self, info):
        odoo_service = OdooService()
        nodes_data = odoo_service.get_logistics_nodes()
        return [LogisticsNode(**node) for node in nodes_data]

    def resolve_get_suppliers(self, info, 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_supplier(self, info, uuid):
        try:
            return Supplier.objects.get(uuid=uuid)
        except Supplier.DoesNotExist:
            return None

    def resolve_get_offers(self, info, status=None, product_uuid=None, location_uuid=None, category_name=None, team_uuid=None):
        queryset = Offer.objects.prefetch_related('lines')
        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(lines__product_uuid=product_uuid).distinct()
        if category_name:
            queryset = queryset.filter(lines__category_name__icontains=category_name).distinct()
        # Enrich offers with location metadata from Odoo logistics nodes
        nodes_map = {}
        try:
            odoo_service = OdooService()
            nodes = odoo_service.get_logistics_nodes()
            nodes_map = {str(node.get('uuid')): node for node in nodes}
        except Exception:
            nodes_map = {}

        enriched = []
        for offer in queryset:
            node = nodes_map.get(str(offer.location_uuid)) if offer.location_uuid else None
            if node:
                offer.locationLatitude = node.get('latitude')
                offer.locationLongitude = node.get('longitude')
                offer.locationCountry = node.get('country')
                offer.locationCountryCode = node.get('country_code')
            enriched.append(offer)
        return enriched

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


public_schema = graphene.Schema(query=PublicQuery)
