from django.contrib import messages
from django.contrib.auth.decorators import (
    login_required,
    permission_required,
    user_passes_test,
)
from django.http import HttpResponseRedirect
from django.shortcuts import redirect, render
from django.utils.html import format_html

from allianceauth.services.hooks import get_extension_logger

from buybackprogram.forms import (
    AddWatchlistForm,
    ProgramItemForm,
    ProgramMarketGroupForm,
    StaticItemPriceForm,
)
from buybackprogram.models import Program, ProgramItem, StaticItemPrice, WatchlistItem
from buybackprogram.utils import can_manage_program_test, messages_plus

logger = get_extension_logger(__name__)


@login_required
@permission_required("buybackprogram.basic_access")
def program_special_taxes(request, program_pk):
    program = Program.objects.get(pk=program_pk)
    program_items = ProgramItem.objects.filter(program=program)
    static_prices = StaticItemPrice.objects.filter(program=program)
    watchlist_items = WatchlistItem.objects.filter(program=program)

    context = {
        "program": program,
        "program_items": program_items,
        "static_prices": static_prices,
        "watchlist_items": watchlist_items,
    }

    return render(request, "buybackprogram/program_special_taxes.html", context)


@login_required
@user_passes_test(can_manage_program_test)
def program_edit_item(request, program_pk):
    program = Program.objects.get(pk=program_pk)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    program_items = ProgramItem.objects.filter(program=program)

    if request.method != "POST":
        form = ProgramItemForm()
    else:
        form = ProgramItemForm(
            request.POST,
            value=int(request.POST["item_type"]),
        )

        if form.is_valid():
            item_tax = form.cleaned_data["item_tax"]
            disallow_item = form.cleaned_data["disallow_item"]

            item_type = form.cleaned_data["item_type"]

            ProgramItem.objects.update_or_create(
                item_type=item_type,
                program=program,
                defaults={
                    "item_tax": item_tax,
                    "disallow_item": disallow_item,
                    "market_group": None,
                },
            )

            if disallow_item:
                messages_plus.warning(
                    request,
                    format_html(
                        "Disallowed <strong>{}</strong> in program",
                        item_type.name,
                    ),
                )

            else:
                messages_plus.success(
                    request,
                    format_html(
                        "Adjusted <strong>{}</strong> tax in program with <strong>{}</strong> %, tax is now set at {} %",
                        item_type.name,
                        item_tax,
                        program.tax + item_tax,
                    ),
                )

            return HttpResponseRedirect(request.path_info)

    context = {
        "program": program,
        "program_items": program_items,
        "form": form,
    }

    return render(request, "buybackprogram/program_edit_item.html", context)


@login_required
@user_passes_test(can_manage_program_test)
def program_edit_static_price(request, program_pk):
    program = Program.objects.get(pk=program_pk)
    static_prices = StaticItemPrice.objects.filter(program=program)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    if request.method != "POST":
        form = StaticItemPriceForm()
    else:
        # Use item_type because that is the name of our field in the Form
        form = StaticItemPriceForm(
            request.POST,
            value=int(request.POST["item_type"]),
        )

        if form.is_valid():
            price = form.cleaned_data["price"]
            # Get the object from the form's cleaned data
            item_type = form.cleaned_data["item_type"]

            StaticItemPrice.objects.update_or_create(
                eve_type=item_type,
                program=program,
                defaults={"price": price},
            )

            messages_plus.success(
                request,
                format_html(
                    "Set static price for <strong>{}</strong> to <strong>{}</strong> ISK",
                    item_type.name,
                    price,
                ),
            )
            return HttpResponseRedirect(request.path_info)

    context = {
        "program": program,
        "static_prices": static_prices,
        "form": form,
    }
    return render(request, "buybackprogram/program_edit_static_price.html", context)


@login_required
@user_passes_test(can_manage_program_test)
def remove_static_price(request, program_pk, price_pk):
    program = Program.objects.get(pk=program_pk)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    static_price = StaticItemPrice.objects.get(pk=price_pk, program_id=program_pk)
    name = static_price.eve_type.name
    static_price.delete()
    messages_plus.warning(
        request,
        format_html("Deleted static price for <strong>{}</strong> from program", name),
    )
    return redirect("buybackprogram:program_special_taxes", program_pk)


