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

from dice import engine

from .models import GameScore

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

UPPER_ROWS = [
    ('aces', 'Aces = 1', 'Count and Add Only Aces'),
    ('twos', 'Twos = 2', 'Count and Add Only Twos'),
    ('threes', 'Threes = 3', 'Count and Add Only Threes'),
    ('fours', 'Fours = 4', 'Count and Add Only Fours'),
    ('fives', 'Fives = 5', 'Count and Add Only Fives'),
    ('sixes', 'Sixes = 6', 'Count and Add Only Sixes'),
]

LOWER_ROWS = [
    ('three_kind', '3 of a kind', 'Add Total of All Dice'),
    ('four_kind', '4 of a kind', 'Add Total of All Dice'),
    ('full_house', 'Full House', 'Score 25'),
    ('small', 'Sm. Straight (Sequence of 4)', 'Score 30'),
    ('large', 'Lg. Straight (Sequence of 5)', 'Score 40'),
    ('yahtzee', 'YAHTZEE (5 of a kind)', 'Score 50'),
    ('chance', 'Chance', 'Score Total of All 5 Dice'),
]


def index(request):
    context = {'upper_rows': UPPER_ROWS, 'lower_rows': LOWER_ROWS}
    return render(request, 'yahtzee/index.html', context)


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 = GameScore.objects.create(name=name, total=total)
    top_scores = list(GameScore.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})
