"""
Models module for cards app.
"""

import os
import sys
import base64
from io import BytesIO

from django.db import models
from django.urls import reverse_lazy
from django.contrib.sites.models import Site
from django.core.files.uploadedfile import InMemoryUploadedFile

import qrcode
from django_extensions.db.models import TimeStampedModel


def image_as_base64(image_file, image_format="png"):
    """
    Return the base64 representation of an image.
    """
    if not os.path.isfile(image_file):
        return None

    encoded_string = ""
    with open(image_file, "rb") as img_f:
        encoded_string = base64.b64encode(img_f.read())

    return f"data:image/{image_format};base64,{encoded_string.decode('utf-8')}"


class Template(TimeStampedModel, models.Model):
    """
    Card template model.
    """

    ORIENTACION = ((1, "Horizontal"), (2, "Vertical"))
    example_image = models.ImageField(upload_to="media/cards/")
    blank_image = models.ImageField(upload_to="media/cards/")
    orientation = models.SmallIntegerField(choices=ORIENTACION)

    @property
    def blank_image_as_base64(self):
        """
        Return base64 representation of a blank card.
        """
        return image_as_base64(self.blank_image.path)


class Card(TimeStampedModel, models.Model):
    """
    User card model.
    """

    name = models.CharField(max_length=250, blank=True, null=True)
    position = models.CharField(max_length=250, blank=True, null=True)
    url = models.URLField(blank=True, null=True)
    email = models.EmailField(blank=True, null=True)
    address = models.TextField(blank=True, null=True)
    phone = models.CharField(max_length=20, blank=True, null=True)
    mobile = models.CharField(max_length=20, blank=True, null=True)
    extra = models.TextField(blank=True, null=True)
    facebook = models.CharField(max_length=250, blank=True, null=True)
    twiter = models.CharField(max_length=250, blank=True, null=True)
    linkedin = models.CharField(max_length=250, blank=True, null=True)
    image = models.TextField()
    qrcode = models.ImageField(upload_to="media/qrcode", blank=True, null=True)
    default = models.BooleanField(default=True)
    template = models.ForeignKey(
        "cards.Template",
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        related_name="cards",
    )
    orientation = models.IntegerField(blank=True, null=True)
    user = models.ForeignKey(
        "users.User",
        on_delete=models.CASCADE,
        related_name="cards",
    )
    followers = models.ManyToManyField(
        "users.User",
        related_name="favorite_cards",
    )

    def generate_qr_code(self):
        qr_code = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=4,
        )
        current_site = Site.objects.get_current()
        card_url = reverse_lazy("cards:card-detail", kwargs={"pk": self.id})
        qr_code.add_data(
            f"{current_site.domain}{card_url}",
        )
        qr_code.make(fit=True)
        img = qr_code.make_image()
        buffer = BytesIO()
        img.save(buffer)
        filename = f"events-{self.id}.png"
        filebuffer = InMemoryUploadedFile(
            buffer,
            None,
            filename,
            "image/png",
            sys.getsizeof(buffer),
            None,
        )
        self.qrcode.save(filename, filebuffer, False)

    def save(self, *args, **kwargs):  # pylint: disable=W0222
        """
        Save model.
        """
        super().save(*args, **kwargs)

        if self.id:
            self.generate_qr_code()


class CardMetadata(models.Model):  # pylint: disable=R0902
    """
    Card metadata model.
    """

    card = models.OneToOneField(
        "cards.Card",
        on_delete=models.CASCADE,
    )
    nombre_negocio = models.CharField(max_length=250, blank=True, null=True)
    productos_servicios = models.TextField(blank=True, null=True)
    descripcion_productos_servicios = models.TextField(blank=True, null=True)
    descripcion_detallada_productos_servicios = models.TextField(
        blank=True,
        null=True,
    )
    latitude = models.CharField(max_length=100, blank=True, null=True)
    longitude = models.CharField(max_length=100, blank=True, null=True)
    video = models.CharField(max_length=150, blank=True, null=True)
    pdf = models.TextField(blank=True, null=True)


class Rating(TimeStampedModel, models.Model):
    """
    Card rating model.
    """

    card = models.ForeignKey(
        "cards.Card",
        on_delete=models.CASCADE,
        related_name="ratings",
    )
    value = models.IntegerField(blank=True, null=True)
    comment = models.TextField()
    user = models.ForeignKey(
        "users.User",
        on_delete=models.CASCADE,
        null=True,
    )
