"""
ViewSets for Settings Models
"""
from rest_framework import viewsets, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from django.db import transaction
from igny8_core.api.base import AccountModelViewSet
from igny8_core.api.authentication import JWTAuthentication, CSRFExemptSessionAuthentication
from .settings_models import SystemSettings, AccountSettings, UserSettings, ModuleSettings, AISettings
from .settings_serializers import (
    SystemSettingsSerializer, AccountSettingsSerializer, UserSettingsSerializer,
    ModuleSettingsSerializer, AISettingsSerializer
)


class SystemSettingsViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing system-wide settings (admin only for write operations)
    """
    queryset = SystemSettings.objects.all()
    serializer_class = SystemSettingsSerializer
    permission_classes = [permissions.IsAuthenticated]  # Require authentication
    authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
    
    def get_permissions(self):
        """Admin only for write operations, read for authenticated users"""
        if self.action in ['create', 'update', 'partial_update', 'destroy']:
            return [permissions.IsAdminUser()]
        return [permissions.IsAuthenticated()]
    
    def get_queryset(self):
        """Get all system settings"""
        return SystemSettings.objects.all().order_by('key')
    
    def retrieve(self, request, pk=None):
        """Get setting by key (pk can be key string)"""
        try:
            # Try to get by ID first
            setting = self.get_object()
        except:
            # Try to get by key
            try:
                setting = SystemSettings.objects.get(key=pk)
            except SystemSettings.DoesNotExist:
                return Response(
                    {'error': 'Setting not found'},
                    status=status.HTTP_404_NOT_FOUND
                )
        
        serializer = self.get_serializer(setting)
        return Response(serializer.data)


class AccountSettingsViewSet(AccountModelViewSet):
    """
    ViewSet for managing account-level settings
    """
    queryset = AccountSettings.objects.all()
    serializer_class = AccountSettingsSerializer
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
    
    def get_queryset(self):
        """Get settings for current account"""
        return super().get_queryset().order_by('key')
    
    def retrieve(self, request, pk=None):
        """Get setting by key (pk can be key string)"""
        queryset = self.get_queryset()
        try:
            # Try to get by ID first
            setting = queryset.get(pk=pk)
        except:
            # Try to get by key
            try:
                setting = queryset.get(key=pk)
            except AccountSettings.DoesNotExist:
                return Response(
                    {'error': 'Setting not found'},
                    status=status.HTTP_404_NOT_FOUND
                )
        
        serializer = self.get_serializer(setting)
        return Response(serializer.data)
    
    def perform_create(self, serializer):
        """Set account automatically"""
        account = getattr(self.request, 'account', None)
        if not account:
            user = getattr(self.request, 'user', None)
            if user:
                account = getattr(user, 'account', None)
        
        if not account:
            from rest_framework.exceptions import ValidationError
            raise ValidationError("Account is required")
        
        serializer.save(account=account)


class UserSettingsViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing user-level settings
    """
    queryset = UserSettings.objects.all()
    serializer_class = UserSettingsSerializer
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
    
    def get_queryset(self):
        """Get settings for current user and account"""
        user = self.request.user
        account = getattr(self.request, 'account', None)
        if not account:
            account = getattr(user, 'account', None)
        
        if account:
            return UserSettings.objects.filter(user=user, account=account).order_by('key')
        return UserSettings.objects.none()
    
    def retrieve(self, request, pk=None):
        """Get setting by key (pk can be key string)"""
        queryset = self.get_queryset()
        try:
            # Try to get by ID first
            setting = queryset.get(pk=pk)
        except:
            # Try to get by key
            try:
                setting = queryset.get(key=pk)
            except UserSettings.DoesNotExist:
                return Response(
                    {'error': 'Setting not found'},
                    status=status.HTTP_404_NOT_FOUND
                )
        
        serializer = self.get_serializer(setting)
        return Response(serializer.data)
    
    def perform_create(self, serializer):
        """Set user and account automatically"""
        user = self.request.user
        account = getattr(self.request, 'account', None)
        if not account:
            account = getattr(user, 'account', None)
        
        if not account:
            from rest_framework.exceptions import ValidationError
            raise ValidationError("Account is required")
        
        serializer.save(user=user, account=account)


class ModuleSettingsViewSet(AccountModelViewSet):
    """
    ViewSet for managing module-specific settings
    """
    queryset = ModuleSettings.objects.all()
    serializer_class = ModuleSettingsSerializer
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
    
    def get_queryset(self):
        """Get settings for current account, optionally filtered by module"""
        queryset = super().get_queryset()
        module_name = self.request.query_params.get('module_name')
        if module_name:
            queryset = queryset.filter(module_name=module_name)
        return queryset.order_by('module_name', 'key')
    
    @action(detail=False, methods=['get'], url_path='module/(?P<module_name>[^/.]+)', url_name='by_module')
    def by_module(self, request, module_name=None):
        """Get all settings for a specific module"""
        queryset = self.get_queryset().filter(module_name=module_name)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
    
    def retrieve(self, request, pk=None):
        """Get setting by key (pk can be key string)"""
        queryset = self.get_queryset()
        try:
            # Try to get by ID first
            setting = queryset.get(pk=pk)
        except:
            # Try to get by module_name and key
            module_name = request.query_params.get('module_name')
            if module_name:
                try:
                    setting = queryset.get(module_name=module_name, key=pk)
                except ModuleSettings.DoesNotExist:
                    return Response(
                        {'error': 'Setting not found'},
                        status=status.HTTP_404_NOT_FOUND
                    )
            else:
                return Response(
                    {'error': 'Setting not found'},
                    status=status.HTTP_404_NOT_FOUND
                )
        
        serializer = self.get_serializer(setting)
        return Response(serializer.data)
    
    def perform_create(self, serializer):
        """Set account automatically"""
        account = getattr(self.request, 'account', None)
        if not account:
            user = getattr(self.request, 'user', None)
            if user:
                account = getattr(user, 'account', None)
        
        if not account:
            from rest_framework.exceptions import ValidationError
            raise ValidationError("Account is required")
        
        serializer.save(account=account)


class AISettingsViewSet(AccountModelViewSet):
    """
    ViewSet for managing AI-specific settings
    """
    queryset = AISettings.objects.all()
    serializer_class = AISettingsSerializer
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
    
    def get_queryset(self):
        """Get AI settings for current account"""
        return super().get_queryset().order_by('integration_type')
    
    def retrieve(self, request, pk=None):
        """Get setting by integration_type (pk can be integration_type string)"""
        queryset = self.get_queryset()
        try:
            # Try to get by ID first
            setting = queryset.get(pk=pk)
        except:
            # Try to get by integration_type
            try:
                setting = queryset.get(integration_type=pk)
            except AISettings.DoesNotExist:
                return Response(
                    {'error': 'AI Setting not found'},
                    status=status.HTTP_404_NOT_FOUND
                )
        
        serializer = self.get_serializer(setting)
        return Response(serializer.data)
    
    def perform_create(self, serializer):
        """Set account automatically"""
        account = getattr(self.request, 'account', None)
        if not account:
            user = getattr(self.request, 'user', None)
            if user:
                account = getattr(user, 'account', None)
        
        if not account:
            from rest_framework.exceptions import ValidationError
            raise ValidationError("Account is required")
        
        serializer.save(account=account)

