{% set assign=true %}
{% set signal=true %}
{% set resolve=true %}

{% import "src/default/types/block.js.njk" as block with context %}

{% call block.header() %}
  {% if childs.length %}
    {% if not childs[0].definition.dynamic %}
      // FIRST CHILD: {{childs[0].indexKey}}
      import {{childs[0].codeKey}} from "./{{childs[0].codeKey}}.js";
    {% endif %}
  {% endif%}
{% endcall %}

{% call block.definition() %}

  {% if childs.length %}
    {% if childs[0].definition.dynamic %}
      // FIRST CHILD: {{childs[0].indexKey}}
      const { default: {{childs[0].codeKey}} } = await import("./{{childs[0].codeKey}}.js");
    {% endif %}
  {% endif%}

  for await(const {{context.transform.for.as | safe}} of {{context.transform.for.in | safe}}){
    // Create Proxy for closure-like variable resolution
    // Local variable shadows parent, but parent scope accessible via Proxy fallback
    const localForVar = { {{context.transform.for.as | safe}}: {{context.transform.for.as | safe}} };
    const forProxy = new Proxy(localForVar, {
      get(target, prop) {
        // Check local scope first (shadowing)
        if (prop in target) return target[prop];
        // Fallback to parent scope
        return c.for?.[prop];
      }
    });

    // Create new context with updated for
    const loopContext = { ...c, for: forProxy };

    {% if childs.length %}
      let current= new {{childs[0].codeKey}}({ parent:_this, engine, flow, caller:loopContext  });
      let currentArgs=args;

      do {

        {% if workflow.parent.context.atom.doc.features.print_runners %}
          console.log(new Date().toLocaleString(),' * ',_this.constructor.IndexKey,' -> ',current.constructor.IndexKey);
        {% endif %}

        const nextBlock= typeof currentArgs==='undefined'? await current.run()
          : Array.isArray(currentArgs)? await current.run.apply(current,currentArgs) : await current.run(currentArgs) ;

        if(nextBlock?.type==='return') return resolve(nextBlock);
        else if(nextBlock?.type!=='block') break;

        if(nextBlock.toType.ParentTypeId!==_this.constructor.TypeId)
          return resolve(nextBlock);

        current=new nextBlock.toType({ parent:_this, engine, flow, caller:loopContext, error });
        currentArgs=nextBlock.input;

      } while(true);

    {% endif %}
  }

{% endcall %}

{% call block.footer()%} 
{% endcall %}