from django.db import models
from django.forms.models import model_to_dict
from rest_framework import serializers
from tag import models as tag_models
from django.conf import settings
from product.models import ProductType, ProductSubType, Product
from location.models import WineRegion
from django.utils.text import slugify


class SecondDbManager(models.Manager):
    def get_queryset(self):
        qs = super().get_queryset()

        # if `use_db` is set on model use that for choosing the DB
        if hasattr(self.model, 'use_db'):
            qs = qs.using(self.model.use_db)

        return qs


class MigrateMixin(models.Model):
    """Mixin to data transfer from legacy database"""
    use_db = 'legacy'
    objects = SecondDbManager()

    def _parse_instance_fields(self, fields):
        model_dict = model_to_dict(self, fields)
        print(getattr(self, "using", "Using not found"))

    class Meta:
        abstract = True


class TransferSerializerMixin(serializers.ModelSerializer):
    """Mixin for transferring legacy db models."""

    def create(self, validated_data):
        qs = self.Meta.model.objects.filter(**validated_data)
        if not qs.exists():
            return super().create(validated_data)

    @property
    def tag_category(self):
        if self.CATEGORY_LABEL and self.CATEGORY_INDEX_NAME:
            tag_category, _ = tag_models.TagCategory.objects.get_or_create(
                index_name=self.CATEGORY_INDEX_NAME,
                defaults={
                    'label': {settings.FALLBACK_LOCALE: self.CATEGORY_LABEL},
                    'value_type': tag_models.TagCategory.STRING,
                    'index_name': self.CATEGORY_INDEX_NAME,
                    'public': True
                })
            return tag_category

    def get_vintage_year(self, vintage):
        earliest_year = self.Meta.model.EARLIEST_VINTAGE_YEAR
        latest_year = self.Meta.model.LATEST_VINTAGE_YEAR
        if vintage:
            if vintage.isdigit():
                if len(vintage) == 2:
                    if vintage == '16':
                        return 2016
                elif len(vintage) == 4:
                    if earliest_year < int(vintage) < latest_year:
                        return int(vintage)
                    elif vintage == '1584':
                        return 1984
                    elif vintage == '1017':
                        return 2017
                elif len(vintage) == 5:
                    if vintage == '20115':
                        return 2015
                    elif vintage == '20174':
                        return 2017
            elif vintage.endswith('er'):
                return self.get_vintage_year(vintage[:-2])

    def get_product_type(self, index_name):
        if index_name:
            qs = ProductType.objects.filter(
                index_name__icontains=index_name)
            if qs.exists():
                return qs.first()

    def get_product_sub_type(self, product_type, product_sub_type):
        if not isinstance(product_type, ProductType):
            product_type = self.get_product_type(product_type)
        if product_type and product_sub_type:
            qs = ProductSubType.objects.filter(
                product_type=product_type,
                index_name__icontains=product_sub_type)
            if qs.exists():
                return qs.first()

    def get_slug(self, name, old_id):
        return slugify(f'{name}-{old_id}')

    def get_tag(self, tag, category_index_name: str):
        tag = tag.name if hasattr(tag, 'name') else tag
        if tag:
            qs = tag_models.Tag.objects.filter(
                value=slugify(tag),
                category__index_name=category_index_name)
            if qs.exists():
                return qs.first()

    def get_product(self, old_id):
        if old_id:
            product_qs = Product.objects.filter(old_id=old_id)
            if product_qs.exists():
                return product_qs.first()

    def get_wine_region(self, parent_id):
        qs = WineRegion.objects.filter(old_id=parent_id)
        if qs.exists():
            return qs.first()
