from rest_framework import serializers
from rest_framework.validators import UniqueValidator
#from rest_framework.validators import UniqueTogetherValidator
from decimal import Decimal
import bleach
from .models import *
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# Disable SSL certificate verification warnings
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)



class OfficeSerializer(serializers.ModelSerializer):
    office_id = serializers.IntegerField(read_only = True, min_value=1, validators=[UniqueValidator(queryset=Offices.objects.all())])
    name = serializers.CharField(read_only = True, max_length=100)
    website = serializers.URLField(read_only = True, max_length=100, min_length=None, allow_blank=False)
    logo = serializers.SerializerMethodField()
    telephone = serializers.CharField(read_only = True, max_length=50)
    country = serializers.CharField(read_only = True, max_length=100)
    country_abbreviation = serializers.CharField(read_only = True, max_length=10)
    state = serializers.CharField(read_only = True, max_length=100)
    state_abbreviation = serializers.CharField(read_only = True, max_length=10)
    city = serializers.CharField(read_only = True, max_length=100)
    zone = serializers.CharField(read_only = True, max_length=100)
    neighborhood = serializers.CharField(read_only = True, max_length=100)
    complement = serializers.CharField(read_only = True, max_length=255)
    address = serializers.CharField(read_only = True, max_length=255)
    street_number = serializers.CharField(read_only = True, max_length=255)
    postal_code = serializers.CharField(read_only = True, max_length=20)
    total_properties = serializers.IntegerField(read_only = True)
    

    def get_logo(self, instance):
        logo_instance = instance.logo
        image_formats = ("image/png", "image/jpeg", "image/jpg", "image/gif")
        
        try:
            response = requests.head(logo_instance, verify=False)
            if response.status_code == 200 and response.headers["content-type"] in image_formats:
                return logo_instance
        except Exception as e:
            pass  # Image doesn't exist or couldn't be accessed
        return None


    
    def validate(self, attrs):
        attrs['name'] = bleach.clean(attrs['name'])
        attrs['telephone'] = bleach.clean(attrs['telephone'])
        attrs['country'] = bleach.clean(attrs['country'])
        attrs['country_abbreviation'] = bleach.clean(attrs['country_abbreviation'])
        attrs['state'] = bleach.clean(attrs['state'])
        attrs['state_abbreviation'] = bleach.clean(attrs['state_abbreviation'])
        attrs['city'] = bleach.clean(attrs['city'])
        attrs['zone'] = bleach.clean(attrs['zone'])
        attrs['neighborhood'] = bleach.clean(attrs['neighborhood'])
        attrs['complement'] = bleach.clean(attrs['complement'])
        attrs['address'] = bleach.clean(attrs['address'])
        attrs['street_number'] = bleach.clean(attrs['street_number'])
        attrs['postal_code'] = bleach.clean(attrs['postal_code'])
        return super().validate(attrs)
    
    def validate_office_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Office ID must be equal or higher than 1!')
        return value
      
    class Meta:
        model = Offices
        fields = '__all__'


class AgentSerializer(serializers.ModelSerializer):
    
    agent_id = serializers.IntegerField(read_only = True, min_value=1, validators=[UniqueValidator(queryset=Agents.objects.all())])
    name = serializers.CharField(read_only = True, max_length=100)
    email = serializers.EmailField(max_length=100, allow_blank=False)
    #profile_picture = serializers.CharField(read_only = True, max_length=255)
    profile_picture = serializers.SerializerMethodField()
    total_properties = serializers.IntegerField(read_only = True)
    has_profile_picture = serializers.SerializerMethodField()
    office = OfficeSerializer(read_only=True)

    
    def get_profile_picture(self, instance):
        profile_picture_instance = instance.profile_picture
        image_formats = ("image/png", "image/jpeg", "image/jpg", "image/gif")
        
        try:
            response = requests.head(profile_picture_instance, verify=False)
            if response.status_code == 200 and response.headers["content-type"] in image_formats:
                return profile_picture_instance
        except Exception:
            pass # Image doesn't exist or couldn't be accessed
        return None
    
    def get_has_profile_picture(self, instance):
        return 1 if instance.profile_picture is not None else 0
        

    def validate(self, attrs):
        attrs['name'] = bleach.clean(attrs['name'])
        return super().validate(attrs)
    
    def validate_agent_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Agent ID must be equal or higher than 1!')
        return value
      
    class Meta:
        model = Agents
        fields = '__all__'
        ordering_fields = ['has_profile_picture']
        
        
class FeatureSerializer(serializers.ModelSerializer):
    
    feature_id = serializers.IntegerField(read_only = True, min_value=1, validators=[UniqueValidator(queryset=Features.objects.all())])
    feature_name_en = serializers.CharField(read_only = True, max_length=100)
    feature_name_pt = serializers.CharField(read_only = True, max_length=100)
    properties = serializers.SlugRelatedField(read_only=True, many=True, slug_field='property_id')

    def validate(self, attrs):
        attrs['feature_name_en'] = bleach.clean(attrs['feature_name_en'])
        attrs['feature_name_pt'] = bleach.clean(attrs['feature_name_pt'])
        return super().validate(attrs)
    
    def validate_feature_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Feature ID must be equal or higher than 1!')
        return value
    

      
    class Meta:
        model = Features
        fields = '__all__'
        
        
        
        
