from datetime import datetime, timezone

from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
from tools.forms.ooi import OoiTreeSettingsForm
from tools.ooi_helpers import create_object_tree_item_from_ref, filter_ooi_tree, get_ooi_types_from_tree
from tools.view_helpers import Breadcrumb, get_ooi_url

from rocky.views.ooi_view import BaseOOIDetailView


class OOITreeView(BaseOOIDetailView, TemplateView):
    template_name = "oois/ooi_tree.html"
    connector_form_class = OoiTreeSettingsForm

    def get_tree_dict(self):
        return create_object_tree_item_from_ref(self.tree.root, self.tree.store)

    def get_filtered_tree(self, tree_dict):
        filtered_types = self.request.GET.getlist("ooi_type", [])
        return filter_ooi_tree(tree_dict, filtered_types)

    def count_observed_at_filter(self) -> int:
        return 1 if datetime.now(timezone.utc).date() != self.observed_at.date() else 0

    def count_active_filters(self):
        count_depth_filter = len(self.request.GET.getlist("depth", []))
        count_ooi_type_filter = len(self.request.GET.getlist("ooi_type", []))
        return self.count_observed_at_filter() + count_depth_filter + count_ooi_type_filter

    def get_connector_form_kwargs(self):
        kwargs = super().get_connector_form_kwargs()

        tree_dict = self.get_tree_dict()
        ooi_types = get_ooi_types_from_tree(tree_dict, True)
        kwargs.update({"ooi_types": ooi_types})

        return kwargs

    def build_breadcrumbs(self) -> list[Breadcrumb]:
        breadcrumbs = super().build_breadcrumbs()
        breadcrumbs.append(self.get_last_breadcrumb())
        return breadcrumbs

    def get_last_breadcrumb(self):
        return {
            "url": get_ooi_url("ooi_tree", self.ooi.primary_key, self.organization.code),
            "text": _("Tree Visualisation"),
        }

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        context["tree"] = self.get_filtered_tree(self.get_tree_dict())
        context["tree_view"] = self.request.GET.get("view", "condensed")
        context["observed_at_form"] = self.get_connector_form()
        context["active_filters_counter"] = self.count_active_filters()
        return context


class OOISummaryView(OOITreeView):
    template_name = "oois/ooi_summary.html"

    def get_last_breadcrumb(self):
        return {"url": get_ooi_url("ooi_summary", self.ooi.primary_key, self.organization.code), "text": _("Summary")}


class OOIGraphView(OOITreeView):
    template_name = "graph-d3.html"

    def get_filtered_tree(self, tree_dict):
        filtered_tree = super().get_filtered_tree(tree_dict)
        return hydrate_tree(filtered_tree, self.organization.code)

    def get_last_breadcrumb(self):
        return {
            "url": get_ooi_url("ooi_graph", self.ooi.primary_key, self.organization.code),
            "text": _("Graph Visualisation"),
        }


def hydrate_tree(tree, organization_code: str):
    return hydrate_branch(tree, organization_code)


def hydrate_branch(branch, organization_code: str):
    branch["name"] = branch["tree_meta"]["location"] + "-" + branch["ooi_type"]
    branch["overlay_data"] = {"Type": branch["ooi_type"]}
    if branch["ooi_type"] == "Finding":
        branch["overlay_data"]["Description"] = branch["description"]
        branch["overlay_data"]["Proof"] = branch["proof"]
    elif branch["ooi_type"] == "IpPort":
        branch["overlay_data"]["Port"] = str(branch["port"])
        branch["overlay_data"]["Protocol"] = branch["protocol"]
        branch["overlay_data"]["State"] = branch["state"]

    branch["display_name"] = branch["human_readable"]
    branch["graph_url"] = get_ooi_url("ooi_graph", branch["id"], organization_code=organization_code)

    if branch.get("children"):
        branch["children"] = [hydrate_branch(child, organization_code) for child in branch["children"]]

    return branch
