<svelte:options customElement={{ props: {} }} />

<script lang="ts">
  import NodeWrapper from '../core/NodeWrapper.svelte';
  import {type NodeProps, useNodesData, useSvelteFlow} from '@xyflow/svelte';
  import {Button, Heading, Select} from '../base';
  import RefParameterList from '../core/RefParameterList.svelte';
  import {getCurrentNodeId, getOptions} from '#components/utils/NodeUtils';
  import {useAddParameter} from '../utils/useAddParameter.svelte';
  import OutputDefList from '../core/OutputDefList.svelte';
  import {onMount} from 'svelte';
  import type {SelectItem, TinyflowNodeData} from '#types';
  import CodeScriptEditor from '../core/CodeScriptEditor.svelte';

  const { data, ...rest }: {
        data: TinyflowNodeData,
        [key: string]: any
    } = $props();

    const currentNodeId = getCurrentNodeId();
    const options = getOptions();
    let currentNode = useNodesData(currentNodeId);
    const { addParameter } = useAddParameter();
    const { updateNodeData } = useSvelteFlow();
    const codeNodeHelp = `结果如何返回
- 请把代码执行结果写到 _result 中。
- JS：_result.answer = 'ok'
- Python：_result['answer'] = 'ok'

输出参数如何配置
- 在“输出参数”中新增字段（如 answer、score）。
- 字段名建议与 _result 的 key 保持一致，便于下游节点引用。
- 下游节点可引用：代码节点ID.输出参数名。

示例
- 代码里写：
  _result.answer = '你好';
  _result.score = 95;
- 输出参数配置：answer(String)、score(Number)
- 结束节点输出参数可引用：代码节点ID.answer、代码节点ID.score`;

    const editorParameters = $derived.by(() => {
        return (currentNode?.current?.data?.parameters as Array<any>) || data.parameters || [];
    });

    let engines = $state<SelectItem[]>([
        { label: 'JavaScript', value: 'js' }
    ]);
    const defaultEngine = $derived.by(() => {
        const firstAvailable = engines.find((item) => item.selectable !== false);
        return firstAvailable?.value || 'js';
    });

    onMount(async () => {
        const codeEngines = await options.provider?.codeEngine?.();
        if (codeEngines && codeEngines.length > 0) {
            engines = codeEngines;
        }

        const currentEngine = data.engine;
        const currentEngineSupported = engines.some((item) => item.value === currentEngine && item.selectable !== false);
        if (!currentEngine || !currentEngineSupported) {
            updateNodeData(currentNodeId, () => {
                return {
                    engine: defaultEngine
                };
            });
        }
    });


</script>


<NodeWrapper
    {data}
    titleHelp={codeNodeHelp}
    {...rest}
>

    {#snippet icon()}
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
            <path
                d="M23 12L15.9289 19.0711L14.5147 17.6569L20.1716 12L14.5147 6.34317L15.9289 4.92896L23 12ZM3.82843 12L9.48528 17.6569L8.07107 19.0711L1 12L8.07107 4.92896L9.48528 6.34317L3.82843 12Z"></path>
        </svg>
    {/snippet}

    <div class="heading">
        <Heading level={3}>输入参数</Heading>
        <Button class="input-btn-more" style="margin-left: auto" onclick={()=>{
            addParameter(currentNodeId)
        }}>
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
                <path d="M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z"></path>
            </svg>
        </Button>
    </div>
    <RefParameterList />

    <Heading level={3} mt="10px">代码</Heading>
    <div class="setting-title">执行引擎</div>
    <div class="setting-item">
        <Select items={engines} style="width: 100%" placeholder="请选择执行引擎" onSelect={(item)=>{
              const newValue = item.value;
              updateNodeData(currentNodeId, ()=>{
                  return {
                      engine: newValue
                  }
              })
        }} value={data.engine ? [data.engine] : [defaultEngine]} />
    </div>

    <div class="setting-title">执行代码</div>
    <div class="setting-item">
        <CodeScriptEditor
                  mode="textarea"
                  rows={10}
                  placeholder="请输入执行代码，注：输出内容需添加到_result中，如：_result['key'] = value 或者 _result.key = value"
                  style="width: 100%"
                  engine={(data.engine as string) || (defaultEngine as string)}
                  parameters={editorParameters}
                  oninput={(e:any)=>{
            updateNodeData(currentNodeId, ()=>{
                return {
                    code: e.target.value
                }
            })
        }}
                  value={data.code as string||""}
        />
    </div>


    <div class="heading">
        <Heading level={3} mt="10px">输出参数</Heading>
        <Button class="input-btn-more" style="margin-left: auto" onclick={()=>{
            addParameter(currentNodeId,'outputDefs')
        }}>
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
                <path d="M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z"></path>
            </svg>
        </Button>
    </div>
    <OutputDefList />

</NodeWrapper>

<style>
    .heading {
        display: flex;
        margin-bottom: 10px;
    }

    .setting-title {
        font-size: 12px;
        color: var(--tf-text-muted);
        margin-bottom: 4px;
        margin-top: 10px;
    }

    .setting-item {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 10px;
        gap: 10px;
    }

</style>
