from pathlib import Path
import os
import importlib.util
import json
import inspect

route = None

def Importer(component_folder):
    """
    Sets the global route variable to the specified component folder.
    """
    try:
        with open(os.path.join(os.getcwd(), ".lillie/import_manifest.json"), "w") as f:
            json.dump({}, f)
    except Exception as e:
        os.makedirs(os.path.join(os.getcwd(), ".lillie"), exist_ok=True)
        with open(os.path.join(os.getcwd(), ".lillie/import_manifest.json"), "w") as f:
            json.dump({}, f)

    global route
    route = Path(os.path.join(os.getcwd(), component_folder))
    if not route.is_dir():
        raise ValueError(f"The specified component folder '{route}' does not exist or is not a directory.")

def _import(file, component):
    """
    Dynamically imports a module by file name and component name from the global route.
    """
    if route is None:
        raise ValueError("The route has not been set. Call 'Importer' first to set the component folder.")

    module_path = os.path.join(route, file)
    if not os.path.isfile(module_path):
        raise FileNotFoundError(f"The file '{module_path}' does not exist.")

    spec = importlib.util.spec_from_file_location(component, module_path)
    if spec is None:
        raise ImportError(f"Cannot create a spec for '{module_path}'.")

    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)  

    try:
        with open(os.path.join(os.getcwd(), ".lillie/import_manifest.json"), "r") as f:
            manifest = json.load(f)
        with open(os.path.join(os.getcwd(), ".lillie/import_manifest.json"), "w") as f:
            json.dump({**manifest, module_path: [inspect.stack()[1], component]}, f)
    except Exception as e:
        os.makedirs(os.path.join(os.getcwd(), ".lillie"), exist_ok=True)
        with open(os.path.join(os.getcwd(), ".lillie/import_manifest.json"), "w") as f:
            json.dump({**manifest, module_path: [inspect.stack()[1].filename, component]}, f)

    return getattr(module, component, None)  
