from django.http import HttpResponse, JsonResponse
from django.urls import reverse
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.decorators import api_view, permission_classes
from api_partner.serializers import *
from backoffice.models import *
import datetime
from urllib import response
from django.core.paginator import Paginator
from django.http import JsonResponse
from eth_account.messages import defunct_hash_message
from tixsell import settings
from web3 import Web3
from web3.middleware import construct_sign_and_send_raw_middleware
from eth_account import Account
from eth_account.messages import encode_defunct
from eth_account.signers.local import LocalAccount
from django.shortcuts import render, HttpResponse
from mnemonic import Mnemonic
from django.core import signing
import logging
from rest_framework.permissions import IsAuthenticated
from rest_framework import generics, permissions, serializers
from rest_framework import status
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema 
from api.serializers import CategorySerializer
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate
import base64
import tempfile
import os
import stripe
import json
from django.core.files.base import ContentFile
from backoffice.forms.signup import SignupForm
from django.utils import timezone
import pytz
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from api_partner.views_events import send_image_to_pinata, unpin_image

class CustomPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100

logger = logging.getLogger('django')


class createTicket(APIView):
    permission_classes = [IsAuthenticated]
     
    @swagger_auto_schema(
        operation_id='createTicket',
        operation_description="""Create a Ticket for your event.
        <br><br>To each date provided (booking start date, ...) we will use the timezone of the event.
        <br>For price, we will use the currency of the event.
        <br><br><b>Note:</b>
        Because the image needs to be uploaded on a decentralized server, it can take few seconds before receiving the api response.
        <br><br>
        Once your ticket created you should be able to see It on the <b>sellTixEventPage</b> provided while creating your event.
        <br><br><b><i>Information:</i></b> For simplification management there is no update operation method for tickets.
        <br><br>If you have made a mistake or the ticket design doesn't suit you, you have two options:<br>
         <ul>
          <li>delete the ticket and create a new one with your updated image</li>
          <li>login to your SellTix Dashboard on our website to be able to modify the ticket using our NFT designer widget.</li>
          </ul>
        """,
        #  <br>This solution is less secure since anyone can see the URL once the event has started and sharing it by copying/pasting it.
      
        tags=['Tickets'],
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
                properties={
                    'refEvent': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_UUID,description="Reference to the event for which the ticket will be created"),
                     'image': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_BASE64, description="Base64 encoded image data. Example  'image':'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/......'"),
                    'name': openapi.Schema(type=openapi.TYPE_STRING, description="Ticket Name ie VIP Pass, Standard Ticket, etc"),
                    'maxTickets': openapi.Schema(type=openapi.TYPE_INTEGER, description="Maximum number of tickets that can be sold"),
                    'maxTicketsPerUser': openapi.Schema(type=openapi.TYPE_INTEGER, description="Maximum number of tickets that can be purchased by users"),
                    'ticketPrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Ticket price"),
                    'bookingStartDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the start of the booking. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'bookingEndDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the end of the booking. Should be before the event date.<b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'description': openapi.Schema(type=openapi.TYPE_STRING, description="Ticket description. Will be displayed on the event page"),
                    'revealed': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Ticket is revealed or not. If revealed, the ticket image will be visible on the event page. If not revealed the hidden uri image will be displayed"),
                    'revealStartDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the start of the reveal. At that specific date, your ticket design (image) will be revealed. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'hiddenuri': openapi.Schema(type=openapi.TYPE_STRING,   description="Hidden uri of the ticket image while it's not revealed. Will be displayed on the event page until reveal is done."),
                    'sellable': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Is Ticket sellable or not on marketplace such as Opensea.io."),
                    'maxSellablePrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Maximum price the ticket can be sold on marketplace such as Opensea.io."),
                    'royaltySellable': openapi.Schema(type=openapi.TYPE_INTEGER, description="Royalty you will receive for each sell on marketplace. Will override the event royalty. Please provide a percentage (between 0 and 100)."),
                    'earlyBid': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Do you offer a discount."),
                    'discountPrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Discount price of the ticket. Should be less than the ticket price."),
                    'discountEndDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the end of the discount. Should end before bookingEndDate. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'canStream': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="If your event is a streaming managed by SellTix, does the ticket allow owners to stream during the event.")   
             },
             example={
                     "refEvent":"ade56c0f-8175-462d-b548-fac938fcab14",
                    "name":"Ticket standard",
                    "maxTickets":100,
                    "maxTicketsPerUser":5,
                    "ticketPrice":20,
                    "bookingStartDate":"2024-07-01T10:00:00Z",
                    "bookingEndDate":"2024-08-31T10:00:00Z",
                    "description":"Get access to our conference",
                    "revealed":True,
                    "sellable":True,
                    "maxSellablePrice":15,
                    "royaltySellable":20,
                    "earlyBid":True,
                    "discountPrice":10,
                    "discountEndDate":"2024-07-30T10:00:00Z",
                    "canStream":False,
                    "image":"data:image/jpeg;base64,/9j/4Q/......."
                 
                }
        ),
        
        responses={
            201: openapi.Response(
                description="Ticket created successfully",
                schema=openapi.Schema(
                type=openapi.TYPE_OBJECT,
                properties={
                    'id': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_UUID,description="Ticket ID"),
                    'refEvent': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_UUID,description="Reference to the event for which the ticket will be created"),
                    'image': openapi.Schema(type=openapi.TYPE_STRING, description="Image URL for the event"),
                    'name': openapi.Schema(type=openapi.TYPE_STRING, description="Ticket Name ie VIP Pass, Standard Ticket, etc"),
                    'maxTickets': openapi.Schema(type=openapi.TYPE_INTEGER, description="Maximum number of tickets that can be sold"),
                    'maxTicketsPerUser': openapi.Schema(type=openapi.TYPE_INTEGER, description="Maximum number of tickets that can be purchased by users"),
                    'ticketPrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Ticket price"),
                    'bookingStartDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the start of the booking. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'bookingEndDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the end of the booking. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'description': openapi.Schema(type=openapi.TYPE_STRING, description="Ticket description. Will be displayed on the event page"),
                    'revealed': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Ticket is revealed or not. If revealed, the ticket image will be visible on the event page. If not revealed the hidden uri image will be displayed"),
                    'revealStartDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the start of the reveal. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'hiddenuri': openapi.Schema(type=openapi.TYPE_STRING,  description="Hidden uri of the ticket image. Will be displayed on the event page"),
                    'sellable': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Is Ticket sellable or not on marketplace such as Opensea.io."),
                    'maxSellablePrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Maximum price the ticket can be sold on marketplace such as Opensea.io."),
                    'royaltySellable': openapi.Schema(type=openapi.TYPE_INTEGER, description="Royalty you will receive for each sell on marketplace. Please provide a percentage (between 0 and 100)."),
                    'earlyBid': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Do you offer a discount."),
                    'discountPrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Price of the ticket if early bid is offered."),
                    'discountEndDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the end of the discount. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'canStream': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="If your event is a streaming managed by SellTix, does the ticket allow owners to stream during the event.")    
                }
                ),
                examples={
                    "application/json": {
                         "id": "b79aaf14-87bd-415f-be38-1898b6c96e8a",
                        "refEvent": "ade56c0f-8175-462d-b548-fac938fcab14",
                        "name": "Ticket standard",
                        "maxTickets": 100,
                        "maxTicketsPerUser": 5,
                        "ticketPrice": 20.0,
                        "bookingStartDate": "2024-07-01T10:00:00",
                        "bookingEndDate": "2024-08-31T10:00:00",
                        "description": "Get access to our conference",
                        "revealed": True,
                        "revealStartDate": None,
                        "hiddenuri": None,
                        "sellable": True,
                        "maxSellablePrice": 15.0,
                        "royaltySellable": 2000.0,
                        "earlyBid": True,
                        "discountPrice": 10.0,
                        "discountEndDate": "2024-07-30T10:00:00",
                        "canStream": False
                    }
                }
            ),
             400: openapi.Response(
                description="Bad request",
                schema=openapi.Schema(
                type=openapi.TYPE_OBJECT,
                    properties={
                        'status': openapi.Schema(type=openapi.TYPE_STRING, description="Status of the operation KO"),
                        'reason': openapi.Schema(type=openapi.TYPE_STRING, description="message of the failure exception"),
                    }
                ),
                examples={
                   "application/json": {
                        "status": "KO",
                        "reason": "The reason of the failure"
                    },
                    "Event not found": {
                                "status": "KO",
                                "reason": "Event does not exist"
                    },
                    "Not authorized": {
                       "status": "KO",
                        "reason": "You are not authorized to create a ticket type for this event"
                    },
                    "Event already published": {
                      "status": "KO",
                      'reason':"Event is already published"
                    },
                   "No image provided":{
                         "status": "KO",
                                'reason':"Please provide an image"
                   },
                   "Start date incoherence": {
                      "status": "KO",
                      'reason':"Booking start date should be before booking end date"
                    },
                   "End date incoherence": {
                      "status": "KO",
                      'reason':"Booking end date should be before event date"
                    },
                    "Reveal date incoherence": {
                      "status": "KO",
                      'reason':"Reveal start date should be before event date"
                    },
                    "Hiddenuri missing":{
                        "status": "KO",
                        'reason':"Please provide a hidden uri that will be used before revealing the ticket design"
                    },
                    "Tickets incoherence":{
                        "status": "KO",
                        'reason':"Max Tickets Per User should be less than max Tickets"
                    },
                    "Number of tickets incoherence":{
                        "status": "KO",
                        'reason':"Max Tickets should be greater than 0"
                    },
                    "Sellable price incoherence":{
                       "status": "KO",
                        'reason':"maxSellablePrice should be less or equal ticketPrice"
                    },
                    "Royalty incoherence":{
                        "status": "KO",
                        'reason':"Royalty sellable should be between 0 and 100"
                    },
                    "Discount price incoherence":{
                          "status": "KO",
                       'reason':"Discount price should be less than ticketPrice"
                    },
                    "Discount end date incoherence":{
                       "status": "KO",
                       'reason':"Discount end date should be before booking end date"
                    }
                }
            ),
            401: openapi.Response(
                description="Unauthorized",
                examples={
                    "application/json": {
                    
                        "detail": "Given token not valid for any token type",
                        "code": "token_not_valid",
                        "messages": [
                            {
                            "token_class": "AccessToken",
                            "token_type": "access",
                            "message": "Token is invalid or expired"
                            }
                        ]
                      
                }

                }
            ) 
        }
    )
    def post(self, request, format=None):
       
        try:
            organizer = User.objects.get(id=request.user.id)
           
            serializer = TicketTypeSerializerForCreate(data=request.data)
            if serializer.is_valid():
                theEvent = serializer.validated_data.get('refEvent')
                logger.info("===RefEvent===")
                logger.info(theEvent)
                if theEvent:
                    if theEvent.refOrganiser.id != organizer.id:
                        jsonToReturn = {
                            "status": "KO",
                            "reason": "You are not authorized to create a ticket type for this event"
                        }
                        return JsonResponse(jsonToReturn, safe=False,status=400)
                    if theEvent.status>0:
                        jsonToReturn = {
                            "status": "KO",
                            'reason':"Event is already published"
                        }
                        return JsonResponse(jsonToReturn, safe=False,status=400)
                    else:
                        #check image
                        image = serializer.validated_data.get('image')
                        if image is None:
                            jsonToReturn = {
                                "status": "KO",
                                'reason':"Please provide an image"
                            }
                            return JsonResponse(jsonToReturn, safe=False,status=400)
                        logger.info("===Check DAtes===")
                        # Check booking start date, end Date are before event date
                        bookingStartDate = serializer.validated_data.get('bookingStartDate')
                        bookingEndDate = serializer.validated_data.get('bookingEndDate')
                        if bookingStartDate > bookingEndDate:
                            jsonToReturn = {
                                "status": "KO",
                                'reason':"Booking start date should be before booking end date"
                            }
                            return JsonResponse(jsonToReturn, safe=False,status=400)
                        if bookingEndDate >= theEvent.eventDate:
                            jsonToReturn = {
                                "status": "KO",
                                'reason':"Booking end date should be before event date"
                            }
                            return JsonResponse(jsonToReturn, safe=False,status=400)
                         
                        # if not revealed check date coherence
                        revealed = serializer.validated_data.get('revealed')
                        if revealed==False:
                            revealStartDate = serializer.validated_data.get('revealStartDate')
                            if revealStartDate >= theEvent.eventDate:
                                jsonToReturn = {
                                    "status": "KO",
                                    'reason':"Reveal start date should be before event date"
                                }
                                return JsonResponse(jsonToReturn, safe=False,status=400)
                            hiddenuri = serializer.validated_data.get('hiddenuri')
                            if hiddenuri is None:
                                jsonToReturn = {
                                    "status": "KO",
                                    'reason':"Please provide a hidden uri that will be used before revealing the ticket design"
                                }
                                return JsonResponse(jsonToReturn, safe=False,status=400)
                        else:
                            revealStartDate = None
                            hiddenuri = None

                        logger.info("===Check number of tickets===")
                        # check maxTickerPerUser < maxTickets
                        maxTickets = serializer.validated_data.get('maxTickets')
                        maxTicketsPerUser = serializer.validated_data.get('maxTicketsPerUser')
                        if maxTickets<=0:
                            jsonToReturn = {
                                "status": "KO",
                                'reason':"Max Tickets should be greater than 0"
                            }
                            return JsonResponse(jsonToReturn, safe=False,status=400)
                        if maxTicketsPerUser > maxTickets:
                            jsonToReturn = {
                                "status": "KO",
                                'reason':"Max Tickets Per User should be less than max Tickets"
                            }
                            return JsonResponse(jsonToReturn, safe=False,status=400)
                        ticketPrice = serializer.validated_data.get('ticketPrice')
                        sellable = serializer.validated_data.get('sellable')
                        maxSellablePrice = serializer.validated_data.get('maxSellablePrice')
                        royaltySellable = serializer.validated_data.get('royaltySellable')
                        if sellable:
                            if maxSellablePrice > ticketPrice:
                                jsonToReturn = {
                                    "status": "KO",
                                    'reason':"maxSellablePrice should be less or equal ticketPrice"
                                }
                                return JsonResponse(jsonToReturn, safe=False,status=400)
                            
                            if royaltySellable<0 or royaltySellable>100:
                                jsonToReturn = {
                                    "status": "KO",
                                    'reason':"Royalty sellable should be between 0 and 100"
                                }
                                return JsonResponse(jsonToReturn, safe=False,status=400)
                            else:
                                #transform value for smart contract
                                royaltySellable = royaltySellable*100

                        # If discount check date coherence 
                        earlyBid = serializer.validated_data.get('earlyBid')
                        discountPrice = serializer.validated_data.get('discountPrice')
                        discountEndDate = serializer.validated_data.get('discountEndDate')
                        if earlyBid:
                            if discountPrice > ticketPrice:
                                jsonToReturn = {
                                    "status": "KO",
                                    'reason':"Discount price should be less than ticketPrice"
                                }
                                return JsonResponse(jsonToReturn, safe=False,status=400)
                            if discountEndDate >= bookingEndDate:
                                jsonToReturn = {
                                    "status": "KO",
                                    'reason':"Discount end date should be before booking end date"
                                }
                                return JsonResponse(jsonToReturn, safe=False,status=400)
                        
                        # create default template 
                        ticketTypeTemplate = TicketTypeTemplate()
                        ticketTypeTemplate.name = serializer.validated_data.get('name')
                        fullImage = ''
                        pinata_api_key = settings.PINATA_API_KEY
                        image_url = send_image_to_pinata(image, pinata_api_key)
                        if image_url:
                                fullImage = 'https://amber-large-nightingale-955.mypinata.cloud/ipfs/'+image_url
                        else:
                            fullImage = ''
                        ticketTypeTemplate.image = fullImage 
                        ticketTypeTemplate.fontUrl = "https://fonts.googleapis.com/css2?family=Alumni+Sans+Collegiate+One&amp;family=Montserrat:wght@400;800&amp;display=swap"
                        ticketTypeTemplate.templateId = 4
                        from backoffice.helpers import get_titles
                        titleOne, titleTwo = get_titles(theEvent.name)
                         
                        ticketTypeTemplate.gradient1Color ='#0dcaf0'
                        ticketTypeTemplate.gradient2Color = '#FF0090'
                        ticketTypeTemplate.eventTitleOne = titleOne
                        ticketTypeTemplate.eventTitleTWo = titleTwo
                        ticketTypeTemplate.eventTitleFont='25'
                        ticketTypeTemplate.eventColor = '#fff'
                        ticketTypeTemplate.categoryFont ='20'
                        ticketTypeTemplate.categoryColor ='#fff'
                        ticketTypeTemplate.ticketTypeFont = '25'
                        ticketTypeTemplate.ticketTypeColor = '#fff'
                        ticketTypeTemplate.price = str(ticketPrice)+ ' '+theEvent.currency
                        ticketTypeTemplate.priceColor = '#fff'
                        ticketTypeTemplate.priceFont = '15'
                        ticketTypeTemplate.typeEventColor = '#fff'
                        ticketTypeTemplate.typeEventFont = '15'
                        ticketTypeTemplate.venue = 'Online'
                        ticketTypeTemplate.svgUrl =''
                        ticketTypeTemplate.save()

                        name = serializer.validated_data.get('name')
                        description = serializer.validated_data.get('description')
                        canStream = serializer.validated_data.get('canStream')
                        ticketType = TicketType()
                        ticketType.refEvent = theEvent
                        ticketType.refTicketTypeTemplate = ticketTypeTemplate
                        ticketType.name = name
                        ticketType.maxTickets = maxTickets
                        ticketType.maxTicketsPerUser = maxTicketsPerUser
                        ticketType.ticketPrice = ticketPrice
                        ticketType.bookingStartDate = bookingStartDate
                        ticketType.bookingEndDate = bookingEndDate
                        ticketType.description = description
                        ticketType.revealed = revealed
                        ticketType.revealStartDate = revealStartDate
                        ticketType.hiddenuri = hiddenuri
                        ticketType.sellable = sellable
                        ticketType.maxSellablePrice = maxSellablePrice
                        ticketType.royaltySellable = royaltySellable
                        ticketType.earlyBid = earlyBid
                        ticketType.discountPrice = discountPrice
                        ticketType.discountEndDate = discountEndDate
                     
                        if theEvent.isConference:
                            ticketType.fixAmount = 0.1
                        elif theEvent.streamWithSelltix:
                            ticketType.fixAmount = 0.6
                        else:
                            ticketType.fixAmount = 0.3
                            
                        ticketType.canStream = canStream
                        ticketType.save()
                        return JsonResponse(TicketTypeForReadSerializer(ticketType).data, safe=False, status=201)
                else:
                    jsonToReturn = {
                        "status": "KO",
                        'reason':"Event does not exist"
                    }
                    return JsonResponse(jsonToReturn, safe=False,status=400)
               
                
            else:
                jsonToReturn = {
                    "status": "KO",
                    'reason':serializer.errors
                }
                return JsonResponse(jsonToReturn, safe=False,status=400)
        
        except Exception as e:
            logger.error(e)
            logger.error(serializer.validated_data)
            jsonToReturn = {
                    "status": "KO",
                    'reason':str(e)
            }
            return JsonResponse(jsonToReturn, safe=False,status=400)
 
