from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import JsonResponse, HttpResponseNotAllowed
from .models import Student, Candidate, Vote


def home(request):
    """Redirect to login or voting page based on session"""
    if 'student_id' in request.session:
        return redirect('candidates')
    return redirect('login')


def login(request):
    """Login page - students select Kelas + Nama Siswa (nama unik)"""
    if request.method == 'POST':
        nama = request.POST.get('nama', '').strip()
        kelas = request.POST.get('kelas', '').strip()

        students = Student.objects.order_by('nama')

        allowed_kelas = {'7A', '7B', '7C', '7D', '7E', '8A', '8B', '8C', '8D', '9A', '9B', '9C', 'Guru'}

        if not kelas:
            messages.error(request, 'Kelas tidak boleh kosong')
            return render(request, 'voting/login.html', {'students': students})

        if kelas not in allowed_kelas:
            messages.error(request, 'Kelas tidak valid')
            return render(request, 'voting/login.html', {'students': students})

        if not nama:
            messages.error(request, 'Nama siswa tidak boleh kosong')
            return render(request, 'voting/login.html', {'students': students})

        try:
            student = Student.objects.get(nama=nama)

            # Validasi kelas agar sesuai dengan pilihan user
            if (student.kelas or '').strip() != kelas:
                messages.error(request, 'Kelas tidak sesuai dengan nama siswa')
                return render(request, 'voting/login.html', {'students': students})

            # Check if student already voted
            if student.sudah_memilih:
                messages.warning(request, 'Anda sudah menggunakan hak pilih')
                return render(request, 'voting/login.html', {'students': students})

            # Store student in session
            request.session['student_id'] = student.id
            request.session['student_nisn'] = student.nisn
            request.session['student_nama'] = student.nama

            return redirect('candidates')

        except Student.DoesNotExist:
            messages.error(request, 'Nama siswa tidak ditemukan dalam database')
            return render(request, 'voting/login.html', {'students': students})

    students = Student.objects.order_by('nama')
    return render(request, 'voting/login.html', {'students': students})


def candidates(request):
    """Display all candidates"""
    # Check if student is logged in
    if 'student_id' not in request.session:
        return redirect('login')

    candidates_list = Candidate.objects.filter(is_active=True)
    student_nama = request.session.get('student_nama', '')

    context = {
        'candidates': candidates_list,
        'student_nama': student_nama,
    }
    return render(request, 'voting/candidates.html', context)


def candidate_detail(request, candidate_id):
    """Display candidate detail"""
    # Check if student is logged in
    if 'student_id' not in request.session:
        return redirect('login')

    candidate = get_object_or_404(Candidate, id=candidate_id, is_active=True)

    context = {
        'candidate': candidate,
    }
    return render(request, 'voting/candidate_detail.html', context)


def vote(request, candidate_id):
    """Process voting"""
    if 'student_id' not in request.session:
        return redirect('login')

    if request.method == 'POST':
        student_id = request.session['student_id']

        # Double-check if student already voted (security)
        try:
            student = Student.objects.get(id=student_id)
            if student.sudah_memilih:
                messages.warning(request, 'Anda sudah menggunakan hak pilih')
                # Clear session data only, keep CSRF token
                for key in ['student_id', 'student_nisn', 'student_nama']:
                    if key in request.session:
                        del request.session[key]
                return render(request, 'voting/login.html')
        except Student.DoesNotExist:
            messages.error(request, 'Session tidak valid')
            return redirect('login')

        candidate = get_object_or_404(Candidate, id=candidate_id, is_active=True)

        # Create vote record
        Vote.objects.create(student=student, candidate=candidate)

        # Update student status
        student.sudah_memilih = True
        student.save()

        # Increment candidate vote count
        candidate.jumlah_suara += 1
        candidate.save()

        # Clear student session data only (keep CSRF token intact)
        for key in ['student_id', 'student_nisn', 'student_nama']:
            if key in request.session:
                del request.session[key]

        # Pass success message to result page
        return render(request, 'voting/vote_success.html', {
            'candidate_name': candidate.nama
        })

    return redirect('candidates')