class UsageSerializer(serializers.ModelSerializer):
    
    usage_id = serializers.IntegerField(read_only = True, min_value=1, validators=[UniqueValidator(queryset=Usages.objects.all())])
    usage_name_en = serializers.CharField(read_only = True, max_length=100)
    usage_name_pt = serializers.CharField(read_only = True, max_length=100)

    def validate(self, attrs):
        attrs['usage_name_en'] = bleach.clean(attrs['usage_name_en'])
        attrs['usage_name_pt'] = bleach.clean(attrs['usage_name_pt'])
        return super().validate(attrs)
    
    def validate_feature_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Usage ID must be equal or higher than 1!')
        return value
      
    class Meta:
        model = Usages
        fields = '__all__'
        

class TypeSerializer(serializers.ModelSerializer):
    
    type_id = serializers.IntegerField(read_only = True, min_value=1, validators=[UniqueValidator(queryset=Types.objects.all())])
    type_name_en = serializers.CharField(read_only = True, max_length=100)
    type_name_pt = serializers.CharField(read_only = True, max_length=100)
    usage = UsageSerializer(read_only=True)

    def validate(self, attrs):
        attrs['type_name_en'] = bleach.clean(attrs['type_name_en'])
        attrs['type_name_pt'] = bleach.clean(attrs['type_name_pt'])
        return super().validate(attrs)
    
    def validate_type_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Type ID must be equal or higher than 1!')
        return value
      
    class Meta:
        model = Types
        fields = '__all__'



class LocationSerializer(serializers.ModelSerializer):
    
    property_location_id = serializers.IntegerField(read_only = True, min_value=1, 
                                                 validators=[UniqueValidator(queryset=Location.objects.all())])
    display_address = serializers.CharField(read_only = True, max_length=20)
    country = serializers.CharField(read_only = True, max_length=100)
    country_abbreviation = serializers.CharField(read_only = True, max_length=10)
    state = serializers.CharField(read_only = True, max_length=100)
    city = serializers.CharField(read_only = True, max_length=100)
    zone = serializers.CharField(read_only = True, max_length=100)
    neighborhood = serializers.CharField(read_only = True, max_length=100)
    complement = serializers.CharField(read_only = True, max_length=255)
    address = serializers.CharField(read_only = True, max_length=255)
    street_number = serializers.CharField(read_only = True, max_length=255)
    postal_code = serializers.CharField(read_only = True, max_length=20)
    lat = serializers.CharField(read_only = True, max_length=20)
    lng = serializers.CharField(read_only = True, max_length=20)
    

    def validate(self, attrs):
        attrs['display_address'] = bleach.clean(attrs['display_address'])
        attrs['country'] = bleach.clean(attrs['country'])
        attrs['country_abbreviation'] = bleach.clean(attrs['abbreviation'])
        attrs['state'] = bleach.clean(attrs['state'])
        attrs['city'] = bleach.clean(attrs['city'])
        attrs['zone'] = bleach.clean(attrs['zone'])
        attrs['neighborhood'] = bleach.clean(attrs['neighborhood'])
        attrs['complement'] = bleach.clean(attrs['complement'])
        attrs['address'] = bleach.clean(attrs['address'])
        attrs['street_number'] = bleach.clean(attrs['street_number'])
        attrs['postal_code'] = bleach.clean(attrs['postal_code'])
        return super().validate(attrs)
    
    def validate_property_location_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Property Location ID must be equal or higher than 1!')
        return value
      
    class Meta:
        model = Location
        fields = '__all__'