class DeleteTicket(APIView):
    permission_classes = [permissions.IsAuthenticated]
    @swagger_auto_schema(
        operation_id='deleteTicket',
        operation_description="""Delete a ticket.
        <br><br><b>Note:</b> If the event is already published the delete operation will not be allowed.
          """,
         tags=['Tickets'],
         responses={
            200: openapi.Response(
                description="Ticket deleted successfully"
            ),
            400: openapi.Response(
                description="Bad request",
                schema=openapi.Schema(
                type=openapi.TYPE_OBJECT,
                    properties={
                        'status': openapi.Schema(type=openapi.TYPE_STRING, description="Status of the operation KO"),
                        'reason': openapi.Schema(type=openapi.TYPE_STRING, description="message of the failure exception"),
                    }
                ),
                examples={
                    "application/json": {
                        "status": "KO",
                        "reason": "Ticket does not exist"
                   },
                   "Ticket not found":{
                       "status": "KO", 
                       'reason': 'Ticket not found'
                   },
                   "Not owner":{
                       "status": "KO", 
                       'reason': 'Not allowed'
                   },
                   "Event published":{
                       "status": "KO",
                       'reason': 'Event is published'
                   }
                }
            ),
            401: openapi.Response(
                description="Unauthorized",
                examples={
                    "application/json": {
                    
                        "detail": "Given token not valid for any token type",
                        "code": "token_not_valid",
                        "messages": [
                            {
                            "token_class": "AccessToken",
                            "token_type": "access",
                            "message": "Token is invalid or expired"
                            }
                        ]
                      
                }

                }
            ) 
        }
    )
    def delete(self, request, pk=None, format=None):
        try:
            ticketType = TicketType.objects.get(id=pk)
            if ticketType.refEvent.refOrganiser.id!= request.user.id:
                return JsonResponse({"status": "KO", 'reason': 'Not allowed'}, safe=False, status=400)
            
            if ticketType.refEvent.status>0:
                return JsonResponse({"status": "KO", 'reason': 'Event is published'}, safe=False, status=400)
            
            image = ticketType.refTicketTypeTemplate.image
            if len(image)>5:
                unpin_image(image)
            ticketType.refTicketTypeTemplate.delete()
            ticketType.delete()
            return JsonResponse({},safe=False, status=200)
        except TicketType.DoesNotExist:
            return JsonResponse({"status": "KO", 'reason': 'Ticket not found'}, safe=False, status=404)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"status": "KO", 'reason': str(e)}, safe=False, status=400)


