import random

from django.shortcuts import get_object_or_404, redirect, render

from .forms import CharacterCreateForm, ChoiceForm
from .models import Character, Choice, InventoryItem, Item, Quest, Scene, StoryEntry


BACKGROUND_STATS = {
    Character.BACKGROUND_WARDEN: {"vigor": 5, "focus": 3, "alchemy": 2},
    Character.BACKGROUND_SCOUR: {"vigor": 4, "focus": 4, "alchemy": 2},
    Character.BACKGROUND_ALCHEMIST: {"vigor": 2, "focus": 4, "alchemy": 5},
}


def get_active_character(request):
    character_id = request.session.get("active_character_id")
    if character_id:
        try:
            return Character.objects.get(id=character_id)
        except Character.DoesNotExist:
            request.session.pop("active_character_id", None)
    return None


def home(request):
    character = get_active_character(request)
    quests = character.quests.all()[:3] if character else []
    inventory = character.inventory.select_related("item")[:3] if character else []

    context = {
        "page_title": "Темная тропа — интерактивная RPG",
        "page_description": "Мрачное текстовое RPG-приключение в духе ведьмачьих саг: выбор, проверки навыков, журнал заданий и лут.",
        "character": character,
        "quests": quests,
        "inventory": inventory,
    }
    return render(request, "core/index.html", context)


def character_create(request):
    if request.method == "POST":
        form = CharacterCreateForm(request.POST)
        if form.is_valid():
            background = form.cleaned_data["background"]
            stats = BACKGROUND_STATS.get(background, {"vigor": 3, "focus": 3, "alchemy": 3})
            starting_scene = Scene.objects.first()
            character = Character.objects.create(
                name=form.cleaned_data["name"],
                background=background,
                vigor=stats["vigor"],
                focus=stats["focus"],
                alchemy=stats["alchemy"],
                current_scene=starting_scene,
            )
            request.session["active_character_id"] = character.id
            starter_item = Item.objects.first()
            if starter_item:
                InventoryItem.objects.create(
                    character=character, item=starter_item, equipped=True
                )
            Quest.objects.create(
                character=character,
                title="Шепот Чёрной Трясины",
                summary="Разузнать, кто тревожит болота и почему местные боятся ночи.",
            )
            return redirect("character_detail", pk=character.id)
    else:
        form = CharacterCreateForm()

    return render(
        request,
        "core/character_create.html",
        {
            "form": form,
            "page_title": "Создать героя",
            "page_description": "Соберите персонажа и начните мрачное приключение.",
        },
    )


def character_detail(request, pk):
    character = get_object_or_404(Character, pk=pk)
    request.session["active_character_id"] = character.id
    equipped = character.inventory.select_related("item").filter(equipped=True)
    recent_entries = character.story_entries.select_related("scene")[:4]

    return render(
        request,
        "core/character_detail.html",
        {
            "character": character,
            "equipped": equipped,
            "recent_entries": recent_entries,
            "page_title": f"{character.name} — профиль героя",
            "page_description": "Профиль персонажа, характеристики и недавние выборы.",
        },
    )


def story_view(request):
    character = get_active_character(request)
    if not character:
        return redirect("character_create")

    scene = character.current_scene or Scene.objects.first()
    if not scene:
        return render(
            request,
            "core/story.html",
            {
                "character": character,
                "scene": None,
                "form": None,
                "page_title": "Сюжет",
                "page_description": "Пока нет сцен. Добавьте их через админку.",
            },
        )

    last_entry_id = request.session.pop("last_entry_id", None)
    last_entry = None
    if last_entry_id:
        last_entry = StoryEntry.objects.filter(
            id=last_entry_id, character=character
        ).select_related("scene").first()

    if request.method == "POST":
        form = ChoiceForm(request.POST, choice_queryset=scene.choices.all())
        if form.is_valid():
            choice = form.cleaned_data["choice"]
            outcome = StoryEntry.OUTCOME_NEUTRAL
            roll = None
            total = None
            next_scene = choice.next_scene or scene

            if choice.required_skill and choice.difficulty:
                roll = random.randint(1, 20)
                skill_value = getattr(character, choice.required_skill, 0)
                total = roll + skill_value
                success = total >= choice.difficulty
                outcome = StoryEntry.OUTCOME_SUCCESS if success else StoryEntry.OUTCOME_FAIL
                next_scene = choice.success_scene if success else choice.fail_scene
                next_scene = next_scene or choice.next_scene or scene

            entry = StoryEntry.objects.create(
                character=character,
                scene=scene,
                choice_text=choice.text,
                outcome=outcome,
                roll=roll,
                total=total,
            )

            if choice.reward_item and outcome != StoryEntry.OUTCOME_FAIL:
                InventoryItem.objects.get_or_create(
                    character=character, item=choice.reward_item
                )

            character.current_scene = next_scene
            character.save(update_fields=["current_scene"])
            request.session["last_entry_id"] = entry.id
            return redirect("story")
    else:
        form = ChoiceForm(choice_queryset=scene.choices.all())

    return render(
        request,
        "core/story.html",
        {
            "character": character,
            "scene": scene,
            "form": form,
            "last_entry": last_entry,
            "page_title": "Сюжет",
            "page_description": "Выбирайте действия и наблюдайте последствия.",
        },
    )


def quest_list(request):
    character = get_active_character(request)
    quests = character.quests.all() if character else []
    return render(
        request,
        "core/quest_list.html",
        {
            "character": character,
            "quests": quests,
            "page_title": "Журнал заданий",
            "page_description": "Список текущих и завершённых заданий.",
        },
    )


def quest_detail(request, pk):
    character = get_active_character(request)
    quest = get_object_or_404(Quest, pk=pk)
    return render(
        request,
        "core/quest_detail.html",
        {
            "character": character,
            "quest": quest,
            "page_title": quest.title,
            "page_description": "Детали задания и его статус.",
        },
    )


def inventory_view(request):
    character = get_active_character(request)
    items = (
        character.inventory.select_related("item") if character else InventoryItem.objects.none()
    )
    return render(
        request,
        "core/inventory.html",
        {
            "character": character,
            "items": items,
            "page_title": "Инвентарь",
            "page_description": "Лут, экипировка и свойства предметов.",
        },
    )


def item_detail(request, pk):
    character = get_active_character(request)
    inventory_item = get_object_or_404(InventoryItem, pk=pk)
    return render(
        request,
        "core/item_detail.html",
        {
            "character": character,
            "inventory_item": inventory_item,
            "page_title": inventory_item.item.name,
            "page_description": "Подробности предмета и его эффектов.",
        },
    )
