import graphene
from graphene_django import DjangoObjectType
from offers.models import Offer
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 OfferType(DjangoObjectType):
    class Meta:
        model = Offer
        fields = "__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 OfferInput(graphene.InputObjectType):
    team_uuid = graphene.String(required=True)
    # Товар
    product_uuid = graphene.String(required=True)
    product_name = graphene.String(required=True)
    category_name = graphene.String()
    # Локация
    location_uuid = graphene.String()
    location_name = graphene.String()
    location_country = graphene.String()
    location_country_code = graphene.String()
    location_latitude = graphene.Float()
    location_longitude = graphene.Float()
    # Цена и количество
    quantity = graphene.Decimal(required=True)
    unit = graphene.String()
    price_per_unit = graphene.Decimal()
    currency = graphene.String()
    # Прочее
    description = graphene.String()
    valid_until = graphene.Date()
    terminus_schema_id = graphene.String()
    terminus_payload = graphene.JSONString()


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))
    get_team_offers = graphene.List(OfferType, team_uuid=graphene.String(required=True))

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

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

    @require_scopes("teams:member")
    def resolve_get_team_offers(self, info, team_uuid):
        return Offer.objects.filter(team_uuid=team_uuid).order_by('-created_at')


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

    request = graphene.Field(RequestType)

    @require_scopes("teams:member")
    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)

    success = graphene.Boolean()
    message = graphene.String()
    workflowId = graphene.String()
    offerUuid = graphene.String()

    @require_scopes("teams:member")
    def mutate(self, info, input):
        from ..temporal_client import start_offer_workflow

        offer_uuid = str(uuid_lib.uuid4())
        workflow_id, _ = start_offer_workflow(
            offer_uuid=offer_uuid,
            team_uuid=input.team_uuid,
            product_uuid=input.product_uuid,
            product_name=input.product_name,
            category_name=input.category_name,
            location_uuid=input.location_uuid,
            location_name=input.location_name,
            location_country=input.location_country,
            location_country_code=input.location_country_code,
            location_latitude=input.location_latitude,
            location_longitude=input.location_longitude,
            quantity=input.quantity,
            unit=input.unit,
            price_per_unit=input.price_per_unit,
            currency=input.currency,
            description=input.description,
            valid_until=input.valid_until,
            terminus_schema_id=getattr(input, "terminus_schema_id", None),
            terminus_payload=getattr(input, "terminus_payload", None),
        )
        return CreateOffer(
            success=True,
            message="Offer workflow started",
            workflowId=workflow_id,
            offerUuid=offer_uuid,
        )


class UpdateOffer(graphene.Mutation):
    class Arguments:
        uuid = graphene.String(required=True)
        input = OfferInput(required=True)

    offer = graphene.Field(OfferType)

    @require_scopes("teams:member")
    def mutate(self, info, uuid, input):
        try:
            offer = Offer.objects.get(uuid=uuid)
        except Offer.DoesNotExist:
            raise Exception("Offer not found")

        # Обновляем поля
        offer.product_uuid = input.product_uuid
        offer.product_name = input.product_name
        offer.category_name = input.category_name or ''
        offer.location_uuid = input.location_uuid or ''
        offer.location_name = input.location_name or ''
        offer.location_country = input.location_country or ''
        offer.location_country_code = input.location_country_code or ''
        offer.location_latitude = input.location_latitude
        offer.location_longitude = input.location_longitude
        offer.quantity = input.quantity
        offer.unit = input.unit or 'ton'
        offer.price_per_unit = input.price_per_unit
        offer.currency = input.currency or 'USD'
        offer.description = input.description or ''
        offer.valid_until = input.valid_until
        if input.terminus_schema_id is not None:
            offer.terminus_schema_id = input.terminus_schema_id
        offer.save()

        return UpdateOffer(offer=offer)


class DeleteOffer(graphene.Mutation):
    class Arguments:
        uuid = graphene.String(required=True)

    success = graphene.Boolean()

    @require_scopes("teams:member")
    def mutate(self, info, uuid):
        try:
            offer = Offer.objects.get(uuid=uuid)
            offer.delete()
            return DeleteOffer(success=True)
        except Offer.DoesNotExist:
            return DeleteOffer(success=False)


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


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