class TicketsAPIListView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    
    @swagger_auto_schema(
        operation_id='getTickets',
        operation_description="""Get all your tickets.
        <br><br><b>Note:</b> 
        <br><br>If you want tickets for a specific event you can use the refEvent parameter and pass it in the query url.
        """,
         tags=['Tickets'],
         responses={
            200: openapi.Response(
                description="List of all organizer tickets",
                schema=openapi.Schema(
                type=openapi.TYPE_OBJECT,
                properties={
                     'id': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_UUID,description="Ticket ID"),
                    'refEvent': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_UUID,description="Reference to the event for which the ticket has been created"),
                    'image': openapi.Schema(type=openapi.TYPE_STRING, description="Image URL for the event"),
                    'name': openapi.Schema(type=openapi.TYPE_STRING, description="Ticket Name ie VIP Pass, Standard Ticket, etc"),
                    'maxTickets': openapi.Schema(type=openapi.TYPE_INTEGER, description="Maximum number of tickets that can be sold"),
                    'maxTicketsPerUser': openapi.Schema(type=openapi.TYPE_INTEGER, description="Maximum number of tickets that can be purchased by users"),
                    'ticketPrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Ticket price"),
                    'bookingStartDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the start of the booking. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'bookingEndDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the end of the booking. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'description': openapi.Schema(type=openapi.TYPE_STRING, description="Ticket description. Will be displayed on the event page"),
                    'revealed': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Ticket is revealed or not. If revealed, the ticket image will be visible on the event page. If not revealed the hidden uri image will be displayed"),
                    'revealStartDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the start of the reveal. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'hiddenuri': openapi.Schema(type=openapi.TYPE_STRING,  description="Hidden uri of the ticket image. Will be displayed on the event page"),
                    'sellable': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Is Ticket sellable or not on marketplace such as Opensea.io."),
                    'maxSellablePrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Maximum price the ticket can be sold on marketplace such as Opensea.io."),
                    'royaltySellable': openapi.Schema(type=openapi.TYPE_INTEGER, description="Royalty you will receive for each sell on marketplace. Please provide a percentage (between 0 and 100)."),
                    'earlyBid': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="Do you offer a discount."),
                    'discountPrice': openapi.Schema(type=openapi.TYPE_NUMBER, description="Price of the ticket if early bid is offered."),
                    'discountEndDate': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME, description="Date and time of the end of the discount. <b>Very important</b> should be in <strong>UTC format</strong> : %Y-%m-%dT%H:%M:%SZ"),
                    'canStream': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="If your event is a streaming managed by SellTix, does the ticket allow owners to stream during the event.")    
                    }
                ),
                examples={
                    "application/json": {
                            "count": 1,
                            "next": None,
                            "previous": None,
                            "results": [
                                {
                                 "id": "0bbcd4ad-604a-4687-8e0b-ffefc6d994b5",
                                "refEvent": "ade56c0f-8175-462d-b548-fac938fcab14",
                                "name": "Ticket standard",
                                "maxTickets": 100,
                                "maxTicketsPerUser": 5,
                                "ticketPrice": 20.0,
                                "bookingStartDate": "2024-07-01T10:00:00",
                                "bookingEndDate": "2024-08-31T10:00:00",
                                "description": "Get access to our conference",
                                "revealed": True,
                                "revealStartDate": None,
                                "hiddenuri": None,
                                "sellable": True,
                                "maxSellablePrice": 15.0,
                                "royaltySellable": 2000.0,
                                "earlyBid": True,
                                "discountPrice": 10.0,
                                "discountEndDate": "2024-07-30T10:00:00",
                                "canStream": False
                                }
                            ]
                    }
                }
            ),
            400: openapi.Response(
                description="Bad request",
                schema=openapi.Schema(
                type=openapi.TYPE_OBJECT,
                    properties={
                        'status': openapi.Schema(type=openapi.TYPE_STRING, description="Status of the operation KO"),
                        'reason': openapi.Schema(type=openapi.TYPE_STRING, description="message of the failure exception"),
                    }
                ) 
            ),
            401: openapi.Response(
                description="Unauthorized",
                examples={
                    "application/json": {
                    
                        "detail": "Given token not valid for any token type",
                        "code": "token_not_valid",
                        "messages": [
                            {
                            "token_class": "AccessToken",
                            "token_type": "access",
                            "message": "Token is invalid or expired"
                            }
                        ]
                      
                }

                }
            ) 
        }
    )      
    def get(self, request, format=None):
            try:
                ref_event = request.query_params.get('refEvent')
                if ref_event:
                    tickets = TicketType.objects.filter(refEvent__id=ref_event, refEvent__refOrganiser=request.user)
                else:
                    tickets = TicketType.objects.filter(refEvent__refOrganiser=request.user)
                paginator = CustomPagination()
                paginated_tickets = paginator.paginate_queryset(tickets, request)
                serializer = TicketTypeForReadSerializer(paginated_tickets, many=True)
                return paginator.get_paginated_response(serializer.data)
            except Exception as e:
                logger.error(e)
                return JsonResponse({"status": "KO", 'reason': str(e)}, safe=False, status=400)
    
 