from rest_framework import serializers
from .models import Permission, Role, UserCompanyRole
from apps.companies.models import Company
from apps.userprofile.models import UserProfile
from django.contrib.auth import get_user_model

User = get_user_model()

class PermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Permission
        fields = ['id', 'name', 'codename', 'is_active', 'created_at', 'updated_at']
        read_only_fields = ['created_at', 'updated_at']

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ['first_name', 'last_name', 'phone_number']


class UserSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(required=False)

    class Meta:
        model = User
        fields = ['id', 'profile', 'email']

class RoleSerializer(serializers.ModelSerializer):
    permissions = PermissionSerializer(many=True, read_only=True)
    users = serializers.SerializerMethodField()
    permission_ids = serializers.PrimaryKeyRelatedField(
        many=True, 
        write_only=True, 
        queryset=Permission.objects.all(),
        required=False,
        source='permissions'
    )
    company_name = serializers.CharField(source='company.name', read_only=True)
    users_count = serializers.SerializerMethodField()

    
    class Meta:
        model = Role
        fields = [
            'id', 'name', 'description', 'company', 'company_name',
            'permission_ids', 'is_active', 'users_count', 'created_at', 'updated_at', 'users','permissions'
        ]
        read_only_fields = ['company', 'users_count', 'created_at', 'updated_at']
    
    def get_users_count(self, obj):
        """Count the number of active users assigned to this role"""
        return UserCompanyRole.objects.filter(
            role=obj,
            is_active=True
        ).count()

    def get_users(self, obj):
        """Return all users assigned to this role"""
        assignments = UserCompanyRole.objects.filter(role=obj).select_related('user')
        users = [a.user for a in assignments]
        return UserSerializer(users, many=True).data
    
    def validate_name(self, value):
        """Validate unique role name within company"""
        request = self.context.get('request')
        if request and request.user:
            # Get company from request data or use active company
            company_id = request.data.get('company')
            if company_id:
                try:
                    company = Company.objects.get(id=company_id, is_active=True)
                    # Check if role with this name already exists in the specified company
                    existing_role = Role.objects.filter(
                        name=value,
                        company=company,
                        is_active=True
                    )
                    
                    # If updating, exclude current instance
                    if self.instance:
                        existing_role = existing_role.exclude(id=self.instance.id)
                    
                    if existing_role.exists():
                        raise serializers.ValidationError(
                            f"Role with name '{value}' already exists in company '{company.name}'"
                        )
                except Company.DoesNotExist:
                    pass  # Will be handled in perform_create
            elif request.user.active_company:
                # Fallback to active company validation
                existing_role = Role.objects.filter(
                    name=value,
                    company=request.user.active_company,
                    is_active=True
                )
                
                # If updating, exclude current instance
                if self.instance:
                    existing_role = existing_role.exclude(id=self.instance.id)
                
                if existing_role.exists():
                    raise serializers.ValidationError(
                        f"Role with name '{value}' already exists in your active company"
                    )
        
        return value
    
    def validate_permission_ids(self, value):
        """Validate that user can only assign permissions they have access to"""
        request = self.context.get('request')
        if request and request.user:
            # Superuser can assign any permissions
            if request.user.is_superuser:
                return value
            
            # Company admins can assign any permissions (for initial setup)
            if request.user.is_company_admin():
                return value
            
            # Users with create_roles permission can assign any permissions
            if request.user.has_company_permission('create_roles'):
                return value
            
            # Regular users can only assign permissions used in their company
            if request.user.active_company and request.user.role:
                company_permissions = Permission.objects.filter(
                    is_active=True,
                    roles__company=request.user.active_company
                ).distinct()
                
                # Check if all provided permissions are available in user's company
                for permission in value:
                    if permission not in company_permissions:
                        raise serializers.ValidationError(
                            f"Permission '{permission.name}' is not available in your company"
                        )
        
        return value 