import { I_Node } from '@fangzhou/compiler-js';
import React, { FC } from 'react';
import { View, StyleSheet } from 'react-native';
import { useObservable, useComponent } from '@fangzhou/rxui-lite';
import css from './style';

export function RenderCom({
  node,
  comDefs,
  env,
  slotIo,
  rtMaps,
  events,
  layoutComs,
}: {
  node: {} & I_Node;
  comDefs;
  env;
  slotIo: any;
  rtMaps: {};
  events: any;
  layoutComs: {
    Wrapper: FC;
    Slot: FC;
  };
}) {
  const { slots: comSlots, parent, def, id, model, title } = node;
  const rtType = def.rtType;

  if (rtType && rtType.match(/js/gi)) {
    //逻辑组件
    return;
  }
  const nodeModel = model;
  const style = useObservable(nodeModel.style);
  const data = useObservable(nodeModel.data);

  const comDefsKey = def.namespace + '@' + def.version;

  const ComRuntime = comDefs[comDefsKey];
  const rt = rtMaps[id];

  const { inputs, outputs, fork } = rt.io;
  let nInputs = inputs,
    nOutputs = outputs;
  // 当slot有io时，rt.io里merge slotIo的输入输出，参考designer的debugrunner里render代码
  if (inputs && slotIo?.inputs) {
    nInputs = fork('inputs', slotIo.inputs);
  }
  if (outputs && slotIo?.outputs) {
    nOutputs = fork('outputs', slotIo.outputs);
  }

  const slots = {};
  const Slot = layoutComs.Slot;
  const Wrapper = layoutComs.Wrapper;
  if (comSlots) {
    comSlots.forEach((slot) => {
      slots[slot.id] = {
        id: slot.id,
        title: slot.title,
        //comAry:slot.comAry,
        render(...args) {
          const { frames } = rtMaps[id];
          let frame;
          for (let fid in frames) {
            frame = frames[fid];
            delete frames[fid];
          }

          if (frame && args[1]) {
            frame(void 0, node.id);
          }
          const fn = frames[slot.id];
          if (typeof fn === 'function') {
            fn(); //兼容之前的非框图
          }
          const comAry = slot.comAry || [];
          return (
            <Slot slot={slot}>
              {comAry.map((com) => {
                return (
                  <RenderCom
                    events={events}
                    slotIo={args[0]}
                    key={com.id}
                    node={com}
                    comDefs={comDefs}
                    env={env}
                    rtMaps={rtMaps}
                    layoutComs={layoutComs}
                  />
                );
              })}
            </Slot>
          );
        },
        get size() {
          return slot.comAry?.length || 0;
        },
      };
    });
  }

  const Render = useComponent(() => {
    return (
      <Wrapper
        id={id}
        title={title}
        node={node}
        style={style}
        parent={parent}
      >
        <ComRuntime
          slots={slots}
          env={env}
          data={data}
          title={title}
          style={style}
          inputs={nInputs}
          outputs={nOutputs}
          events={events}
        />
      </Wrapper>
    );
  });
  return <Render />;
}
