<script setup>
import { Effect } from "effect";
import { createDefu } from "defu";
import { cel as _rawCel } from "../../../../../utils/cel";
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
import { dispatchTriggers, useEventChannel } from "../../../../../share/event-bus";
import { useFormState } from "../../../../form/utils/state";
import ShwfedActionDefinition from "../../../components/definition.vue";
defineOptions({ name: "ShwfedStateWriteActionRuntime" });
const props = defineProps({
  buttonId: { type: String, required: true },
  config: { type: null, required: true }
});
const inherited = injectCELContext();
const $cel = (expression, context) => _rawCel(expression, { ...celBindings(inherited), ...context });
const nearestFormState = useFormState();
const formState = nearestFormState.kind === "form" && nearestFormState.parent ? nearestFormState.parent : nearestFormState;
const channel = useEventChannel();
const mergeObjects = createDefu((obj, key, value) => {
  if (Array.isArray(obj[key]) && Array.isArray(value)) {
    obj[key] = value;
    return true;
  }
});
function isPlainObject(v) {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}
function mergeAtKey(current, next) {
  if (isPlainObject(current) && isPlainObject(next)) {
    return mergeObjects({ ...next }, current);
  }
  return next;
}
const effect = Effect.suspend(
  () => Effect.flatMap(
    $cel(props.config.expression),
    (result) => {
      for (const key of Object.keys(result)) {
        const merged = mergeAtKey(formState.getAt(key), result[key]);
        formState.setAt(key, merged);
      }
      return dispatchTriggers(channel, props.config.onSuccess, $cel);
    }
  )
);
</script>

<template>
  <ShwfedActionDefinition
    :action-id="buttonId"
    :effect="effect"
  />
</template>
