import logging

from .models import Group, Group2Type, GroupParent, Node, Node2Group, Measurement


def get_child_nodes(parent: Group):
    relationships = list(GroupParent.objects.all())
    node2group = list(Node2Group.objects.all())

    result = []

    for node in node2group:
        if node.group.pk == parent.pk:
            result.append(node.node.pk)

    children = [rel.child for rel in relationships if rel.parent.pk == parent.pk]

    for child in children:
        result.extend(get_child_nodes(child))

    return result

def get_sites_for_user():
    site_candidates = Group.objects.raw("SELECT * FROM datavis_group JOIN datavis_group2type ON datavis_group.id = datavis_group2type.group_id JOIN datavis_grouptype ON datavis_grouptype.id = datavis_group2type.type_id WHERE datavis_grouptype.name = 'Site'")
    return site_candidates

def get_customer_site_application_data(site_id: int) -> dict | None :
    """
    Composes relationships into logical application format, for a given customer

    site_id: Primary key int for the group
    """

    # Filter by groups of type site with name site_name
    site_candidates = Group.objects.filter(id=site_id)

    logging.debug(f"Getting site data for [{site_id}], found [{len(site_candidates)}] matches")

    if len(site_candidates) != 1:
        if len(site_candidates) == 0:
            logging.error(f"Requested customer site information for a site that doesn't exist: {site_id}")
        else:
            logging.fatal(f"Unique primary key invariant not upheld for Groups! Primary key: {site_id}")
        return None

    result = {
        "site": site_candidates[0],
        "windrows": {
        #     {
        #         "name": "1",
        #         "status": "status_enum",
        #         "temperature_sites": {
        #             "id":     {
        #                 "name": "t1",
        #                 "assigned_probe": "1",
        #                 "measurements": [],
        #             }
        #         }
        #     }
        },
        "spare_nodes": [],
    }

    windrows = Group.objects.filter(group2type__type__name="Windrow", child_group__parent_id=site_id)

    for windrow in windrows:
        new_windrow = {"id": windrow.pk, "name": windrow.name, "temperature_sites": {}}

        temperature_sites = Group.objects.filter(group2type__type__name="Temperature Site", child_group__parent_id=windrow.pk)

        for t_site in temperature_sites:
            nodes = Node.objects.filter(node2group__group_id=t_site.pk)

            if len(nodes) <= 1:
                # Do something
                new_windrow["temperature_sites"][t_site.pk] = {
                        "name": t_site.name,
                        "id": t_site.pk,
                        "parent_windrow_id": windrow.pk,
                        "assigned_probe": None if len(nodes) == 0 else nodes[0],
                        # TODO: Don't do N queries? Or is it cached effectively
                        "measurements": list(Measurement.objects.filter(associated_group=t_site)[:10]),
                        # TODO: Derive this information
                        "days_at_temperature": 0
                    }
            else:
                logging.fatal("Invariant not upheld: Multiple nodes in temperature site")

        result["windrows"][windrow.pk] = new_windrow


    return result

def get_staff_application_data():
    """
    Composes relationships into logical application format, across all data for staff viewing
    """
    result = {
        "sites": [],
    }

def get_site_view_context(site_id: int, selected_windrow_id: int = None, selected_temp_site_id: int = None):
    customer_data = get_customer_site_application_data(site_id)

    if customer_data is None:
        logging.warning(f"Get site view context: failed to get site data for site [{site_id}]")
        return None

    temperature_sites = []
    selected_windrow = None
    if selected_windrow_id is not None and len(customer_data["windrows"]) != 0:
        if selected_windrow_id in customer_data["windrows"]:
            selected_windrow = customer_data["windrows"][selected_windrow_id]
            temperature_sites = selected_windrow["temperature_sites"]



    selected_temp_site = None if selected_temp_site_id is None or len(temperature_sites) == 0 else temperature_sites[
        int(selected_temp_site_id)]

    context = {
        "customer": customer_data,
        "selected_windrow": selected_windrow,
        "windrow_temperature_sites": temperature_sites,
        "selected_temperature_site": selected_temp_site

    }
    return context