"""
Public survey views - Token-based survey forms (no login required)
"""
from django.contrib import messages
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.views.decorators.http import require_http_methods

from apps.core.services import AuditService

from .models import SurveyInstance, SurveyQuestion, SurveyResponse


@require_http_methods(["GET", "POST"])
def survey_form(request, token):
    """
    Public survey form - accessible via secure token link.
    
    Features:
    - No login required
    - Token-based access
    - Mobile-first responsive design
    - Bilingual support (AR/EN)
    - Progress indicator
    - Question type rendering
    - Form validation
    """
    # Get survey instance by token
    try:
        survey = SurveyInstance.objects.select_related(
            'survey_template',
            'patient',
            'journey_instance',
            'journey_stage_instance'
        ).prefetch_related(
            'survey_template__questions'
        ).get(
            access_token=token,
            status__in=['pending', 'sent'],
            token_expires_at__gt=timezone.now()
        )
    except SurveyInstance.DoesNotExist:
        return render(request, 'surveys/invalid_token.html', {
            'error': 'invalid_or_expired'
        })
    
    # Mark as opened if first time
    if not survey.opened_at:
        survey.opened_at = timezone.now()
        survey.status = 'in_progress'
        survey.save(update_fields=['opened_at', 'status'])
    
    # Get questions
    questions = survey.survey_template.questions.filter(
        is_required=True
    ).order_by('order') | survey.survey_template.questions.filter(
        is_required=False
    ).order_by('order')
    
    if request.method == 'POST':
        # Process survey responses
        language = request.POST.get('language', 'en')
        errors = []
        responses_data = []
        
        # Validate and collect responses
        for question in questions:
            field_name = f'question_{question.id}'
            
            # Check if required
            if question.is_required and not request.POST.get(field_name):
                errors.append(f"Question {question.order + 1} is required")
                continue
            
            # Get response value based on question type
            if question.question_type in ['rating', 'likert']:
                numeric_value = request.POST.get(field_name)
                if numeric_value:
                    responses_data.append({
                        'question': question,
                        'numeric_value': float(numeric_value),
                        'text_value': '',
                        'choice_value': ''
                    })
            
            elif question.question_type == 'nps':
                numeric_value = request.POST.get(field_name)
                if numeric_value:
                    responses_data.append({
                        'question': question,
                        'numeric_value': float(numeric_value),
                        'text_value': '',
                        'choice_value': ''
                    })
            
            elif question.question_type == 'yes_no':
                choice_value = request.POST.get(field_name)
                if choice_value:
                    # Convert yes/no to numeric for scoring
                    numeric_value = 5.0 if choice_value == 'yes' else 1.0
                    responses_data.append({
                        'question': question,
                        'numeric_value': numeric_value,
                        'text_value': '',
                        'choice_value': choice_value
                    })
            
            elif question.question_type == 'multiple_choice':
                choice_value = request.POST.get(field_name)
                if choice_value:
                    responses_data.append({
                        'question': question,
                        'numeric_value': None,
                        'text_value': '',
                        'choice_value': choice_value
                    })
            
            elif question.question_type in ['text', 'textarea']:
                text_value = request.POST.get(field_name, '')
                if text_value:
                    responses_data.append({
                        'question': question,
                        'numeric_value': None,
                        'text_value': text_value,
                        'choice_value': ''
                    })
        
        # If validation errors, show form again
        if errors:
            context = {
                'survey': survey,
                'questions': questions,
                'errors': errors,
                'language': language,
            }
            return render(request, 'surveys/public_form.html', context)
        
        # Save responses
        for response_data in responses_data:
            SurveyResponse.objects.update_or_create(
                survey_instance=survey,
                question=response_data['question'],
                defaults={
                    'numeric_value': response_data['numeric_value'],
                    'text_value': response_data['text_value'],
                    'choice_value': response_data['choice_value'],
                }
            )
        
        # Update survey status
        survey.status = 'completed'
        survey.completed_at = timezone.now()
        survey.save(update_fields=['status', 'completed_at'])
        
        # Calculate score
        score = survey.calculate_score()
        
        # Log completion
        AuditService.log(
            event_type='survey_completed',
            description=f"Survey completed: {survey.survey_template.name}",
            user=None,
            content_object=survey,
            metadata={
                'score': float(score) if score else None,
                'is_negative': survey.is_negative,
                'response_count': len(responses_data)
            }
        )
        
        # Create PX action if negative
        if survey.is_negative:
            from apps.surveys.tasks import create_action_from_negative_survey
            create_action_from_negative_survey.delay(str(survey.id))
        
        # Redirect to thank you page
        return redirect('surveys:thank_you', token=token)
    
    # GET request - show form
    # Determine language from query param or browser
    language = request.GET.get('lang', 'en')
    
    context = {
        'survey': survey,
        'questions': questions,
        'language': language,
        'total_questions': questions.count(),
    }
    
    return render(request, 'surveys/public_form.html', context)


def thank_you(request, token):
    """Thank you page after survey completion"""
    try:
        survey = SurveyInstance.objects.select_related(
            'survey_template',
            'patient'
        ).get(
            access_token=token,
            status='completed'
        )
    except SurveyInstance.DoesNotExist:
        return render(request, 'surveys/invalid_token.html', {
            'error': 'not_found'
        })
    
    language = request.GET.get('lang', 'en')
    
    context = {
        'survey': survey,
        'language': language,
    }
    
    return render(request, 'surveys/thank_you.html', context)


def invalid_token(request):
    """Invalid or expired token page"""
    return render(request, 'surveys/invalid_token.html')
