from django_rest_passwordreset.signals import reset_password_token_created
from location_field.models.plain import PlainLocationField
from django.template.defaultfilters import truncatechars
from django.core.validators import MinLengthValidator
from django.template.loader import render_to_string
from django.contrib.auth.models import AbstractUser
from extensions.utils import jalali_converter
from django.core.mail import EmailMessage
from django.dispatch import receiver
from django.db import models


class User(AbstractUser):
    GENDER_CHOICES = (
        ('male', 'آقا'),
        ('female', 'خانم')
    )
    name = models.CharField(max_length=256, null=True, blank=True, verbose_name="نام")
    email = models.CharField(max_length=254, unique=True, blank=True, null=True, verbose_name="پست الکترونیک")
    username = models.CharField(max_length=50, unique=True, blank=True, null=True, verbose_name="نام کاربری")
    first_name = models.CharField(max_length=150, null=True, blank=True, verbose_name="نام")
    last_name = models.CharField(max_length=150, null=True, blank=True, verbose_name="نام خانوادگی")
    password = models.CharField(max_length=256, unique=False, null=True, verbose_name="رمز عبور")
    mobile = models.CharField(max_length=11, validators=[MinLengthValidator(11)], unique=False,
                              verbose_name="شماره تلفن همراه")
    nationality_code = models.CharField(max_length=10, validators=[MinLengthValidator(10)], unique=True, null=True,
                                        verbose_name="کد ملی")
    gender = models.CharField(max_length=20, choices=GENDER_CHOICES, null=True, blank=True, verbose_name="جنسیت")
    validated = models.BooleanField(default=False, verbose_name="صحت شماره موبایل")
    USERNAME_FIELD = 'username'

    class Meta:
        verbose_name = "کاربر"
        verbose_name_plural = "کاربران"

    def get_user_type(self):
        seller = User.objects.select_related().filter(seller=self.pk)
        return 'seller' if seller else 'customer'


class Province(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=256, verbose_name="نام استان")

    class Meta:
        verbose_name = "استان"
        verbose_name_plural = "استان ها"

    def __str__(self):
        return self.name


class City(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=256, verbose_name="نام شهر")
    province = models.ForeignKey(Province, on_delete=models.CASCADE, default=0, verbose_name="استان")

    class Meta:
        verbose_name = "شهر"
        verbose_name_plural = "شهرها"

    def __str__(self):
        return self.name


class Address(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=256, null=True, blank=True, verbose_name="نام آدرس")
    province = models.ForeignKey(Province, on_delete=models.CASCADE, null=True, verbose_name="استان")
    city = models.ForeignKey(City, on_delete=models.CASCADE, null=True, verbose_name="شهر")
    province_city = models.CharField(max_length=256, default='', blank=True)
    address = models.TextField(null=True, verbose_name="آدرس")
    zipcode = models.CharField(max_length=10, validators=[MinLengthValidator(10)], null=True,
                               verbose_name="کد پستی")
    location = PlainLocationField(based_fields=['province_city'], default='35.6892523,51.3896004',
                                  verbose_name="لوکیشن")
    user = models.ForeignKey(User, related_name='address_info', on_delete=models.CASCADE, null=True,
                             verbose_name="کاربر")

    class Meta:
        verbose_name = "آدرس"
        verbose_name_plural = "آدرس ها"

    def __str__(self):
        return self.full_address() if self.province and self.city and self.address else ''

    def full_address(self):
        return truncatechars(self.province.name + ' - ' + self.city.name + ' - ' + self.address, 100)

    full_address.short_description = "آدرس"


class IPAddress(models.Model):
    ip_address = models.GenericIPAddressField(verbose_name="آدرس ip")


class Comment(models.Model):
    id = models.AutoField(primary_key=True)
    comment = models.TextField(verbose_name="متن نظر")
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, verbose_name="کاربر")

    class Meta:
        verbose_name = "نظر"
        verbose_name_plural = "نظرات"

    def __str__(self):
        return truncatechars(self.comment, 100)


class Message(models.Model):
    SEND_TYPE_CHOICES = (
        ('users', 'همه کاربران'),
        ('sellers', 'همه فروشندگان'),
        ('customers', 'همه مشتریان'),
        ('specified', 'یک یا چند کاربر خاص')
    )
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=255, null=True, blank=True, verbose_name="عنوان پیام")
    message = models.TextField(verbose_name="متن پیام")
    send_type = models.CharField(max_length=20, choices=SEND_TYPE_CHOICES, blank=True, verbose_name="نوع ارسال")
    send_to = models.ManyToManyField(User, blank=True, null=True, verbose_name="کاربران")
    created = models.DateTimeField(auto_now_add=True, null=True, verbose_name="زمان ثبت")

    class Meta:
        verbose_name = "پیام"
        verbose_name_plural = "پیام ها"

    def __str__(self):
        return self.title

    def jalali_created(self):
        return jalali_converter(self.created)

    jalali_created.short_description = "زمان ثبت"


class Verification(models.Model):
    id = models.AutoField(primary_key=True)
    code = models.CharField(max_length=6, null=True, blank=True)
    expired_time = models.CharField(max_length=40)
    mobile = models.CharField(max_length=11, validators=[MinLengthValidator(11)], unique=False)


@receiver(reset_password_token_created)
def password_reset_token_created(sender, instance, reset_password_token, *args, **kwargs):
    html = 'user/reset_password.html'
    context = {
        'link': 'tookapoot.ir/user/password-reset/?token={}'.format(reset_password_token.key)
    }
    html_message = render_to_string(html, {'context': context})
    msg = EmailMessage("Password Reset for tookapoot.ir", html_message, "noreply@tookapoot.ir",
                       to=[reset_password_token.user.email])
    msg.content_subtype = 'html'
    msg.send()
