from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.template import loader
from json import loads, dumps
from math import floor
import requests
from .forms import ServerAddressForm
import logging

# Create your views here.

# Debug and defaults.
defaults = {
    "listen_address": "http://localhost:51111/",
}
logging.basicConfig(encoding="utf-8", level=logging.DEBUG)

# API endpoints
# /overview - {screne, seed, items (int), entrances (int), hints (int), codes (dict of codes in an area and how care they are, can be empty)}
# /items - {[scene names] ({name (name of item that was received), owner (in multiworld, who received that item)})}
# /doors - {[scene names] ({scene (name of scene the mapped entrance is in), door (name of entrance it leads to)})}
# /hints - {[where hint was received] (raw trunic string of hint)}


def session_key(session, key):
    if key not in session.keys():
        session[key] = defaults[key]

    # TODO: consider serializing user sessions for debugging in the future.
    logging.info(f"Session {key} set to: {session[key]}")
    return session[key]


def index(request):
    listen_address = session_key(request.session, "listen_address")

    # try:
    #     request_overview_data = requests.get(
    #         f"{listen_address}overview", timeout=5, verify=True
    #     ).text
    #     request_items_data = requests.get(
    #         f"{listen_address}items", timeout=5, verify=True
    #     ).text
    #     request_doors_data = requests.get(
    #         f"{listen_address}doors", timeout=5, verify=True
    #     ).text
    #     request_hints_data = requests.get(
    #         f"{listen_address}hints", timeout=5, verify=True
    #     ).text
    #     tracker_overview_data = loads(request_overview_data)
    #     if "error" in tracker_overview_data.keys():
    #         raise ValueError
    #     tracker_items_data = loads(request_items_data)
    #     tracker_doors_data = loads(request_doors_data)
    #     tracker_hints_data = loads(request_hints_data)
    # except:
    with open("empty_overview.json", "r") as t:
        tracker_overview_data = loads(t.read())
    with open("empty_items.json", "r") as t:
        tracker_items_data = loads(t.read())
    with open("empty_doors.json", "r") as t:
        tracker_doors_data = loads(t.read())
    with open("empty_hints.json", "r") as t:
        tracker_hints_data = loads(t.read())
    with open("tracker/static/tracker/data/holy_cross_codes.json", "r") as t:
        try:
            temp_codes = loads(t.read())
            cross_codes = {
                x: {
                    k: l.replace("U", "⬆️")
                    .replace("D", "⬇️")
                    .replace("L", "⬅️")
                    .replace("R", "➡️")
                    .strip()
                    for k, l in temp_codes[x].items()
                }
                for x in temp_codes.keys()
            }
        except:
            return

    # Data from the /overview API call
    tracker_current_scene = tracker_overview_data["scene"]
    tracker_seed = tracker_overview_data["seed"]
    tracker_hints_found_total = tracker_overview_data["hints"]
    tracker_current_scene_codes = tracker_overview_data["codes"]

    # Data from the /doors API call
    tracker_entrances_total = tracker_doors_data["total"]
    tracker_entrances_remaining = tracker_doors_data["remaining"]
    tracker_entrances_mapped_total = tracker_doors_data["found"]

    # Data from the /items API call
    tracker_checks_total = tracker_items_data["total"]
    tracker_checks_remaining = tracker_items_data["remaining"]
    tracker_checks_cleared_total = tracker_items_data["collected"]

    active_codes = {}
    for name, value in tracker_current_scene_codes.items():
        logging.debug(value)
        this_scene = tracker_current_scene
        if value["Global"]:
            this_scene = "Global"
        active_codes[name] = {
            "distance": value["Distance"],
            "global": value["Global"],
            "in_range": value["InRange"],
            "code": cross_codes[this_scene][name],
        }
    logging.debug(active_codes)

    scene_data = {}
    for scene in tracker_doors_data["scenes"].keys():
        scene_data[scene] = {
            "entrances": tracker_doors_data["scenes"][scene],
            "checks": tracker_items_data["scenes"][scene],
        }
        scene_data[scene]["checks"]["collected"] = (
            scene_data[scene]["checks"]["collected"]
            + scene_data[scene]["checks"]["found"]
        )

    template = loader.get_template("tracker/index.html")
    server_address_form = ServerAddressForm()
    server_address_form.fields["server_address_form"].initial = listen_address
    logging.debug(format_overview_output(tracker_overview_data))
    context = {
        "server_address": listen_address,
        "debug": {},
        "default_codes": cross_codes["Default"],
        "totals": {
            "Checks": {
                "Undiscovered": tracker_checks_cleared_total,
                "Remaining": tracker_checks_remaining,
                "Total": tracker_checks_total,
            },
            "Entrances": {
                "Undiscovered": tracker_entrances_mapped_total,
                "Remaining": tracker_entrances_remaining,
                "Total": tracker_entrances_total,
            },
        },
        "scenes": scene_data,
        "current_scene": tracker_current_scene,
        "codes": active_codes,
        "server_address_form": server_address_form,
        "hints": tracker_hints_data,
    }
    return HttpResponse(template.render(context, request))


def get_address(request):
    if request.method == "GET":
        return HttpResponse(
            dumps({"listen_address": request.session["listen_address"]}),
            content_type="application/json",
        )
    else:
        return render(request, "tracker/index.html")


def set_address(request):
    if request.method == "POST":
        form = ServerAddressForm(request.POST)
        if form.is_valid():
            request.session["listen_address"] = form.cleaned_data["server_address_form"]
            return HttpResponseRedirect("/")
    else:
        form = ServerAddressForm()
    return render(request, "tracker/index.html", {"server_address_form": form})


def format_overview_output(overview):
    overview_string = "\nReceived Overview Data:\n"
    for key, value in overview.items():
        overview_string += f"\t{key}: "
        if key == "codes":
            overview_string += "\n"
            for code, something in value.items():
                overview_string += f"\t\t{code}: {something['Distance']:.2f}\n"
        else:
            overview_string += f"{value}\n"
    return overview_string


def format_items_output(items):
    items_string = "\nReceived Item Data:\n"
    for key, value in items.items():
        items_string += f"\t{key}:\n"
        for check_key, check_value in value.items():
            items_string += f"\t\t{check_key}: {check_value}\n"
    return items_string


def format_doors_output(doors):
    doors_string = "\nReceived Door Data:\n"
    for key, value in doors.items():
        doors_string += f"\t{key}: "
        for entrance_key, entrance_value in value.items():
            doors_string += f"\t\t{entrance_key}: {entrance_value}\n"
    return doors_string


def format_hints_output(hints):
    hints_string = "\nReceived Hint Data:\n"
    for key, value in hints.items():
        hints_string += f"\t{key}: "
    return hints_string
