from __future__ import unicode_literals
from datetime import timezone
 
from django.db import models
import uuid
from sorl.thumbnail import ImageField
from django.utils.text import slugify
from django.db.models.signals import post_save
from backoffice.signals import *
from django.utils.crypto import get_random_string
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin
import pytz
from django.utils import timezone

def unique_slugify(instance, slug):
    model = instance.__class__
    unique_slug = slug
    while model.objects.filter(slug=unique_slug).exists():
        unique_slug = slug + get_random_string(length=4)
    return unique_slug

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields)
    
class User(AbstractBaseUser, PermissionsMixin):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    email = models.EmailField(('email address'), unique=True)
    first_name = models.CharField(('first name'), max_length=30, blank=True)
    last_name = models.CharField(('last name'), max_length=30, blank=True)
    date_joined = models.DateTimeField(('date joined'), auto_now_add=True)
    is_active = models.BooleanField(('active'), default=True)
    is_staff = models.BooleanField(('is_staff'), default=True)
    phoneNumber = models.CharField(('phone number'), max_length=40,blank=True)
    walletAddress = models.CharField(max_length=100,null=True,blank=True)
    generatedWallet = models.BooleanField(default=False)
    publicKey = models.CharField(max_length=256,null=True,blank=True)
    privateKey = models.CharField(max_length=256,null=True,blank=True)
    words = models.CharField(max_length=2048,null=True,blank=True)
    pinCode = models.CharField(max_length=256,null=True,blank=True)
    isOrganizer = models.BooleanField(default=False)
    cryptoAccepted = models.BooleanField(default=True)
    usdtAccepted = models.BooleanField(default=True)
    usdcAccepted = models.BooleanField(default=True)
    eureAccepted = models.BooleanField(default=True)
    cbAccepted = models.BooleanField(default=True)
    type_organiser = (
        (0, "NotSet"),
        (1, "Individual"),
        (2, "Company"),
        (3,"Association"),
        (4,"Particular")
    )
    organiserType = models.IntegerField(choices=type_organiser, default=0, db_index=True)
    organizerContract =  models.CharField(max_length=100,null=True,blank=True)
    organizerCompany =  models.CharField(max_length=200,null=True,blank=True)
    organizerAddress =  models.CharField(max_length=200,null=True,blank=True)
    organizerCity =  models.CharField(max_length=200,null=True,blank=True)
    organizerZipCode =  models.CharField(max_length=200,null=True,blank=True)
    organizerCurrency = models.CharField(max_length=5,default='eur')
    vatNumber =  models.CharField(max_length=200,null=True,blank=True)
    organizeWebsite =  models.CharField(max_length=200,null=True,blank=True)
    organizerDescription =  models.TextField(null=True,blank=True)
    organizerImage =  models.ImageField(upload_to='organizer_images/', null=True, blank=True)
    transactionHash = models.CharField(max_length=100,null=True,blank=True)
    nonce =  models.CharField(max_length=10,null=True,blank=True)
    country = models.CharField(max_length=2,default='FR')
    signInToken = models.CharField(max_length=100,null=True,blank=True)
    stripeCustomerId = models.CharField(max_length=100,null=True,blank=True)
    accountLocked = models.BooleanField(default=False)
    accountFinalized = models.BooleanField(default=False)
    appleGoogleWallet = models.BooleanField(default=False)
    qrcodeTimeout = models.IntegerField(default=1)
    lastLoginCode = models.CharField(max_length=7,null=True,blank=True)
    lastLoginCodeDate = models.DateTimeField(null=True,blank=True)
    maticSent = models.BooleanField(default=False)
    webhookUrl = models.CharField(max_length=200,null=True,blank=True)
    timezone = models.CharField(
        max_length=50,
        default='Europe/Paris',
        choices=[(tz, tz) for tz in pytz.all_timezones],
        help_text="User's preferred timezone"
    )
    subscription = models.BooleanField(default=False)
    subscriptionPrice = models.IntegerField(default=0)
    subscriptionStartDate = models.DateTimeField(null=True,blank=True)
    subscriptionEndDate = models.DateTimeField(null=True,blank=True)
    subscriptionStatus = models.CharField(max_length=20,default='inactive')
    accountCreatedBySellTix = models.BooleanField(default=False)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

    def __str__(self):
        return self.email