def logout_view(request):
    """Logout student - clear session data only"""
    # Clear student session data only (keep CSRF token intact)
    for key in ['student_id', 'student_nisn', 'student_nama']:
        if key in request.session:
            del request.session[key]
    messages.success(request, 'Anda telah keluar')
    return redirect('login')


def dashboard(request):
    """Dashboard monitoring - only for admin (no session needed for now)"""
    total_students = Student.objects.count()
    total_votes = Vote.objects.count()
    students_voted = Student.objects.filter(sudah_memilih=True).count()
    students_not_voted = Student.objects.filter(sudah_memilih=False).count()
    candidates_data = Candidate.objects.filter(is_active=True)
    recent_votes = Vote.objects.select_related('student', 'candidate').order_by('-timestamp')[:10]

    context = {
        'total_students': total_students,
        'total_votes': total_votes,
        'students_voted': students_voted,
        'students_not_voted': students_not_voted,
        'participation_rate': (students_voted / total_students * 100) if total_students > 0 else 0,
        'candidates': candidates_data,
        'recent_votes': recent_votes,
    }
    return render(request, 'voting/dashboard.html', context)


def monitor_partisipasi(request):
    """Monitoring partisipasi publik (tanpa session)."""
    return render(request, 'voting/monitor_partisipasi.html')


def monitor_partisipasi_api(request):
    """Return data 'sudah memilih' vs 'belum memilih' + semua kandidat untuk realtime monitoring."""
    if request.method != 'GET':
        return HttpResponseNotAllowed(['GET'])

    total_students = Student.objects.count()
    students_voted = Student.objects.filter(sudah_memilih=True).count()
    students_not_voted = Student.objects.filter(sudah_memilih=False).count()

    participation_rate = (students_voted / total_students * 100) if total_students > 0 else 0

    candidates = list(
        Candidate.objects.filter(is_active=True)
        .order_by('-jumlah_suara', 'nama')
        .values('id', 'nama', 'jumlah_suara', 'foto', 'visi', 'misi')
    )
    podium_id = candidates[0]['id'] if candidates else None
    max_votes = candidates[0]['jumlah_suara'] if candidates else 0

    return JsonResponse({
        'total_students': total_students,
        'students_voted': students_voted,
        'students_not_voted': students_not_voted,
        'participation_rate': participation_rate,
        'podium_id': podium_id,
        'max_votes': max_votes,
        'candidates': candidates,
    })


def monitor_podium(request, candidate_id):
    """Monitoring podium publik untuk kandidat tertentu (tanpa session)."""
    import json

    candidate = get_object_or_404(Candidate, id=candidate_id, is_active=True)

    # leaderboard awal (untuk render cepat sebelum polling)
    leaderboard = list(
        Candidate.objects.filter(is_active=True)
        .order_by('-jumlah_suara', 'nama')
        .values('id', 'nama', 'jumlah_suara')[:10]
    )

    podium = leaderboard[0]['id'] if leaderboard else None

    context = {
        'candidate': candidate,
        'leaderboard': leaderboard,
        'podium_id': podium,
        'target_suara_awal': candidate.jumlah_suara,
        'leaderboard_json': json.dumps(leaderboard, ensure_ascii=False),
    }
    return render(request, 'voting/monitor_podium.html', context)


def monitor_podium_api(request, candidate_id):
    """Return leaderboard & suara kandidat target untuk realtime polling."""
    if request.method != 'GET':
        return HttpResponseNotAllowed(['GET'])

    candidate = get_object_or_404(Candidate, id=candidate_id, is_active=True)

    leaderboard = list(
        Candidate.objects.filter(is_active=True)
        .order_by('-jumlah_suara', 'nama')
        .values('id', 'nama', 'jumlah_suara')[:10]
    )

    podium_id = leaderboard[0]['id'] if leaderboard else None

    return JsonResponse({
        'leaderboard': leaderboard,
        'podium_id': podium_id,
        'target': {
            'id': candidate.id,
            'nama': candidate.nama,
            'jumlah_suara': candidate.jumlah_suara,
        }
    })


def login_required(view_func):
    """Decorator to check if student is logged in"""
    def wrapper(request, *args, **kwargs):
        if 'student_id' not in request.session:
            messages.error(request, 'Silakan login terlebih dahulu')
            return redirect('login')
        return view_func(request, *args, **kwargs)
    return wrapper
