from django.db import models
from django.utils.html import format_html
from django.contrib.postgres.fields import HStoreField, ArrayField
from taggit.managers import TaggableManager

from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from mptt.models import MPTTModel, TreeForeignKey, TreeManyToManyField
from djrichtextfield.models import RichTextField
from django_editorjs_fields import EditorJsJSONField  # Django >= 3.1
from django_editorjs_fields import EditorJsTextField
from filebrowser.fields import FileBrowseField
import qrcode
import base64
import uuid

from django.conf import settings
from django_google_maps.fields import AddressField, GeoLocationField
from phonenumber_field.modelfields import PhoneNumberField


# Create your models here.
PROCESS = "process"
STATUS_CHOICES = [
    ('process', 'Process'),
    ('fn', 'Finished'),
    ('purchase', 'Purchase')
]
GENDER_CHOICES = [
    ('na', 'N/A'),
    ('lgbt', 'LGBT'),
    ('male', 'Male'),
    ('female', 'Female'),
]

MENU_GROUP_CHOICES = [
    ('primary', 'Primary'),
    ('footer', 'Footer'),
    ('secondary', 'Secondary'),
]


class Profile(models.Model):
    STORE_OWNER = 1
    CHEF = 2
    EMPLOYEE = 3
    ROLE_CHOICES = (
        (STORE_OWNER, 'Store Owner'),
        (CHEF, 'Chef'),
        (EMPLOYEE, 'Employee'),
    )

    user = models.OneToOneField(User, on_delete=models.CASCADE)
    location = models.CharField(max_length=30, blank=True)
    birthdate = models.DateField(null=True, blank=True)
    role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
    store = models.ForeignKey('Store', on_delete=models.CASCADE, null=True, blank=False)

    def __str__(self):  # __unicode__ for Python 2
        return self.user.username

@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

    else:
        try:
            instance.profile.save()
        except:
            Profile.objects.create(user=instance)

class GeneralField(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)

    class Meta:
        abstract = True

class ProcesslField(models.Model):
    inProcess = models.CharField(max_length=100, blank=True, null=True)
    status = models.CharField(max_length=100,choices=STATUS_CHOICES,default=PROCESS)

    class Meta:
        abstract = True