@login_required
@user_passes_test(can_manage_program_test)
def program_edit_marketgroup(request, program_pk):
    program = Program.objects.get(pk=program_pk)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    program_items = ProgramItem.objects.filter(program=program)

    if request.method != "POST":
        form = ProgramMarketGroupForm()
    else:
        form = ProgramMarketGroupForm(
            request.POST,
            value=int(request.POST["marketgroup"]),
        )

        if form.is_valid():
            item_tax = form.cleaned_data["item_tax"]
            disallow_item = form.cleaned_data["disallow_item"]
            marketgroup = form.cleaned_data["marketgroup"]

            ProgramItem.objects.update_or_create(
                market_group=marketgroup,
                program=program,
                defaults={
                    "item_tax": item_tax,
                    "disallow_item": disallow_item,
                    "item_type": None,
                },
            )

            if disallow_item:
                messages_plus.warning(
                    request,
                    format_html(
                        "Disallowed market group <strong>{}</strong> in program",
                        marketgroup,
                    ),
                )
            else:
                messages_plus.success(
                    request,
                    format_html(
                        "Added market group <strong>{}</strong> to program with <strong>{}</strong> % tax",
                        marketgroup,
                        item_tax,
                    ),
                )

            return HttpResponseRedirect(request.path_info)

    context = {
        "program": program,
        "program_items": program_items,
        "form": form,
    }

    return render(request, "buybackprogram/program_edit_marketgroup.html", context)


@login_required
@user_passes_test(can_manage_program_test)
def program_item_remove(request, program_pk, item_pk):
    program = Program.objects.get(pk=program_pk)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    ProgramItem.objects.filter(pk=item_pk, program__pk=program_pk).delete()
    return redirect("buybackprogram:program_special_taxes", program_pk=program_pk)


@login_required
@user_passes_test(can_manage_program_test)
def program_item_remove_all(request, program_pk):
    program = Program.objects.get(pk=program_pk)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    program_item = ProgramItem.objects.filter(program=program_pk)

    program_item.delete()

    messages_plus.warning(
        request,
        format_html(
            "Deleted all special taxation items from program",
        ),
    )

    return redirect("buybackprogram:program_special_taxes", program_pk)


@login_required
@user_passes_test(can_manage_program_test)
def program_edit_watchlist(request, program_pk):
    program = Program.objects.get(pk=program_pk)
    watchlist_items = WatchlistItem.objects.filter(program=program)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    if request.method != "POST":
        form = AddWatchlistForm()
    else:
        # Extract the raw IDs safely
        raw_item_type = request.POST.get("item_type")
        item_val = (
            int(raw_item_type) if raw_item_type and raw_item_type.isdigit() else None
        )

        raw_eve_group = request.POST.get("eve_group")
        group_val = (
            int(raw_eve_group) if raw_eve_group and raw_eve_group.isdigit() else None
        )

        # Pass both values to the form's __init__ method
        form = AddWatchlistForm(
            request.POST,
            item_value=item_val,
            group_value=group_val,
        )

        if form.is_valid():
            item_type = form.cleaned_data.get("item_type")
            eve_group = form.cleaned_data.get("eve_group")

            # Check if this rule already exists
            exists = WatchlistItem.objects.filter(
                program=program, item_type=item_type, eve_group=eve_group
            ).exists()

            if exists:
                messages_plus.warning(
                    request, "This item or group is already on the watchlist."
                )
            else:
                WatchlistItem.objects.create(
                    program=program, item_type=item_type, eve_group=eve_group
                )

                name = item_type.name if item_type else eve_group.name
                target_type = "Item" if item_type else "Group"

                messages_plus.success(
                    request,
                    format_html(
                        "Added {} <strong>{}</strong> to the manual review watchlist",
                        target_type,
                        name,
                    ),
                )
            return HttpResponseRedirect(request.path_info)

    context = {
        "program": program,
        "watchlist_items": watchlist_items,
        "form": form,
    }
    return render(request, "buybackprogram/program_edit_watchlist.html", context)


@login_required
@user_passes_test(can_manage_program_test)
def remove_watchlist_item(request, program_pk, watchlist_pk):
    program = Program.objects.get(pk=program_pk)

    if not program.user_can_manage(request.user):
        messages.error(request, "You do not have permission to manage this program.")
        return redirect("buybackprogram:program_special_taxes", program_pk=program.id)

    watchlist_item = WatchlistItem.objects.get(pk=watchlist_pk, program_id=program_pk)

    name = (
        watchlist_item.item_type.name
        if watchlist_item.item_type
        else watchlist_item.eve_group.name
    )
    target_type = "Item" if watchlist_item.item_type else "Group"

    watchlist_item.delete()

    messages_plus.warning(
        request,
        format_html(
            "Removed {} <strong>{}</strong> from the watchlist", target_type, name
        ),
    )
    # Redirect back to the special taxes dashboard
    return redirect("buybackprogram:program_special_taxes", program_pk)
