import math
import os
import platform
import random
from collections import Counter

from django import get_version as django_version
from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone
from django.contrib import messages

from .forms import LotterySimulatorForm
from .models import Lottery, DrawResult, AdminAccess

def check_admin(request):
    """Verifica se a chave privada na sessão é válida."""
    key = request.session.get('admin_key')
    return AdminAccess.objects.filter(private_key=key).exists()

def admin_login(request):
    """Tela de login simples para a Chave Privada."""
    if request.method == 'POST':
        key = request.POST.get('private_key')
        if AdminAccess.objects.filter(private_key=key).exists():
            request.session['admin_key'] = key
            return redirect('admin_dashboard')
        else:
            messages.error(request, "Chave Privada Inválida!")
    return render(request, 'core/admin_login.html')

def admin_logout(request):
    request.session.flush()
    return redirect('home')

def admin_dashboard(request):
    """Painel principal do administrador."""
    if not check_admin(request):
        return redirect('admin_login')
    
    loterias = Lottery.objects.all()
    return render(request, 'core/admin_dashboard.html', {'loterias': loterias})

def edit_lottery(request, lottery_id):
    """Editor específico para cada jogo (anular números)."""
    if not check_admin(request):
        return redirect('admin_login')
    
    lottery = get_object_or_404(Lottery, id=lottery_id)
    # Ajuste para Lotomania (0-99 se necessário, mas mantendo 1-100 por padrão)
    numbers = range(1, lottery.max_number + 1)
    annulled = [int(n) for n in lottery.annulled_numbers.split(',') if n]

    if request.method == 'POST':
        selected_numbers = request.POST.getlist('numbers')
        lottery.annulled_numbers = ",".join(selected_numbers)
        lottery.save()
        messages.success(request, f"Configurações da {lottery.get_name_display()} salvas!")
        return redirect('admin_dashboard')

    return render(request, 'core/edit_lottery.html', {
        'lottery': lottery,
        'numbers': numbers,
        'annulled': annulled
    })

def _format_odds(total_combinations):
    if total_combinations >= 1_000_000_000_000:
        return f"1 em {total_combinations:.2e}"
    return f"1 em {total_combinations:,}".replace(",", ".")

def _format_percent(odds):
    percent = 100 / odds
    if percent < 0.000001:
        return "<0,000001%"
    return f"{percent:.6f}%".replace(".", ",")

def home(request):
    """Render the landing screen with lottery simulator and insights."""
    host_name = request.get_host().lower()
    agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
    now = timezone.now()

    loterias_db = Lottery.objects.all()
    lottery_choices = [(l.name, l.get_name_display()) for l in loterias_db]
    
    lottery_cards = []
    for l in loterias_db:
        total_combinations = math.comb(l.max_number, l.numbers_to_draw)
        lottery_cards.append({
            "key": l.name,
            "label": l.get_name_display(),
            "tagline": f"{l.numbers_to_draw} dezenas entre {l.max_number}",
            "range_max": l.max_number,
            "picks": l.numbers_to_draw,
            "odds": _format_odds(total_combinations),
        })

    form = LotterySimulatorForm(
        request.POST or None,
        lottery_choices=lottery_choices,
    )
    result = None

    if form.is_valid():
        lottery_key = form.cleaned_data["lottery_type"]
        draws_to_consider = form.cleaned_data["draws_to_consider"]
        games_to_generate = form.cleaned_data["games_to_generate"]
        
        lottery_obj = Lottery.objects.get(name=lottery_key)
        annulled = [int(n) for n in lottery_obj.annulled_numbers.split(',') if n]
        
        # Busca sorteios reais no banco
        draws_db = DrawResult.objects.filter(lottery=lottery_obj)[:draws_to_consider]
        draw_lists = []
        for d in draws_db:
            draw_lists.append([int(n) for n in d.numbers.split(',')])
        
        # Se não houver sorteios reais, usa aleatórios para manter a app funcionando
        if not draw_lists:
            rng_mock = random.Random(42)
            population = list(range(1, lottery_obj.max_number + 1))
            for _ in range(draws_to_consider):
                draw_lists.append(rng_mock.sample(population, lottery_obj.numbers_to_draw))

        frequency = Counter(number for draw in draw_lists for number in draw)
        numbers = [n for n in range(1, lottery_obj.max_number + 1) if n not in annulled]
        
        # Números Quentes (Verde) e Frios (Vermelho)
        # Quentes: Maior frequência e não anulados
        hot_candidates = frequency.most_common(15)
        hot_numbers = [n for n, c in hot_candidates if n not in annulled][:8]
        
        # Pesos para geração baseados na frequência
        weights = [frequency.get(number, 0) + 1 for number in numbers]
        rng = random.Random(f"{lottery_key}-{draws_to_consider}-{games_to_generate}")

        suggestions = []
        for _ in range(games_to_generate):
            if len(numbers) >= lottery_obj.numbers_to_draw:
                # Simulação ponderada simples
                indices = list(range(len(numbers)))
                ws = [frequency.get(numbers[i], 0) + 1 for i in indices]
                selected_indices = random.choices(indices, weights=ws, k=lottery_obj.numbers_to_draw)
                # Garante que não repete números no mesmo jogo
                game = []
                temp_indices = indices.copy()
                for _p in range(lottery_obj.numbers_to_draw):
                    ws_temp = [frequency.get(numbers[i], 0) + 1 for i in temp_indices]
                    idx = random.choices(range(len(temp_indices)), weights=ws_temp, k=1)[0]
                    game.append(numbers[temp_indices[idx]])
                    del temp_indices[idx]
                suggestions.append(sorted(game))

        total_combinations = math.comb(lottery_obj.max_number, lottery_obj.numbers_to_draw)
        
        result = {
            "lottery": lottery_obj.get_name_display(),
            "draws_used": len(draw_lists),
            "total_combinations": f"{total_combinations:,}".replace(",", "."),
            "odds": _format_odds(total_combinations),
            "percent": _format_percent(total_combinations),
            "suggestions": suggestions,
            "hot_numbers": hot_numbers,
            "annulled_numbers": annulled,
        }

    context = {
        "project_name": "LotoPulse",
        "project_description": "Análise matemática e editor de probabilidades para Loterias Caixa.",
        "agent_brand": agent_brand,
        "django_version": django_version(),
        "python_version": platform.python_version(),
        "current_time": now,
        "form": form,
        "result": result,
        "lottery_cards": lottery_cards,
        "is_admin": check_admin(request),
    }
    return render(request, "core/index.html", context)
