import { useCallback, useMemo } from 'react' import produce from 'immer' import { useStoreApi } from 'reactflow' import { isEqual } from 'lodash-es' import { VarType } from '../../types' import type { ValueSelector, Var } from '../../types' import { type AssignerNodeType, WriteMode } from './types' import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' import { useIsChatMode, useNodesReadOnly, useWorkflow, useWorkflowVariables, } from '@/app/components/workflow/hooks' const useConfig = (id: string, payload: AssignerNodeType) => { const { nodesReadOnly: readOnly } = useNodesReadOnly() const isChatMode = useIsChatMode() const store = useStoreApi() const { getBeforeNodesInSameBranch } = useWorkflow() const { getNodes, } = store.getState() const currentNode = getNodes().find(n => n.id === id) const isInIteration = payload.isInIteration const iterationNode = isInIteration ? getNodes().find(n => n.id === currentNode!.parentId) : null const availableNodes = useMemo(() => { return getBeforeNodesInSameBranch(id) }, [getBeforeNodesInSameBranch, id]) const { inputs, setInputs } = useNodeCrud(id, payload) const { getCurrentVariableType } = useWorkflowVariables() const assignedVarType = getCurrentVariableType({ parentNode: iterationNode, valueSelector: inputs.assigned_variable_selector || [], availableNodes, isChatMode, isConstant: false, }) const isSupportAppend = useCallback((varType: VarType) => { return [VarType.arrayString, VarType.arrayNumber, VarType.arrayObject].includes(varType) }, []) const isCurrSupportAppend = useMemo(() => isSupportAppend(assignedVarType), [assignedVarType, isSupportAppend]) const handleAssignedVarChanges = useCallback((variable: ValueSelector | string) => { const newInputs = produce(inputs, (draft) => { draft.assigned_variable_selector = variable as ValueSelector draft.input_variable_selector = [] const newVarType = getCurrentVariableType({ parentNode: iterationNode, valueSelector: draft.assigned_variable_selector || [], availableNodes, isChatMode, isConstant: false, }) if (inputs.write_mode === WriteMode.Append && !isSupportAppend(newVarType)) draft.write_mode = WriteMode.Overwrite }) setInputs(newInputs) }, [inputs, setInputs, getCurrentVariableType, iterationNode, availableNodes, isChatMode, isSupportAppend]) const writeModeTypes = [WriteMode.Overwrite, WriteMode.Append, WriteMode.Clear] const handleWriteModeChange = useCallback((writeMode: WriteMode) => { return () => { const newInputs = produce(inputs, (draft) => { draft.write_mode = writeMode if (inputs.write_mode === WriteMode.Clear) draft.input_variable_selector = [] }) setInputs(newInputs) } }, [inputs, setInputs]) const toAssignedVarType = useMemo(() => { const { write_mode } = inputs if (write_mode === WriteMode.Overwrite) return assignedVarType if (write_mode === WriteMode.Append) { if (assignedVarType === VarType.arrayString) return VarType.string if (assignedVarType === VarType.arrayNumber) return VarType.number if (assignedVarType === VarType.arrayObject) return VarType.object } return VarType.string }, [assignedVarType, inputs]) const filterAssignedVar = useCallback((varPayload: Var, selector: ValueSelector) => { return selector.join('.').startsWith('conversation') }, []) const filterToAssignedVar = useCallback((varPayload: Var, selector: ValueSelector) => { if (isEqual(selector, inputs.assigned_variable_selector)) return false if (inputs.write_mode === WriteMode.Overwrite) { return varPayload.type === assignedVarType } else if (inputs.write_mode === WriteMode.Append) { switch (assignedVarType) { case VarType.arrayString: return varPayload.type === VarType.string case VarType.arrayNumber: return varPayload.type === VarType.number case VarType.arrayObject: return varPayload.type === VarType.object default: return false } } return true }, [inputs.assigned_variable_selector, inputs.write_mode, assignedVarType]) const handleToAssignedVarChange = useCallback((value: ValueSelector | string) => { const newInputs = produce(inputs, (draft) => { draft.input_variable_selector = value as ValueSelector }) setInputs(newInputs) }, [inputs, setInputs]) return { readOnly, inputs, handleAssignedVarChanges, assignedVarType, isSupportAppend: isCurrSupportAppend, writeModeTypes, handleWriteModeChange, filterAssignedVar, filterToAssignedVar, handleToAssignedVarChange, toAssignedVarType, } } export default useConfig