from rest_framework import serializers
from apps.userprofile.serializers import UserProfileSerializer
from apps.core.models.user import User
from apps.userprofile.models import UserProfile
from apps.companies.models import Company

from apps.permissions.models import UserCompanyRole, Role


class SuperAdminUserUpdateSerializer(serializers.ModelSerializer):
    """Simple serializer for super admin to update user and profile"""
    company_ids = serializers.ListField(
        child=serializers.IntegerField(),
        required=False,
        write_only=True,
        help_text="List of company IDs to assign user to"
    )
    
    profile_data = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = User
        fields = ['email', 'username', 'user_type', 'is_active', 'profile_data', 'company_ids']
        extra_kwargs = {
            'email': {'required': False},
            'username': {'required': False},
            'user_type': {'required': False},
            'is_active': {'required': False},
        }
    
    def get_profile_data(self, obj):
        """Return profile data for response"""
        try:
            profile = obj.profile
            if profile:
                return UserProfileSerializer(profile).data
        except UserProfile.DoesNotExist:
            pass
        return None

    def to_internal_value(self, data):
        """Override to handle profile[field_name] and company_ids[index] format"""
        
        profile_data = {}
        profile_fields = ['first_name', 'last_name', 'phone_number', 'image']

        for field in profile_fields:
            profile_key = f'profile[{field}]'
            if profile_key in data:
                profile_data[field] = data[profile_key]

        self._profile_data = profile_data

        data_copy = data.copy()
        for field in profile_fields:
            profile_key = f'profile[{field}]'
            if profile_key in data_copy:
                del data_copy[profile_key]

        company_ids_list = []
        keys_to_remove = []
        
        for key in data_copy.keys():
            if key.startswith('company_ids[') and key.endswith(']'):
                value = data_copy[key]
                if isinstance(value, list) and len(value) > 0:
                    company_ids_list.append(int(value[0]))
                else:
                    company_ids_list.append(int(value))
                keys_to_remove.append(key)

        for key in keys_to_remove:
            del data_copy[key]

        data_dict = {}
        for key, value in data_copy.items():
            if isinstance(value, list) and len(value) > 0:
                data_dict[key] = value[0]
            else:
                data_dict[key] = value
        
        if company_ids_list:
            data_dict['company_ids'] = company_ids_list

        return super().to_internal_value(data_dict)

    def update(self, instance, validated_data):
        profile_data = getattr(self, '_profile_data', {})

        company_ids = validated_data.pop('company_ids', None)
        if company_ids is not None:
            invalid_company_ids = []
            valid_company_ids = company_ids.copy()
            
            if not self.context['request'].user.is_superuser:
                admin_company_ids = list(self.context['request'].user.companies.values_list('id', flat=True))
                invalid_company_ids = [cid for cid in company_ids if cid not in admin_company_ids]
                valid_company_ids = [cid for cid in company_ids if cid in admin_company_ids]

            if valid_company_ids:
                companies = Company.objects.filter(id__in=valid_company_ids, is_active=True)

                existing_roles = UserCompanyRole.objects.filter(user=instance)
                existing_company_ids = set(existing_roles.values_list('company_id', flat=True))

                new_company_ids = set(valid_company_ids) - existing_company_ids
                removed_company_ids = existing_company_ids - set(valid_company_ids)

                if new_company_ids:
                    # advisor_role = Role.objects.filter(name__iexact='Advisor', company_id__in=new_company_ids).first()
                    for company_id in new_company_ids:
                        company = Company.objects.get(id=company_id)
                        role = Role.objects.filter(name__iexact='Advisor', company=company).first()
                        UserCompanyRole.objects.create(
                            user=instance,
                            company=company,
                            role=role
                        )

                if removed_company_ids:
                    UserCompanyRole.objects.filter(user=instance, company_id__in=removed_company_ids).delete()

                instance.companies.set(companies)

                if instance.active_company and instance.active_company.id not in valid_company_ids:
                    instance.active_company = companies.first() if companies.exists() else None


            if invalid_company_ids:
                instance._company_warnings = {
                    'invalid_company_ids': invalid_company_ids,
                    'message': f'You can only assign users to companies you belong to. Invalid company IDs: {invalid_company_ids}'
                }

        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()

        if profile_data:
            profile, created = UserProfile.objects.get_or_create(user=instance)
            
            profile_serializer = UserProfileSerializer(profile, data=profile_data, partial=True)
            if profile_serializer.is_valid():
                profile_serializer.save()
            else:
                raise serializers.ValidationError({'profile': profile_serializer.errors})

        return instance