import { computed, inject, provide, shallowRef } from "vue";
import { Effect, Schema } from "effect";
export const Trigger = Schema.Struct({
  target: Schema.UUID.annotations({
    description: "\u76EE\u6807\u7956\u5148\u5B9E\u4F8B\u7684 ID"
  }),
  operation: Schema.String.annotations({
    description: "\u76EE\u6807\u7EC4\u4EF6\u80FD\u529B\u6E05\u5355\u4E2D\u7684\u64CD\u4F5C ID"
  })
}).annotations({
  title: "Trigger",
  description: "\u4E00\u6761\u5411\u4E0A\u5192\u6CE1\u7684\u64CD\u4F5C\u8BF7\u6C42"
});
export const Triggers = Schema.Array(Trigger).annotations({
  title: "\u89E6\u53D1\u64CD\u4F5C",
  description: "\u6309\u5217\u8868\u987A\u5E8F\u6267\u884C"
});
export const EVENT_CHANNEL_KEY = Symbol("shwfed/event-channel");
export function createEventChannel(instanceId, operations, parent) {
  return {
    dispatch(request) {
      const handled = request.target === instanceId ? operations[request.operation]?.() ?? Effect.void : Effect.void;
      return parent ? Effect.andThen(handled, parent.dispatch(request)) : handled;
    }
  };
}
export function provideEventTarget(instanceId, operations) {
  const parent = inject(EVENT_CHANNEL_KEY, void 0);
  provide(EVENT_CHANNEL_KEY, createEventChannel(instanceId, operations, parent));
}
export function useEventChannel() {
  return inject(EVENT_CHANNEL_KEY, void 0);
}
export function dispatchTriggers(channel, triggers) {
  if (!channel || !triggers || triggers.length === 0) return Effect.void;
  return Effect.forEach(
    triggers,
    (trigger) => channel.dispatch({ target: trigger.target, operation: trigger.operation }),
    { discard: true }
  );
}
const EVENT_ANCESTRY_KEY = Symbol("shwfed/event-ancestry");
export function provideEventAncestor(ancestor) {
  const parent = inject(EVENT_ANCESTRY_KEY, void 0);
  provide(
    EVENT_ANCESTRY_KEY,
    computed(() => {
      const chain = parent?.value ?? [];
      return ancestor.value ? [ancestor.value, ...chain] : chain;
    })
  );
}
export function useEventAncestry() {
  return inject(EVENT_ANCESTRY_KEY, void 0) ?? shallowRef([]);
}
