from datetime import date, timedelta
from urllib.parse import urlparse

from django.contrib.auth import get_user_model
from django.db.models import Q
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.validators import UniqueValidator

from verify_trusted.companies.api.serializers import (
    CompanySerializer,
    SubscriptionSerializer,
)
from verify_trusted.companies.history_types import HistoryType
from verify_trusted.companies.models import Company, Subscription
from verify_trusted.utils.validators import (
    IncludeDigitValidator,
    IncludeLowercaseValidator,
    IncludeUppercaseValidator,
)
from verify_trusted.widgets.models import Widget

User = get_user_model()


class UserCompanyRegistrationSerializer(serializers.ModelSerializer):
    id = serializers.HiddenField(default=None)
    url = serializers.HiddenField(default=None)

    def create(self, validated_data):
        if 'id' in validated_data:
            old_widget = Widget.objects.filter(company_id=validated_data['id']).first()
            if old_widget is None:
                widget_data = {
                    "company_id": validated_data['id'],
                    "layout_id": 16,
                    "layout_type": "Slider",
                    "more_style": {
                        "backgroundColor": "#FFFFFF",
                        "borderColor": "#DBDFEA",
                        "dateFontSize": 12,
                        "nameColor": "#3D424D",
                        "nameFontSize": 15,
                        "reviewColor": "#3D424D",
                        "reviewFontSize": 14,
                    },
                    "number_of_review": 0,
                    "order_by": "TOP_RATING",
                    "set_id": "light-background",
                }
                widget = Widget.objects.create(**widget_data)
                widget.save()
        return super().create(validated_data)

    def validate(self, attrs):
        url = attrs['url_display']
        try:
            o = urlparse(url)
        except ValueError:
            raise ValidationError({'url': 'MSG016'})
        query = Q(url=url) | Q(url=o.hostname)
        company = Company.objects.filter(query).first()
        if company:
            if company.user is not None:
                raise ValidationError({'url': 'MSG015'})
            attrs['id'] = company.id
            attrs.pop('url_display', None)
        else:
            attrs['url'] = o.hostname if o.hostname is not None else url
        return super().validate(attrs)

    class Meta:
        model = Company
        fields = ['id', 'name', 'url_display', 'url', 'country_code', 'address', 'web_alias']
        extra_kwargs = {
            'url_display': {
                'validators': [],
                'error_messages': {
                    'invalid': 'MSG016',
                    'blank': 'MSG013',
                },
            }
        }


class UserRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(
        write_only=True,
        min_length=6,
        validators=[
            IncludeDigitValidator(message='MSG009'),
            IncludeLowercaseValidator(message='MSG010'),
            IncludeUppercaseValidator(message='MSG011'),
        ],
        error_messages={
            'blank': 'MSG007',
            'min_length': 'MSG008',
        },
    )
    company = UserCompanyRegistrationSerializer(write_only=True, many=True)
    companies = CompanySerializer(read_only=True, many=True)

    class Meta:
        model = User
        fields = ['name', 'email', 'password', 'ip', 'company', 'companies']
        extra_kwargs = {
            'name': {
                'allow_blank': False,
                'required': True,
                'min_length': 6,
                'max_length': 32,
                'error_messages': {
                    'blank': 'MSG001',
                    'max_length': 'MSG003',
                    'min_length': 'MSG003',
                },
            },
            'email': {
                'allow_blank': False,
                'required': True,
                'validators': [
                    UniqueValidator(queryset=User.objects.all(), message='MSG017'),
                ],
                'error_messages': {
                    'invalid': 'MSG006',
                    'blank': 'MSG005',
                },
            },
        }

    def create(self, validated_data):
        companies = validated_data.pop('company')
        company = companies[0]
        validated_data['username'] = validated_data[
            'email'
        ]  # Using `email` as `username`
        validated_data['is_active'] = True
        user = User.objects.create_user(**validated_data)
        if 'id' in company and company['id'] is not None:
            company = self.user_claim_company(user, company)
        else:
            company = self.user_create_company(user, company)
        subscription = Subscription.objects.filter(company_id=company.id).first()
        if subscription is None:
            subscription_serializer = SubscriptionSerializer(
                data={
                    'company': company.id,
                    'due_date': date.today() + timedelta(days=7),
                }
            )
            subscription_serializer.is_valid(raise_exception=True)
            subscription_serializer.create(subscription_serializer.validated_data)
        return user

    def user_create_company(self, user: User, company: Company):  # noqa
        company['user'] = user.id  # User claim this company
        company['is_verified'] = True
        company['ssl_status'] = True
        company['one_year'] = True
        company_serializer = CompanySerializer(data=company)
        company_serializer.is_valid(raise_exception=True)
        company = company_serializer.create(company_serializer.validated_data)
        return company

    def user_claim_company(self, user: User, company: Company):  # noqa
        country_code = company['country_code'] if 'country_code' in company else ''
        address = company['address'] if 'address' in company else ''
        company = Company.objects.get(id=company['id'])
        company.user = user
        company.is_verified = True
        company.ssl_status = True
        company.one_year = True
        company.country_code = (
            country_code if len(country_code) > 0 else company.country_code
        )
        company.address = address if len(address) > 0 else company.address
        # company.currency_symbol = (
        #     'GBP' if company.country_code == 'GB' else company.currency_symbol
        # )
        # company.currency_symbol = 'GBP' if company.country_code == 'GB' else 'USD'
        company.currency_symbol = 'USD'
        # https://django-simple-history.readthedocs.io/en/latest/historical_model.html#change-reason
        company._change_reason = HistoryType.CLAIMED
        company.save()
        old_widget = Widget.objects.filter(company_id=company.id).first()
        if old_widget is None:
            widget_data = {
                "company": company,
                "layout_id": 16,
                "layout_type": "Slider",
                "more_style": {
                    "backgroundColor": "#FFFFFF",
                    "borderColor": "#DBDFEA",
                    "dateFontSize": 12,
                    "nameColor": "#3D424D",
                    "nameFontSize": 15,
                    "reviewColor": "#3D424D",
                    "reviewFontSize": 14,
                },
                "number_of_review": 0,
                "order_by": "TOP_RATING",
                "set_id": "light-background",
            }
            widget = Widget.objects.create(**widget_data)
            widget.save()
        # self.create_widget(company)
        return company

    def create_widget(self, company: Company):
        if company is not None:
            old_widget = Widget.objects.filter(company_id=company.id).first()
            if old_widget is None:
                widget_data = {
                    "company": company,
                    "layout_id": 16,
                    "layout_type": "Slider",
                    "more_style": {
                        "backgroundColor": "#FFFFFF",
                        "borderColor": "#DBDFEA",
                        "dateFontSize": 12,
                        "nameColor": "#3D424D",
                        "nameFontSize": 15,
                        "reviewColor": "#3D424D",
                        "reviewFontSize": 14,
                    },
                    "number_of_review": 0,
                    "order_by": "TOP_RATING",
                    "set_id": "light-background",
                }
                widget = Widget.objects.create(**widget_data)
                widget.save()
