# --------------------------------------- 
# MCM routing & configuration engine 
# --------------------------------------- 
# 
# This module provides routing and configuration management for MCM (Material Control Module) views.
# 
# Key Functions:
# - getMcm(fc, mcm): Retrieves MCM configuration from PLC tags
# - getArea(fc, mcm): Returns the primary area name for an MCM
# - getSubAreas(fc, mcm): Returns list of sub-area names for an MCM
# - buildViewPath(fc, mcm, subArea): Constructs view path strings in format "DetailedView/{mcm} {view}"
# - handleIsFound(view, value): Chains navigation through area/sub-area views until device is found
# 
# Navigation Chain:
# When a device is not found in the current view, handleIsFound automatically navigates to the next 
# available view in this sequence: Area -> SubArea[0] -> SubArea[1] -> ... -> SubArea[n]
# The chain stops when the device is found or all views have been searched.
# 

import json 

# --------------------------------------- 
# CONFIG ACCESS 
# --------------------------------------- 

def _getPlcConfigTag(fc): 
    if not fc: 
        return None 
    return "[%s_SCADA_TAG_PROVIDER]/Configuration/PLC" % fc 


def _readConfig(fc): 
    tag_path = _getPlcConfigTag(fc) 
    if not tag_path: 
        return {} 

    res = system.tag.readBlocking([tag_path])[0] 
    if not res.quality.isGood() or not res.value: 
        return {} 

    try: 
        return json.loads(res.value) 
    except: 
        return {} 


def getMcm(fc, mcm): 
    return _readConfig(fc).get(mcm) 


def getArea(fc, mcm): 
    cfg = getMcm(fc, mcm) 
    if not cfg: 
        return None 
    return cfg.get("Area") 


def getSubAreas(fc, mcm): 
    cfg = getMcm(fc, mcm) 
    if not cfg: 
        return [] 
    return cfg.get("SubAreas", []) or [] 


# --------------------------------------- 
# VIEW PATH CONTRACT 
# --------------------------------------- 

def buildViewPath(fc, mcm, subArea=None): 
    area = getArea(fc, mcm) 
    if not area: 
        return None 

    view_name = subArea if subArea else area
    
    return "DetailedView/{} {}".format(mcm, view_name)

# --------------------------------------- 
# CHAIN HANDLER 
# --------------------------------------- 

def handleIsFound(view, value): 
    device = view.params.selectDevice or "" 
    if not device: 
        return 
    
    found_status = str(value).replace(device, "").strip() 
    
    if found_status not in ("TRUE", "FALSE"):
        return 
    
    if found_status == "TRUE": 
        return 
    
    current_view_path = view.page.props.primaryView or "" 
    
    mcm = view.params.mcm 
    fc = view.session.custom.fc
    
    if not mcm or not fc: 
        return 
    
    area = getArea(fc, mcm) 
    subareas = getSubAreas(fc, mcm) or [] 
    
    if not area: 
        return 
    
    area_view_path = buildViewPath(fc, mcm, None) 
    
    if current_view_path == area_view_path: 
        if len(subareas) > 0: 
            next_view = buildViewPath(fc, mcm, subareas[0]) 
            if next_view: 
                system.perspective.navigate( 
                    view=next_view, 
                    params={ 
                        "selectDevice": device, 
                        "mcm": mcm 
                    } 
                ) 
        else: 
            system.perspective.print( 
                "Device '{}' not found in {} Area and no SubAreas to search".format(device, mcm) 
            ) 
    else: 
        path_parts = current_view_path.split("/")
        
        if len(path_parts) >= 2:
            last_part = path_parts[-1]
            view_parts = last_part.split(" ", 1)
            
            if len(view_parts) >= 2:
                current_subarea = view_parts[1]
            else:
                current_subarea = None
        else:
            current_subarea = None
        
        if current_subarea and current_subarea in subareas: 
            current_index = subareas.index(current_subarea) 
            next_index = current_index + 1 
            
            if next_index < len(subareas): 
                next_subarea = subareas[next_index] 
                next_view = buildViewPath(fc, mcm, next_subarea) 
                if next_view: 
                    system.perspective.navigate( 
                        view=next_view, 
                        params={ 
                            "selectDevice": device, 
                            "mcm": mcm 
                        } 
                    ) 
            else: 
                system.perspective.print( 
                    "Device '{}' not found in {} (searched all SubAreas)".format(device, mcm) 
                ) 
        else: 
            system.perspective.print( 
                "Could not determine current SubArea from path: {} (extracted: {})".format(current_view_path, current_subarea) 
            )