from django.utils.translation import get_language from rest_framework import serializers from django.utils.translation import gettext_lazy as _ # from django.db.models import Count from ..models import HadisSect, HadisCategory, Hadis , HadisCategory from django.utils.translation import get_language def get_localized_text(json_list, request=None, fallback_lang="en"): """ Extract localized text from a JSON list based on request's language. Expects: [{"language_code": "en", "text": "..."}, ...] Returns: Single text string or None """ if not json_list or not isinstance(json_list, list): return None # Get target language language_code = getattr(request, "LANGUAGE_CODE", None) if request else None if not language_code: language_code = get_language() or fallback_lang # 1) Exact match for item in json_list: if isinstance(item, dict) and item.get("language_code") == language_code: return item.get("text") # 2) Fallback to English for item in json_list: if isinstance(item, dict) and item.get("language_code") == "en": return item.get("text") # 3) First available if json_list and isinstance(json_list[0], dict): return json_list[0].get("text") return None class LocalizedField(serializers.Field): """ Extracts the correct language from a JSON list based on request.LANGUAGE_CODE (LocaleMiddleware), with sensible fallbacks. """ def to_representation(self, value): # Expecting value to be a list of {"language_code": "...", "text": "..."} if not value or not isinstance(value, list): return None # Get language from request, then fall back to global language / 'fa' request = self.context.get("request") language_code = getattr(request, "LANGUAGE_CODE", None) if request else None if not language_code: language_code = get_language() or "fa" # global active language [web:164][web:172] # 1) Exact match with request language for item in value: if item.get("language_code") == language_code: return item.get("text") # 2) Fallback to English for item in value: if item.get("language_code") == "en": return item.get("text") # 3) Fallback to first item first = value[0] return first.get("text") if isinstance(first, dict) else None class HadisCategorySectListSerializer(serializers.ModelSerializer): """Serializer for HadisSect list with grouped response""" source_types = serializers.SerializerMethodField() title = LocalizedField() class Meta: model = HadisSect fields = ['id', 'title', 'description', 'source_types'] def get_source_types(self, obj): """Get unique source types for this sect's categories""" source_types = HadisCategory.objects.filter( sect=obj ).values_list('source_type', flat=True).distinct() return list(source_types) class HadisCategoryTreeSerializer(serializers.ModelSerializer): title = LocalizedField() """Serializer for HadisCategory tree structure""" sect_id = serializers.IntegerField(source='sect.id', read_only=True) sect_type = serializers.CharField(source='sect.sect_type', read_only=True) children = serializers.SerializerMethodField() class Meta: model = HadisCategory fields = ['id', 'title', 'source_type', 'sect_id', 'sect_type', 'children'] def get_name(self, obj): """Get category name based on request language""" request = self.context.get('request') language_code = getattr(request, 'LANGUAGE_CODE', 'en') return obj.get_translation(language_code) if hasattr(obj, 'get_translation') else obj.title def get_children(self, obj): """Get all active children categories (no filtering by hadis/children)""" children = obj.get_children().filter(sect=obj.sect).order_by('order') return [self.to_dict(cat) for cat in children] def get_hadis_count(self, obj): """Get direct hadis count for this category only""" return Hadis.objects.filter(category=obj, status=True).count() def get_has_hadis(self, obj): """Check if category can have hadis (no active children) and has hadis""" # Check if category has active children has_active_children = obj.get_children().filter(sect=obj.sect).exists() # If has active children, cannot have hadis if has_active_children: return False # If no active children, check if has hadis return Hadis.objects.filter(category=obj, status=True).exists() def get_xmind_file(self, obj): """Get absolute URL for xmind file""" if obj.xmind_file: request = self.context.get('request') if request: return request.build_absolute_uri(obj.xmind_file.url) return obj.xmind_file.url return None def get_has_xmind_file(self, obj): """Check if category has xmind file""" return bool(obj.xmind_file) def get_thumbnail(self, obj): """Get absolute URL for thumbnail""" if hasattr(obj, 'thumbnail') and obj.thumbnail: request = self.context.get('request') if request: return request.build_absolute_uri(obj.thumbnail.url) return obj.thumbnail.url return None def get_hadis_index(self, obj): """Get list of hadis numbers in this category (not including children)""" return list( Hadis.objects.filter( category=obj, status=True ).order_by('number').values_list('number', flat=True) ) def get_children_count(self, obj): """Get count of active children categories""" return obj.get_children().filter(sect=obj.sect).count() def to_dict(self, category, request=None): """Convert category to dict, applying localization""" if request is None: request = self.context.get('request') return { 'id': category.id, 'title': get_localized_text(category.title, request), # <-- use helper 'description': get_localized_text(category.description, request), # <-- use helper 'slug': category.slug, 'source_type': category.source_type, 'hadis_count': self.get_hadis_count(category), 'has_hadis': self.get_has_hadis(category), 'children_count': self.get_children_count(category), 'order': category.order, 'thumbnail': self.get_thumbnail(category), 'xmind_file': self.get_xmind_file(category), 'has_xmind_file': self.get_has_xmind_file(category), 'children': [ self.to_dict(child, request) # recursively apply for child in category.children.all() ] } class HadisCategorySelectSerializer(serializers.ModelSerializer): """Serializer for HadisCategory Selection Flow""" sect_id = serializers.IntegerField(source='sect.id', read_only=True) sect_type = serializers.CharField(source='sect.sect_type', read_only=True) # children = serializers.SerializerMethodField() children_count = serializers.SerializerMethodField() has_hadis = serializers.SerializerMethodField() hadis_count= serializers.SerializerMethodField() title = LocalizedField() description =LocalizedField() class Meta: model = HadisCategory fields = ['id', 'title', 'source_type','slug', 'sect_id', 'sect_type','description','children_count','has_hadis','hadis_count'] def get_has_hadis(self, obj): """Check if category can have hadis (no active children) and has hadis""" # Check if category has active children has_active_children = obj.get_children().filter(sect=obj.sect).exists() # If has active children, cannot have hadis if has_active_children: return False # If no active children, check if has hadis return Hadis.objects.filter(category=obj, status=True).exists() def get_children_count(self, obj): """Get count of active children categories that have children or hadis""" children = obj.get_children().filter(sect=obj.sect) return len(children) def get_hadis_count(self,obj): return len(Hadis.objects.filter(category=obj)) class HadisCategorySelectSourceSerializer(serializers.ModelSerializer): """Serializer for HadisCategory Selection Flow""" sect_id = serializers.IntegerField(source='sect.id', read_only=True) sect_type = serializers.CharField(source='sect.sect_type', read_only=True) children_count = serializers.SerializerMethodField() has_hadis = serializers.SerializerMethodField() hadis_count = serializers.SerializerMethodField() title = LocalizedField() description = LocalizedField() class Meta: model = HadisCategory fields = ['id', 'title', 'source_type','slug', 'sect_id', 'sect_type','description','children_count','has_hadis','hadis_count'] def get_has_hadis(self, obj): """Check if category can have hadis (no active children) and has hadis""" # Check if category has active children has_active_children = obj.get_children().filter(sect=obj.sect).exists() # If has active children, cannot have hadis if has_active_children: return False # If no active children, check if has hadis return Hadis.objects.filter(category=obj, status=True).exists() def get_children_count(self, obj): """Get count of active children categories that have children or hadis""" children = obj.get_children().filter(sect=obj.sect , source_type= obj.source_type) return len(children) def get_hadis_count(self,obj): return len(Hadis.objects.filter(category=obj)) class CategorySerializer(serializers.ModelSerializer): sect_id = serializers.IntegerField(source='sect.id', read_only=True) sect_type = serializers.CharField(source='sect.sect_type', read_only=True) children_count = serializers.SerializerMethodField() has_hadis =serializers.SerializerMethodField() hadis_count=serializers.SerializerMethodField() title = LocalizedField() description = LocalizedField() class Meta: model = HadisCategory fields = ['id', 'title', 'sect_id', 'sect_type','source_type', 'description','slug', 'children_count','has_hadis','hadis_count'] def get_children_count(self, obj): """Get count of active children categories that have children or hadis""" children = obj.get_children().filter(sect=obj.sect) return len(children) def get_has_hadis(self,obj): return Hadis.objects.filter(category=obj).exists() def get_hadis_count(self,obj): return len(Hadis.objects.filter(category=obj)) # def get_title(self,obj): # # ✅ Get language from request # request = self.context.get('request') # lang = request.query_params.get('lang', 'ru') if request else 'ru' # # ✅ CALL THE MODEL METHOD! # return obj.get_title(lang)