class PropertySerializer(serializers.ModelSerializer):
    
    property_id = serializers.IntegerField(read_only = True, min_value=1, validators=[UniqueValidator(queryset=Properties.objects.all())])
    listing_id = serializers.CharField(read_only = True, max_length=100)
    title = serializers.CharField(read_only = True, max_length=255)
    transaction_type = serializers.CharField(read_only = True, max_length=50)
    detail_view_url = serializers.URLField(read_only = True, max_length=100, min_length=None, allow_blank=False)
    description = serializers.CharField(read_only=True)
    list_price = serializers.DecimalField(read_only=True, max_digits=10, decimal_places=2)
    list_price_currency = serializers.CharField(read_only = True, max_length=5)  
    rental_price = serializers.DecimalField(read_only=True, max_digits=10, decimal_places=2)
    rental_price_currency = serializers.CharField(read_only = True, max_length=5)
    rental_price_period = serializers.CharField(read_only = True, max_length=50)
    property_administration_fee = serializers.DecimalField(read_only=True, max_digits=10, decimal_places=2)
    property_administration_fee_period = serializers.CharField(read_only = True, max_length=30)
    yearly_tax = serializers.DecimalField(read_only=True, max_digits=10, decimal_places=2)
    yearly_tax_currency = serializers.CharField(read_only = True, max_length=5)
    living_area = serializers.IntegerField(read_only = True)
    living_area_unit = serializers.CharField(read_only = True, max_length=30)
    year_built = serializers.IntegerField(read_only = True, min_value=4, max_value=4)
    bedrooms = serializers.IntegerField(read_only = True)
    bathrooms = serializers.IntegerField(read_only = True)
    garage = serializers.IntegerField(read_only = True)
    garage_type = serializers.CharField(read_only = True, max_length=30)
    unit_floor = serializers.IntegerField(read_only = True)
    unit_number = serializers.CharField(read_only = True, max_length=30)
    publish_date = serializers.DateTimeField(read_only=True, default=None)
    sync_date = serializers.DateTimeField(read_only=True, default=None)
    region_id = serializers.IntegerField(read_only = True)
    usage = UsageSerializer(read_only=True)
    type = TypeSerializer(read_only=True)
    office = OfficeSerializer(read_only=True)
    agent = AgentSerializer(read_only=True)
    location = LocationSerializer(read_only=True)  
   #features = serializers.SlugRelatedField(many=True, read_only=True, slug_field='feature_id')
    #features = FeatureSerializer(read_only=True, many=True)
    features = serializers.SerializerMethodField()
    #medias = serializers.SlugRelatedField(many=True, read_only=True, slug_field='url')
    medias = serializers.SerializerMethodField()
    
    
    def get_features(self, obj):
        # Get the related PropertiesFeatures objects for the current property
        property_features = PropertiesFeatures.objects.filter(property=obj)
        # Extract the feature data from the related PropertiesFeatures
        feature_data = [
            {
                'feature_id': pf.feature.feature_id,
                'feature_name_en': pf.feature.feature_name_en,
                'feature_name_pt': pf.feature.feature_name_pt,
                # Add other feature fields if needed
            }
            for pf in property_features
        ]
        return feature_data
    
    def get_medias(self, obj):
        # Get the related PropertiesMedia objects for the current property
        property_medias = PropertiesMedia.objects.filter(property=obj)
        # Extract the media data from the related PropertiesMedia
        media_data = [
            {
                'property_media_id': pm.property_media_id,
                'type': pm.type,
                'main': pm.main,
                'url': pm.url,
                # Add other media fields as needed
            }
            for pm in property_medias
        ]
        return media_data

    
    
    def validate(self, attrs):
        attrs['title'] = bleach.clean(attrs['title'])
        attrs['transaction_type'] = bleach.clean(attrs['transaction_type'])
        attrs['description'] = bleach.clean(attrs['description'])
        attrs['list_price_currency'] = bleach.clean(attrs['list_price_currency'])
        attrs['living_area_unit'] = bleach.clean(attrs['living_area_unit'])
        attrs['garage_type'] = bleach.clean(attrs['garage_type'])
        attrs['unit_number'] = bleach.clean(attrs['unit_number'])

        return super().validate(attrs)
    
    def validate_listing_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Listing ID must be equal or higher than 1!')
        return value
      
    class Meta:
        model = Properties
        fields = '__all__'
        depth = 2
        

class PropertyMediaSerializer(serializers.ModelSerializer):
    
    property_media_id = serializers.IntegerField(read_only = True, min_value=1, 
                                                 validators=[UniqueValidator(queryset=PropertiesMedia.objects.all())])
    type = serializers.CharField(read_only = True, max_length=20)
    main = serializers.IntegerField(read_only = True, min_value=0, max_value=1)
    url = serializers.SerializerMethodField()
    #property = serializers.SlugRelatedField(read_only=True, many=True, slug_field='properties')
    property = serializers.PrimaryKeyRelatedField(read_only=True)
    
    def get_url(self, instance):
        url_instance = instance.url
        type_instance = instance.type
        image_formats = ("image/png", "image/jpeg", "image/jpg", "image/gif")
        
        try:
            response = requests.head(url_instance, verify=False)
            if type_instance=='video':
                return url_instance
            elif instance.type=='image' and response.status_code == 200 and response.headers["content-type"] in image_formats:
                return url_instance
        except Exception as e:
            pass  # Image doesn't exist or couldn't be accessed
        return None


    def validate(self, attrs):
        attrs['type'] = bleach.clean(attrs['type'])
        return super().validate(attrs)
    
    def validate_property_media_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Property Media ID must be equal or higher than 1!')
        return value
      
    class Meta:
        model = PropertiesMedia
        fields = '__all__'



class PropertyFeatureSerializer(serializers.ModelSerializer):
    
    property_feature_id = serializers.IntegerField(read_only = True, min_value=1, 
                                                 validators=[UniqueValidator(queryset=PropertiesFeatures.objects.all())])
    feature = serializers.PrimaryKeyRelatedField(read_only=True)
    property = serializers.PrimaryKeyRelatedField(read_only=True)

    
    def validate_property_feature_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Property Feature ID must be equal or higher than 1!')
        return value
    
    def validate_feature_id(self, value):
        if (value < 1):
            raise serializers.ValidationError('Feature ID must be equal or higher than 1!')
        return value
    

      
    class Meta:
        model = PropertiesFeatures
        fields = ['property_feature_id', 'feature', 'property']