import os
import uuid
from binascii import hexlify

from django.db import models
from django.utils.translation import gettext_lazy as _
from django_countries.fields import CountryField


def _createId():
    return hexlify(os.urandom(6)).decode()


def _generate_validation_code():
    return uuid.uuid4().hex[:16]


class Industry(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=128)

    class Meta:
        verbose_name_plural = "    Industries"

    def __str__(self):
        return self.name


class Business(models.Model):
    class REWARDS_PRICE_TYPE(models.IntegerChoices):
        OFF = 0, _('Off')
        POINT = 1, _('Point')
        STAMP = 2, _('Stamp')

    id = models.CharField(max_length=16, primary_key=True, default=_createId)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    manager_full_name = models.CharField(max_length=128)
    country = CountryField(default="AE")
    manager_mobile = models.CharField(max_length=30, unique=True)
    name = models.CharField(max_length=128)
    industry = models.ForeignKey(Industry, on_delete=models.CASCADE, null=True, blank=True)
    email = models.EmailField(null=True, blank=True)
    phone = models.CharField(max_length=30, null=True, blank=True)
    address = models.TextField(null=True, blank=True)
    web_site = models.URLField(max_length=256, null=True, blank=True)
    instagram = models.CharField(max_length=64, null=True, blank=True)
    icon = models.ImageField(upload_to='media', null=True, blank=True)
    google_link = models.URLField(max_length=1024, null=True, blank=True)
    address_link = models.URLField(max_length=1024, null=True, blank=True)
    manager_email = models.EmailField(null=True, blank=True)
    purchase_link = models.URLField(max_length=1024, null=True, blank=True)
    loyalty_model = models.PositiveSmallIntegerField(choices=REWARDS_PRICE_TYPE.choices, default=REWARDS_PRICE_TYPE.OFF)
    point_amount_value = models.PositiveIntegerField(
        default=0, help_text="Note: it's the value of each point if you use point system for business")
    approval_code = models.CharField(max_length=20, default=_generate_validation_code)
    google_place_id = models.CharField(max_length=256, null=True, blank=True)

    class Meta:
        verbose_name_plural = "  Businesses"

    def __str__(self):
        return self.name

    @property
    def loyalty_model_label(self):
        choices = [c[1] for c in self.REWARDS_PRICE_TYPE.choices if c[0] == self.loyalty_model]
        return choices[0] if len(choices) else None


class Product(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=128)
    industry = models.ForeignKey(Industry, on_delete=models.CASCADE, null=True, blank=True)

    class Meta:
        verbose_name_plural = "   Products"

    def __str__(self):
        return self.name


class Customer(models.Model):
    GENDER_CHOICES = (
        ('M', 'male'),
        ('F', 'female'),
        ('O', 'other'),
    )
    ACQUISITION_CHOICES = (
        (1, "Google search"),
        (2, "Social media"),
        (3, "Walk-in"),
        (4, "Friends"),
        (5, "Online advertisements"),
        (6, "Offline advertisements"),
    )

    id = models.CharField(max_length=16, primary_key=True, default=_createId)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    country_code = models.CharField(max_length=12)
    mobile = models.CharField(max_length=30)
    full_name = models.CharField(max_length=128)
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES, null=True, blank=True)
    dob = models.DateField(null=True, blank=True)
    email = models.EmailField(null=True, blank=True)
    business = models.ForeignKey(Business, on_delete=models.CASCADE)
    validation_code = models.CharField(max_length=20, default=_generate_validation_code, unique=True, null=True)
    acquisition_channel = models.PositiveSmallIntegerField(choices=ACQUISITION_CHOICES, null=True, blank=True)
    loyalty_weight = models.PositiveIntegerField(default=0)
    phone_verification = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = " Customers"

    def __str__(self):
        return self.full_name


class SaleRecord(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    rate = models.PositiveSmallIntegerField(null=True)
    description = models.TextField(null=True, blank=True)
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
    business = models.ForeignKey(Business, on_delete=models.CASCADE)
    products = models.ManyToManyField(Product, blank=True)
    amount = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=15)
    delivery_date = models.DateTimeField(null=True, blank=True)
    is_verified = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = " Sale Records"  # 2 spaces


class Reward(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    business = models.ForeignKey(Business, on_delete=models.CASCADE)
    name = models.CharField(max_length=256, blank=True, null=True)
    cover_photo = models.ImageField(upload_to='media', null=True, blank=True)
    description = models.TextField(blank=True, null=True)
    loyalty_weight = models.PositiveIntegerField()
    start_date = models.DateField(null=True, blank=True)
    end_date = models.DateField(null=True, blank=True)
    capacity = models.PositiveIntegerField(default=0, help_text='Note: zero in this field means infinity')
    reusable = models.PositiveIntegerField(
        default=1, help_text='Note: how many times one customer can redeem this reward')
    is_enabled = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = "Rewards"  # 2 spaces

    def __str__(self):
        return self.name


class Redeem(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    id = models.CharField(max_length=16, primary_key=True, default=_createId)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    reward = models.ForeignKey(Reward, on_delete=models.CASCADE)

    class Meta:
        verbose_name_plural = "Redeems"