post_save.connect(signal_updateuser, dispatch_uid="signal_updateuser",sender=User)

class Seller(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    stripe_user_id = models.CharField(max_length=255, blank=True)
    stripe_access_token = models.CharField(max_length=255, blank=True)
    stripe_charges_enabled = models.BooleanField(default=False)
    stripe_account_json = models.TextField(default="")
    def __str__(self):
        return self.user.email


class ScanUsers(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    login = models.CharField(max_length=100,unique=True)
    password = models.CharField(max_length=20)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

class Category(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255,help_text="Category Name",unique=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name_plural='Categories'

    def __str__(self):
        return str(self.name)    

class EventPageTemplate(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name =  models.CharField(max_length=100,null=True,blank=True)
    image = ImageField(upload_to='images')
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    

    def __str__(self):
        return u'%d - %s' % (self.id, self.name)
 
    
class Event(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refOrganiser = models.ForeignKey(User,on_delete=models.SET_NULL,null=True,related_name="event_organiser")
    refCategory = models.ForeignKey(Category,on_delete=models.SET_NULL,null=True,blank=True,related_name="event_category",help_text="Category associated with the event")
    refEventPageTemplate = models.ForeignKey(EventPageTemplate,on_delete=models.SET_NULL,null=True,blank=True,related_name="event_page_template")
    type_event = (
        (0, "Online"),
        (1, "Venue"),
        (2, "Content")
    )
    eventType = models.IntegerField(choices=type_event, default=0, db_index=True)
    status_event = (
        (0, "Created"),
        (1, "Published"),
        (2, "Cancel"),
    )
    status = models.IntegerField(choices=status_event, default=1, db_index=True,help_text="Status of the event: 0:Created 1:Published 2:Cancel")
    isPrivate = models.BooleanField(default=False,help_text='Organizer does not want SellTix to reference this event on it''s website')
    openBookings = models.BooleanField(default=False,help_text='No conditions on booking end date')
    eventContract =  models.CharField(max_length=100,null=True,blank=True)
    ticketContract =  models.CharField(max_length=100,null=True,blank=True)
    paymentContract =  models.CharField(max_length=100,null=True,blank=True)
    ticketTypeContract =  models.CharField(max_length=100,null=True,blank=True)
    transactionHash = models.CharField(max_length=100,null=True,blank=True)
    name = models.CharField(max_length=250,help_text="Event Name")
    slug = models.SlugField(max_length=250,default="", null=False,unique=True)
    description = models.TextField()
    venueName = models.CharField(max_length=255)
    venueAddress = models.CharField(max_length=255)
    venueGeoloc = models.CharField(max_length=255) 
    eventDate = models.DateTimeField(help_text="The UTC date of the event in format %Y-%m-%dT%H:%M:%SZ", default=timezone.now)
    
    currency = models.CharField(max_length=10,default="EUR")
    duration = models.IntegerField(help_text='Duration of the event in minutes') # event Date contient jour + heure debut + duration = jour/heure fin
    entryTime = models.TimeField(null=True,blank=True)
    previewVideo = models.CharField(max_length=200,null=True,blank=True)
    onlineUrl = models.CharField(max_length=200,null=True,blank=True,help_text="Link of the conference event if not managed by SellTix")
    website = models.CharField(max_length=200,null=True,blank=True,help_text="URL of the website to present event")
    image =  models.CharField(max_length=512,help_text="An image to illustrate the Event")
    cryptoAccepted = models.BooleanField(default=True)
    cbAccepted = models.BooleanField(default=True)
    webHookSet  = models.BooleanField(default=False)
    alchemyWebHookId = models.CharField(max_length=200,null=True,blank=True)
    royalty  = models.FloatField(default=500) #default 5%
    sellTixRoyaltieValue = models.FloatField(default=1000) #default 10% for online
    appleGoogleWallet = models.BooleanField(default=False)
    qrcodeTimeout = models.IntegerField(default=1)
    isConference = models.BooleanField(default=False)
    streamingId = models.CharField(max_length=200,null=True,blank=True)
    streamWithSelltix = models.BooleanField(default=False)
    streaming_quality = (
        (0, "SD"),
        (1, "HD"),
    )
    streamingQuality = models.IntegerField(choices=streaming_quality, default=0, db_index=True)
    recordStreaming = models.BooleanField(default=False)
    recordedVideo = models.BooleanField(default=False)
    recordedFile = models.FileField(upload_to='videos',null=True,blank=True)
    recordedStreamingUrl = models.CharField(max_length=200,null=True,blank=True)
    mailRappelSent = models.BooleanField(default=False)
    ended = models.BooleanField(default=False,help_text="Used to know if the event is finished")
    isFreeOfCharge = models.BooleanField(default=False,help_text="Used to know if the event is free of charge, meaning all tickets will be free")
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name_plural='Events'

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = unique_slugify(self, slugify(self.name))
        super().save(*args, **kwargs)


    def __str__(self):
        return u'%d - %s' % (self.eventType, self.name)
#on envoi un push
post_save.connect(signal_modifEvent, dispatch_uid="update_event",sender=Event)

     
class EventPayees(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refEvent = models.ForeignKey(Event,on_delete=models.SET_NULL,null=True,related_name="event_payees")
    walletAddress =  models.CharField(max_length=100)
    shareAmount = models.FloatField(default=0)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    class Meta:
        unique_together = ('refEvent', 'walletAddress',)
        verbose_name_plural='EventPayees'

class EventParticipant(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refEvent = models.ForeignKey(Event,on_delete=models.SET_NULL,null=True,related_name="event_participant")
    refUser = models.ForeignKey(User,on_delete=models.SET_NULL,null=True,related_name="event_participant_user")
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    class Meta:
        unique_together = ('refEvent', 'refUser',)
        verbose_name_plural='EventParticipants'

class Content(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refOrganiser = models.ForeignKey(User,on_delete=models.SET_NULL,null=True,related_name="content_organiser")
    type_content = (
        (0, "PDF"),
        (1, "VIDEO"),
        (2, "IMAGE"),
        (3, "ZIP"),
        (4, "AUDIO"),
    )
    typeContent = models.IntegerField(choices=type_content, default=0, db_index=True)
    fileContentType = models.CharField(max_length=255,null=True,blank=True)
    contentContract =  models.CharField(max_length=100,null=True,blank=True)
    ticketContract =  models.CharField(max_length=100,null=True,blank=True)
    name = models.CharField(max_length=255)
    description = models.TextField()
    canceled = models.BooleanField(default=False)
    royalty  = models.FloatField(default=2000) #default 20%
    sellTixRoyaltieValue = models.FloatField(default=1000) #default 10% for online
    ticketPrice = models.FloatField(default=0)
    sellable = models.BooleanField(default=True)
    maxSellablePrice = models.FloatField(default=0)
    fixAmount= models.FloatField(default=0)
    unlimitedAccess  = models.BooleanField(default=True)
    restrictedAge = models.BooleanField(default=False)
    image =  models.CharField(max_length=512,help_text="An image to illustrate the Content")
    contentFile = models.FileField(upload_to='content',null=True,blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name_plural='Contents'
    
    def __str__(self):
        return u'%s - %s' % (self.refOrganiser, self.name)

class ContentProtection(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    uniqueId = models.CharField(max_length=255)
    used = models.BooleanField(default=False)
    nbUsed = models.IntegerField(default=0)
    num_segments = models.IntegerField(default=1)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    class Meta:
        verbose_name_plural='ContentProtections'
    
    def __str__(self):
        return u'%s - %s' % (self.uniqueId, self.used)
    
class TicketTypeTemplate(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name =  models.CharField(max_length=100,null=True,blank=True)
    image = models.URLField(max_length=512)
    fontUrl = models.URLField(max_length=512)
    templateId = models.IntegerField(default=1)
    gradient1Color =  models.CharField(max_length=10,default="#0dcaf0")
    gradient2Color =  models.CharField(max_length=10,default="#FF0090")
    eventTitleOne=  models.CharField(max_length=30)
    eventTitleTWo=  models.CharField(max_length=30,null=True,blank=True)
    eventTitleFont=  models.CharField(max_length=10,default='30')
    eventColor=  models.CharField(max_length=10,default='#fff')
    categoryFont=  models.CharField(max_length=10,default='20')
    categoryColor=  models.CharField(max_length=10,default='#fff')
    ticketTypeFont=  models.CharField(max_length=10,default='25')
    ticketTypeColor=  models.CharField(max_length=10,default='#fff')
    price=  models.CharField(max_length=80)
    priceColor=  models.CharField(max_length=10,default='#fff')
    priceFont=  models.CharField(max_length=10,default='15')
    typeEventColor=  models.CharField(max_length=10,default='#fff')
    typeEventFont=  models.CharField(max_length=10,default='21')
    venue=  models.CharField(max_length=30,null=True,blank=True)
    svgUrl = models.URLField(max_length=512,null=True,blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    

    def __str__(self):
        return u'%d - %s' % (self.id, self.name)
    
class TicketType(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refEvent = models.ForeignKey(Event,on_delete=models.SET_NULL,null=True,blank=True)
    refTicketTypeTemplate = models.ForeignKey(TicketTypeTemplate,on_delete=models.SET_NULL,null=True,blank=True)
    ticketTypeId = models.IntegerField(default=-1)
    transactionHash = models.CharField(max_length=100,null=True,blank=True)
    name =  models.CharField(max_length=100,null=True,blank=True)
    maxTickets = models.IntegerField(default=1)
    maxTicketsPerUser =  models.IntegerField(default=1)
    ticketPrice = models.FloatField(default=0)
    bookingStartDate = models.DateTimeField(default=timezone.now,help_text="The UTC date in format %Y-%m-%dT%H:%M:%SZ")
    bookingEndDate = models.DateTimeField(default=timezone.now,help_text="The UTC date in format %Y-%m-%dT%H:%M:%SZ")
    description = models.TextField(null=True,blank=True)
    revealed = models.BooleanField(default=False)
    revealStartDate = models.DateTimeField(null=True,blank=True,default=timezone.now,help_text="The UTC date in format %Y-%m-%dT%H:%M:%SZ")
    sellable = models.BooleanField(default=False)
    maxSellablePrice  = models.FloatField(default=0)
    royaltySellable  = models.FloatField(default=0)
    earlyBid  = models.BooleanField(default=False)
    discountPrice = models.FloatField(default=0)
    discountEndDate = models.DateTimeField(null=True,blank=True,default=timezone.now,help_text="The UTC date in format %Y-%m-%dT%H:%M:%SZ")
    hiddenuri =  models.CharField(max_length=255,null=True,blank=True)
    hasRule = models.BooleanField(default=False)
    fixAmount = models.FloatField(default=0)
    freeDrink = models.BooleanField(default=False)
    priorityQueue = models.BooleanField(default=False)
    canStream = models.BooleanField(default=False)
    transferable = models.BooleanField(default=True)
    status_ticketType = (
        (0, "Created"),
        (1, "Published"),
        (2, "Deleted"),
    )
    status = models.IntegerField(choices=status_ticketType, default=0, db_index=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name_plural='TicketsType'

    def __str__(self):
        return u'%s - %d : %s' % (self.refEvent, self.ticketTypeId,self.name)
#post_save.connect(signal_publishTicketType, dispatch_uid="signal_publishTicketType",sender=TicketType)


class TicketHistory(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refUser = models.ForeignKey(User,on_delete=models.SET_NULL,null=True,blank=True)
    wallet =  models.CharField(max_length=100,null=True,blank=True)
    pricePaid = models.FloatField(default=0) 
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    class Meta:
        verbose_name_plural='TicketHistory'

    def __str__(self):
        return u'%s' % (self.id)
    
class Ticket(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refUser = models.ForeignKey(User,on_delete=models.SET_NULL,null=True,blank=True)
    refTicketType = models.ForeignKey(TicketType,on_delete=models.SET_NULL,null=True,blank=True)
    refContent = models.ForeignKey(Content,on_delete=models.SET_NULL,null=True,blank=True)
    transactionHash = models.CharField(max_length=100,null=True,blank=True)
    ticketId = models.IntegerField()
    lastOwner =  models.CharField(max_length=100,null=True,blank=True)
    hashedTicket = models.CharField(max_length=100)
    pricePaid = models.FloatField(default=0) 
    owners = models.ManyToManyField(TicketHistory,blank=True)
    hasBeenOffered = models.BooleanField(default=False)
    transferedToSellTix = models.BooleanField(default=False,help_text="En cas de vente ou si offert, on transfère à SellTix")
    sellable = models.BooleanField(default=False,help_text="Ticket en vente")
    priceForSell = models.FloatField(default=0,help_text="Prix de vente")
    sellInProgress  = models.BooleanField(default=False,help_text="En cours de vente")
    dateSellInProgress = models.DateTimeField(null=True,blank=True)
    type_ticket_choice = (
        (0, "Event"),
        (1, "Content"),
    )
    typeTicket = models.IntegerField(choices=type_ticket_choice, default=0, db_index=True)
    status_ticket = (
        (0, "To be minted"),
        (1, "minted"),
        (2, "Deleted"),
    )
    status = models.IntegerField(choices=status_ticket, default=0, db_index=True)
    scanned = models.BooleanField(default=False)
    hasParticipated = models.BooleanField(default=False)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name_plural='Tickets'

    def __str__(self):
        if self.refTicketType:
            return u'%s - %d' % (self.refTicketType.refEvent, self.ticketId)
        else:
            return u'%d'%self.ticketId


class Payment(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refUser = models.ForeignKey(User, models.SET_NULL, related_name='paiementsFrom', db_index=True,null=True)
    toUser = models.ForeignKey(User, models.SET_NULL, related_name='paiementsTo', db_index=True,null=True,blank=True)
    type_payment = (
        (0, "Achat"),
        (1, "Offrir"),
        (2, "GasFees"),
        (3, "Vente"),
    )
    typePayment = models.IntegerField(choices=type_payment, default=0, db_index=True)
    refTicketType = models.ForeignKey(TicketType,on_delete=models.SET_NULL,null=True,blank=True)
    refContent = models.ForeignKey(Content,on_delete=models.SET_NULL,null=True,blank=True)
    nbTickets = models.IntegerField(default=1)
    jsonStripe = models.TextField(null=True,blank=True)
    extraInfo = models.TextField(null=True,blank=True)
    paymentIntent = models.CharField(max_length=255,null=True,blank=True,help_text="Stripe PaymentIntent or transactionHash")
    amount = models.FloatField()
    feesSelltix = models.FloatField(default=0)
    feesStripeForSellTix = models.FloatField(default=0)
    polPrice = models.FloatField(default=0)
    withWallet = models.CharField(max_length=100,null=True,blank=True,help_text="Wallet SellTix utilisé pour creer transaction blockchain")
    web2 = models.BooleanField(default=True)
    isContent = models.BooleanField(default=False)
    isPackGasFees = models.BooleanField(default=False)
    status_payment = (
        (0, "Initiated"),
        (1, "Done"),
        (2, "Refunded")
    )
    status = models.IntegerField(choices=status_payment, default=0, db_index=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return u'%s - %d €' % (self.refUser,self.amount)

class Invoice(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refUser = models.ForeignKey(User, models.SET_NULL, related_name='user_invoices', db_index=True,null=True)
    payments = models.ManyToManyField(Payment, related_name='invoices')
    month = models.IntegerField()
    year = models.IntegerField()
    totalVATExcluded = models.FloatField(default=0)
    vatAmount = models.FloatField(default=0)
    totalVATIncluded = models.FloatField(default=0)
    paid = models.BooleanField(default=False)
    pdfFile = models.FileField(upload_to='invoices',null=True,blank=True)
    stripeInvoiceId = models.CharField(max_length=100,null=True,blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    def __unicode__(self):
        return u'%s - %d %d : %d €' % (self.refUser,self.month,self.year,self.totalVATIncluded)
     

class TicketToMint(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refUser = models.ForeignKey(User, models.SET_NULL, related_name='ticketuser', db_index=True,null=True)
    refTicketType = models.ForeignKey(TicketType,on_delete=models.SET_NULL,null=True,blank=True)
    refPayment = models.ForeignKey(Payment,on_delete=models.SET_NULL, db_index=True,null=True)
    reservationId = models.CharField(max_length=255)
    withWallet = models.CharField(max_length=100,null=True,blank=True)
    status_mint = (
        (0, "To_do"),
        (1, "Done"),
        (2,"Failed"),
        (3,"Minting")
    )
    transactionHash = models.CharField(max_length=100,null=True,blank=True)
    status = models.IntegerField(choices=status_mint, default=0, db_index=True)
    nbFailure = models.IntegerField(default=0)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return u'%s - %s' % (self.refTicketType,self.refPayment)

class WebHook(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    webhookId = models.CharField(max_length=100)
    payload =  models.TextField(null=True,blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return u'%s - %s' % (self.webhookId,self.createdAt)

class Notification(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    refOrganizer = models.ForeignKey(User, models.SET_NULL, related_name='organizers', db_index=True,null=True)
    refEvent = models.ForeignKey(Event, models.SET_NULL, related_name='events', db_index=True,null=True)
    notifId = models.CharField(max_length=255)
    type = models.CharField(max_length=100)
    message = models.TextField(null=True,blank=True)
    success = models.BooleanField(default=False)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return u'%s - %s : %d' % (self.refOrganizer,self.notifId,self.success)

class BlockchainSync(models.Model):
    refEvent = models.ForeignKey(Event, models.SET_NULL, related_name='event_event', db_index=True,null=True)
    contract_address = models.CharField(max_length=42)
    last_block = models.BigIntegerField()
    createdAt = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

class Tasks(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    status_batch = (
        (0, "To_do"),
        (1, "Doing"),
        (2,"Done"),
        (3,"Error")
    )
    status = models.IntegerField(choices=status_batch, default=0, db_index=True)
    action = models.CharField(max_length=100)
    metadata = models.TextField(null=True,blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return u'%s - %d' % (self.id,self.status)


class Invitation(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    code = models.CharField(max_length=20,blank=True,null=True)
    burned = models.BooleanField(default=False)
    walletSellTixUsedForTransfer = models.CharField(max_length=100,null=True,blank=True)
    fromUser = models.ForeignKey(User, models.SET_NULL, related_name='userinvite', db_index=True,null=True)
    toUser = models.CharField(max_length=255,default='')
    emailSent = models.CharField(max_length=100,null=True,blank=True)
    refTicket = models.ForeignKey(Ticket,on_delete=models.SET_NULL,null=True,blank=True)
    refPayment = models.ForeignKey(Payment,on_delete=models.SET_NULL, db_index=True,null=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return u'%s - %s' % (self.refTicket__refTicketType__refEvent_name,self.code)

class TransactionManager(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    wallet = models.CharField(max_length=100,null=True,blank=True)
    transactionHashId = models.CharField(max_length=100,null=True,blank=True)
    jsonData = models.TextField(null=True,blank=True)
    nonceValue = models.CharField(max_length=100,null=True,blank=True)
    status_type = (
        (0,"Done"),
        (1,"Error")
    )
    status = models.IntegerField(choices=status_type, default=0, db_index=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    def __unicode__(self):
        return u'%s - %s' % (self.transactionHashId,self.status)
    
class InscriptionNewsletter(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    email = models.CharField(max_length=100,null=True,blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    def __unicode__(self):
        return u'%s - %s' % (self.createdAt,self.email)

class POLPrice(models.Model):
    price = models.FloatField(default=0)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    def __unicode__(self):
        return u'%s - %s' % (self.createdAt,self.price)

class Newsletter(models.Model):
    subject = models.CharField(max_length=200)
    mjml_content = models.TextField()
    html_content = models.TextField(blank=True)
    recipients = models.TextField(null=True,blank=True,help_text="List of email addresses separated by commas")
    created_at = models.DateTimeField(auto_now_add=True)
    sent_at = models.DateTimeField(null=True, blank=True)
    status = models.CharField(max_length=20, choices=[
        ('draft', 'Draft'),
        ('sent', 'Sent')
    ], default='draft')
