import graphene
from graphene_django import DjangoObjectType
from offers.models import Offer, OfferLine
from purchase_requests.models import Request
from ..permissions import require_scopes
import uuid as uuid_lib


class RequestType(DjangoObjectType):
    class Meta:
        model = Request
        fields = "__all__"


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


class OfferType(DjangoObjectType):
    lines = graphene.List(OfferLineType)

    class Meta:
        model = Offer
        fields = "__all__"

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


class RequestInput(graphene.InputObjectType):
    product_uuid = graphene.String(required=True)
    quantity = graphene.Decimal(required=True)
    source_location_uuid = graphene.String(required=True)
    user_id = graphene.String(required=True)


class OfferLineInput(graphene.InputObjectType):
    product_uuid = graphene.String(required=True)
    product_name = graphene.String()
    category_name = graphene.String()
    quantity = graphene.Decimal(required=True)
    unit = graphene.String()
    price_per_unit = graphene.Decimal()
    currency = graphene.String()


class OfferInput(graphene.InputObjectType):
    team_uuid = graphene.String(required=True)
    title = graphene.String(required=True)
    description = graphene.String()
    location_uuid = graphene.String(required=True)
    location_name = graphene.String()
    valid_until = graphene.Date()
    lines = graphene.List(OfferLineInput, required=True)


class TeamQuery(graphene.ObjectType):
    """Team schema - Team Access Token authentication"""
    get_requests = graphene.List(RequestType, user_id=graphene.String(required=True))
    get_request = graphene.Field(RequestType, uuid=graphene.String(required=True))

    @require_scopes("read:requests")
    def resolve_get_requests(self, info, user_id):
        return Request.objects.filter(user_id=user_id).order_by('-created_at')

    @require_scopes("read:requests")
    def resolve_get_request(self, info, uuid):
        try:
            return Request.objects.get(uuid=uuid)
        except Request.DoesNotExist:
            return None


class CreateRequest(graphene.Mutation):
    class Arguments:
        input = RequestInput(required=True)

    request = graphene.Field(RequestType)

    @require_scopes("create:requests")
    def mutate(self, info, input):
        request = Request(
            uuid=str(uuid_lib.uuid4()),
            product_uuid=input.product_uuid,
            quantity=input.quantity,
            source_location_uuid=input.source_location_uuid,
            user_id=input.user_id,
        )
        request.save()
        return CreateRequest(request=request)


class CreateOffer(graphene.Mutation):
    class Arguments:
        input = OfferInput(required=True)

    offer = graphene.Field(OfferType)

    @require_scopes("create:offers")
    def mutate(self, info, input):
        offer = Offer(
            uuid=str(uuid_lib.uuid4()),
            team_uuid=input.team_uuid,
            title=input.title,
            description=input.description or '',
            location_uuid=input.location_uuid,
            location_name=input.location_name or '',
            valid_until=input.valid_until,
        )
        offer.save()

        for line_input in input.lines:
            OfferLine.objects.create(
                uuid=str(uuid_lib.uuid4()),
                offer=offer,
                product_uuid=line_input.product_uuid,
                product_name=line_input.product_name or '',
                category_name=line_input.category_name or '',
                quantity=line_input.quantity,
                unit=line_input.unit or 'ton',
                price_per_unit=line_input.price_per_unit,
                currency=line_input.currency or 'USD',
            )

        return CreateOffer(offer=offer)


class TeamMutation(graphene.ObjectType):
    """Team mutations - Team Access Token authentication"""
    create_request = CreateRequest.Field()
    create_offer = CreateOffer.Field()


team_schema = graphene.Schema(query=TeamQuery, mutation=TeamMutation)
