from django.http import JsonResponse
from django.shortcuts import render

from dice import engine

from .models import DecathlonScore

MAX_DICE = 8
MAX_LEADERBOARD = 100
MAX_NAME = 24
PIP_STYLES = {'pips', 'cpip'}

# The ten decathlon events in play order. `icon` and `cheat` are base filenames
# under decathlon/static/decathlon/img/ (without extension) for the small
# scoresheet icon and the full cheat-sheet graphic; `active` marks events that
# are actually playable this pass. Inactive rows render as locked "coming soon"
# placeholders on the scoresheet. 400m/1500m have no dedicated icon, so they
# reuse the 100m icon.
EVENTS = [
    {'key': 'm100', 'name': '100 Meters', 'icon': 'dec_icon_100_metres', 'cheat': 'dec_100_metres', 'attempts': 1, 'active': True},
    {'key': 'hurdles', 'name': '110 Meter Hurdles', 'icon': 'dec_icon_110_hurdles', 'cheat': 'dec_110_hurdles', 'attempts': 1, 'active': True},
    {'key': 'long_jump', 'name': 'Long Jump', 'icon': 'dec_icon_long_jump', 'cheat': 'dec_long_jump', 'attempts': 3, 'active': True},
    {'key': 'discus', 'name': 'Discus', 'icon': 'dec_icon_discus', 'cheat': 'dec_discus', 'attempts': 3, 'active': True},
    {'key': 'shot_put', 'name': 'Shot Put', 'icon': 'dec_icon_shot_put', 'cheat': 'dec_shot_put', 'attempts': 3, 'active': True},
    {'key': 'pole_vault', 'name': 'Pole Vault', 'icon': 'dec_icon_pole_vault', 'cheat': 'dec_pole_vault', 'attempts': 1, 'active': True},
    {'key': 'high_jump', 'name': 'High Jump', 'icon': 'dec_icon_high_jump', 'cheat': 'dec_high_jump', 'attempts': 1, 'active': True},
    {'key': 'javelin', 'name': 'Javelin', 'icon': 'dec_icon_javelin', 'cheat': 'dec_javelin', 'attempts': 3, 'active': True},
    {'key': 'm400', 'name': '400 Meters', 'icon': 'dec_icon_100_metres', 'cheat': 'dec_400_metres', 'attempts': 1, 'active': True},
    {'key': 'm1500', 'name': '1500 Meters', 'icon': 'dec_icon_100_metres', 'cheat': 'dec_1500_metres', 'attempts': 1, 'active': True},
]


def index(request):
    return render(request, 'decathlon/index.html', {'events': EVENTS})


def roll(request):
    try:
        n = int(request.GET.get('n', '0'))
    except ValueError:
        n = 0
    n = max(0, min(n, MAX_DICE))

    style = request.GET.get('style', 'pips')
    if style not in PIP_STYLES:
        style = 'pips'

    result = engine.roll_dshort(f'{n}d6{style}') if n else {'roll_html': '', 'increments': []}

    return JsonResponse({
        'roll_html': result['roll_html'],
        'values': [face for _dicetype, face in result['increments']],
    })


def save_score(request):
    try:
        total = int(request.GET.get('total', ''))
    except ValueError:
        return JsonResponse({'scores': [], 'new_rank': None})

    name = request.GET.get('name', '').strip()[:MAX_NAME] or 'Anonymous'

    new_score = DecathlonScore.objects.create(name=name, total=total)
    top_scores = list(DecathlonScore.objects.all()[:MAX_LEADERBOARD])

    scores = []
    new_rank = None
    for rank, score in enumerate(top_scores, start=1):
        is_new = score.pk == new_score.pk
        if is_new:
            new_rank = rank
        scores.append({
            'rank': rank,
            'name': score.name,
            'total': score.total,
            'date': score.played_at.strftime('%Y-%m-%d'),
            'is_new': is_new,
        })

    return JsonResponse({'scores': scores, 'new_rank': new_rank})
