
from django.db import models
from django.urls import reverse_lazy
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _

from django_prose_editor.fields import ProseEditorField
from mptt.forms import TreeNodeChoiceField
from mptt.models import MPTTModel, TreeForeignKey


class Category(MPTTModel):

    parent = TreeForeignKey(
        'self',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='children',
        verbose_name=_('Parent category'))

    name = models.CharField(
        _('Category name'),
        max_length=255)

    title = models.CharField(
        _('Category title'),
        max_length=255,
        blank=True)

    logo = models.ImageField(
        _('Logo'),
        upload_to='categories',
        blank=True,
        null=True,
        max_length=255)

    code = models.CharField(
        _('Code'),
        max_length=255,
        blank=True)

    icon = models.CharField(
        _('Icon'),
        max_length=255,
        blank=True)

    description = ProseEditorField(
        _('Description'),
        blank=True,
        extensions={
            'Bold': True,
            'Italic': True,
            'BulletList': True,
            'OrderedList': True,
            'ListItem': True,
            'Link': True,
            'Heading': {'levels': [1, 2, 3]},
        },
        sanitize=True,
    )

    order = models.PositiveIntegerField(default=0)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse_lazy('products:list', args=[self.slug, self.id])

    @property
    def slug(self):
        return slugify(self.name or 'category', allow_unicode=False).replace('-', '_')

    @property
    def full_name(self):
        return ' > '.join([
            c.name for c in self.get_ancestors(include_self=True)
        ])

    class MPTTMeta:
        order_insertion_by = ['order', 'name']

    class Meta:
        ordering = ['order']
        verbose_name = _('Category')
        verbose_name_plural = _('Categories')


class CategoryField(models.ForeignKey):

    def __init__(
            self,
            to='categories.Category',
            verbose_name=_('Category'),
            on_delete=models.CASCADE,
            db_index=True,
            *args, **kwargs):

        super(CategoryField, self).__init__(
            to,
            verbose_name=verbose_name,
            on_delete=on_delete,
            db_index=db_index,
            *args, **kwargs)

    def formfield(self, **kwargs):
        kwargs['form_class'] = TreeNodeChoiceField
        return super().formfield(**kwargs)