class MenuItem(GeneralField, models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField(blank=True, null=True)
    store = models.ForeignKey('Store', on_delete=models.CASCADE)
    qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
    featureImage = models.ImageField(upload_to='uploads/%Y/%m/%d/', blank=True, null=True)
    description = models.TextField(blank=True, null=True)
    '''
    photos = ArrayField(
        models.FileField(upload_to='uploads/%Y/%m/%d/'),
        size=8,blank=True,null=True)
    '''


    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.qrCode.name = self.genCode()
        super(MenuItem, self).save(*args, **kwargs)

    @property
    def qrImage(self):
        if self.qrCode:
             return format_html('<img src="{}" width="100%">', self.qrCode.url)
        else:
            return "-"

    def genCode(self):
        img = qrcode.make(f"{self.store.name}#{self.name}#{self.id}")
        rid = uuid.uuid4().hex
        path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
        rpath = f"qr/{rid}.png"
        img.save(path)
        return rpath


class Ingredient(GeneralField, models.Model):
    name = models.CharField(max_length=200)
    qty = models.DecimalField(decimal_places=2, max_digits=5)
    unit = models.CharField(max_length=10)
    comment = models.TextField(blank=True, null=True)
    menu = models.ForeignKey('MenuItem', on_delete=models.CASCADE)

class Store(GeneralField, models.Model):
    name = models.CharField(max_length=100, blank=False, null=False, default="Unititled")
    addressText = models.TextField(blank=True, null=True)
    province = models.CharField(max_length=100, blank=True, null=True)
    storeType = models.CharField("Store Type", max_length=100, blank=True, null=True)
    qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
    description = models.TextField(blank=True, null=True)

    address = AddressField(max_length=100, null=True, blank=True)
    geolocation = GeoLocationField(blank=True, null=True)
    logo = models.ImageField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')

    phone_number = PhoneNumberField(blank=True, null=True)
    fax_number = PhoneNumberField(blank=True, null=True)

    lineId = models.CharField(max_length=100, blank=True, null=True)
    email = models.EmailField(max_length=200, blank=True, null=True)


    '''
    photos = ArrayField(
        models.FileField(upload_to='uploads/%Y/%m/%d/'),
        size=8,blank=True,null=True)
    '''

    def __str__(self):
        return f"{self.name}"

    def save(self, *args, **kwargs):
        self.qrCode.name = self.genCode()
        super(Store, self).save(*args, **kwargs)

    @property
    def qrImage(self):
        if self.qrCode:
             return format_html('<img src="{}" width="100%">', self.qrCode.url)
        else:
            return "-"

    def genCode(self):
        img = qrcode.make(f"{self.name}#{self.id}")
        rid = uuid.uuid4().hex
        path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
        rpath = f"qr/{rid}.png"
        img.save(path)
        return rpath

class Table(GeneralField, models.Model):
    store = models.ForeignKey('Store', on_delete=models.CASCADE)
    code = models.CharField(max_length=100, default="N\A")
    nSeats = models.IntegerField(default=1)
    occupy = models.BooleanField(default=False)
    qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')

    def __str__(self):
        return f"{self.code}"

    def save(self, *args, **kwargs):
        self.qrCode.name = self.genCode()
        super(Table, self).save(*args, **kwargs)

    @property
    def qrImage(self):
        if self.qrCode:
             return format_html('<img src="{}" width="100%">', self.qrCode.url)
        else:
            return "-"

    def genCode(self):
        img = qrcode.make(f"{self.store.name}#{self.code}")
        rid = uuid.uuid4().hex
        path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
        rpath = f"qr/{rid}.png"
        img.save(path)
        return rpath

class BookingTable(GeneralField, models.Model):
    table = models.ForeignKey(Table, on_delete=models.CASCADE)
    onDate = models.DateField(null=True)
    onTime = models.TimeField(null=True)
    note = models.TextField(blank=True, null=True)
    store = models.ForeignKey('Store', on_delete=models.CASCADE, null=True)
    qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')

    def __str__(self):
        return f"{self.table}@{self.onDate}({self.note})"

    def save(self, *args, **kwargs):
        self.qrCode.name = self.genCode()
        super(BookingTable, self).save(*args, **kwargs)

    @property
    def qrImage(self):
        if self.qrCode:
             return format_html('<img src="{}" width="100%">', self.qrCode.url)
        else:
            return "-"

    def genCode(self):
        img = qrcode.make(f"{self.store.name}#{self.table.code}#{self.onDate}@{self.onTime}")
        rid = uuid.uuid4().hex
        path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
        rpath = f"qr/{rid}.png"
        img.save(path)
        return rpath

class Order(GeneralField, models.Model):
    PURCHASE = 'purchase'
    table = models.ForeignKey(Table, null=True,  on_delete=models.SET_NULL)
    note = models.TextField(blank=True, null=True)
    store = models.ForeignKey('Store', on_delete=models.SET_NULL, default=None, null=True)
    #items = models.ManyToManyField(MenuItem)
    qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')

    def save(self, *args, **kwargs):
        self.qrCode.name = self.genCode()
        super(Order, self).save(*args, **kwargs)

    @property
    def qrImage(self):
        if self.qrCode:
             return format_html('<img src="{}" width="100%">', self.qrCode.url)
        else:
            return "-"

    def genCode(self):
        img = qrcode.make(f"{self.store.name}#{self.table.code}#{self.id}")
        rid = uuid.uuid4().hex
        path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
        rpath = f"qr/{rid}.png"
        img.save(path)
        return rpath

class OrderItem(GeneralField, models.Model):
    item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
    qty = models.IntegerField(default=1)
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    note = models.TextField(blank=True, null=True)
    store = models.ForeignKey('Store', on_delete=models.SET_NULL, default=None, null=True)

    @property
    def store_items(self):
        return MenuItem.objects.filter(store = order.store)



class StoreFile(GeneralField, models.Model):
    store = models.ForeignKey('Store', on_delete=models.CASCADE)
    storeFile = models.FileField(upload_to='uploads/%Y/%m/%d/')
    tags = TaggableManager(blank=True)

class MenuFile(GeneralField, models.Model):
    menuItem = models.ForeignKey('MenuItem', on_delete=models.CASCADE, null=True)
    menuFile = models.FileField(upload_to='uploads/%Y/%m/%d/')
    tags = TaggableManager(blank=True)






class Setting(GeneralField, models.Model):
    store = models.OneToOneField(Store, on_delete=models.CASCADE, primary_key=True)
    data = HStoreField(blank=True, null=True)
    note = models.CharField(max_length=200, blank=True, null=True)


class UIMenu(GeneralField,MPTTModel,  models.Model):
    name = models.CharField(max_length=200)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
    group = models.CharField(choices=MENU_GROUP_CHOICES, max_length=200, default='primary')
    url = models.CharField(max_length=200)
    icon = models.CharField(max_length=100, blank=True, null=True, default='file')
    store = models.ForeignKey('Store', on_delete=models.CASCADE, default=None, null=True)
    nOrder = models.IntegerField(default=1)

    class MPTTMeta:
        order_insertion_by = ['-nOrder']


    def __str__(self):
        return f"{self.name}"


class PostCategory(MPTTModel, models.Model):
    name = models.CharField(max_length=200)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')

    class MPTTMeta:
        order_insertion_by = ['name']


    def __str__(self):
        return f"{self.name}"


class Post(GeneralField, models.Model):
    title = models.CharField(max_length=200)
    content = RichTextField(blank=True)
    description = models.TextField(blank=True, null=True)
    store = models.ForeignKey('Store', on_delete=models.CASCADE, default=None, null=True)
    category = TreeManyToManyField(PostCategory, blank=True, null=True)
    featureImage = models.ImageField(upload_to='uploads/%Y/%m/%d/', blank=True, null=True)
    tags = TaggableManager(blank=True)
    relateMenus = models.ManyToManyField('MenuItem', blank=True, null=True)
    #photos = ArrayField(models.ImageField(upload_to='uploads/%Y/%m/%d/'), blank=True, null=True)

    @property
    def cats(self):
        return ",".join([ c.name for c in self.category.all()])

    def __str__(self):
        return f"{self.title}"



class PostFile(GeneralField, models.Model):
    post = models.ForeignKey('Post', on_delete=models.CASCADE)
    file = models.FileField(upload_to='uploads/%Y/%m/%d/')
    tags = TaggableManager(blank=True)


class Customer(GeneralField, models.Model):
    fullName = models.CharField(max_length=200)
    email = models.EmailField(blank=True, null=True)
    lineId = models.CharField(max_length=100, blank=True, null=True)
    gender = models.CharField(choices=GENDER_CHOICES, default='na', max_length=40)
    store = models.ForeignKey('Store', on_delete=models.CASCADE, default=None, null=True)
    qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')

    def save(self, *args, **kwargs):
        self.qrCode.name = self.genCode()
        super(Customer, self).save(*args, **kwargs)

    @property
    def qrImage(self):
        if self.qrCode:
             return format_html('<img src="{}" width="100%">', self.qrCode.url)
        else:
            return "-"

    def genCode(self):
        img = qrcode.make(f"{self.fullName}#{self.email}#{self.lineId}#{self.store.name}")
        rid = uuid.uuid4().hex
        path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
        rpath = f"qr/{rid}.png"
        img.save(path)
        return rpath


class Message(GeneralField, MPTTModel, models.Model):
    subject = models.CharField(max_length=255)
    email = models.EmailField()
    lineId = models.CharField(max_length=200, blank=True, null=True)
    body = models.TextField()
    reply = models.TextField(blank=True, null=True)
    store = models.ForeignKey("Store", on_delete=models.CASCADE)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
    tel = PhoneNumberField(blank=True, null=True)
    messageFile = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')

    def __str__(self):
        return f"{self.subject} {self.created_at}"

class Code(GeneralField, models.Model):
    store = models.OneToOneField('Store', on_delete=models.CASCADE, default=None, null=True)
    jsCode = models.TextField(blank=True)
    cssCode = models.TextField(blank=True)
    pluginCode = models.TextField(blank=True)
    # body_default = models.TextField()
    # body_editorjs = EditorJsJSONField(
        # plugins=[
            # "@editorjs/image",
            # "@editorjs/header",
            # "editorjs-github-gist-plugin",
            # "@editorjs/code@2.6.0",  # version allowed :)
            # "@editorjs/list@latest",
            # "@editorjs/inline-code",
            # "@editorjs/table",
            # '@editorjs/raw',
            # '@editorjs/embed',
        # ],

    # )  # Django >= 3.1
    # body_editorjs_text = EditorJsTextField()

    # image = FileBrowseField("Image", max_length=200, directory="images/", extensions=[".jpg"], blank=True)
    # document = FileBrowseField("PDF", max_length=200, directory="documents/", extensions=[".pdf",".doc"], blank=True)
    # code = models.TextField(blank=True)




