<script setup>
import { computed, ref } from "vue";
import { Effect } from "effect";
import { Fetch } from "fx-fetch";
import { toast } from "vue-sonner";
import { cel as $cel } from "../../../../../utils/cel";
import { Switch } from "../../../../ui/switch";
import { JUSTIFY_CLASS } from "../../../utils/runtime";
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
import { dispatchTriggers, useEventChannel } from "../../../../../share/event-bus";
defineOptions({ name: "ShwfedTableSwitchRendererRuntime" });
const props = defineProps({
  column: { type: null, required: true },
  ctx: { type: Object, required: true }
});
const celContext = injectCELContext();
const eventChannel = useEventChannel();
const rawValue = computed(() => props.ctx.cell.getValue());
const isMissing = computed(() => rawValue.value === void 0 || rawValue.value === null);
const checked = computed(() => rawValue.value === true);
const justifyClass = computed(
  () => JUSTIFY_CLASS[props.column.align ?? "center"] ?? JUSTIFY_CLASS.center
);
const pending = ref(false);
const isDisabledByConfig = computed(() => {
  if (!props.column.disabled) return false;
  try {
    return Effect.runSync($cel(props.column.disabled, celBindings(celContext))) === true;
  } catch (e) {
    console.error("[shwfed-table] switch disabled failed", e);
    return false;
  }
});
const isInteractive = computed(() => !!props.column.onChange);
const isDisabled = computed(() => !isInteractive.value || isDisabledByConfig.value || pending.value);
async function onUpdate(next) {
  const { onChange, successMessage } = props.column;
  if (!onChange) return;
  pending.value = true;
  const program = Effect.gen(function* () {
    const builder = yield* $cel(onChange, {
      ...celBindings(celContext),
      value: next
    });
    return yield* builder.json();
  });
  try {
    const body = await Effect.runPromise(Effect.provide(program, Fetch.layer));
    if (successMessage) {
      try {
        const message = Effect.runSync($cel(successMessage, { json: body }));
        if (message) toast.success(message);
      } catch (e) {
        console.error("[shwfed-table] switch successMessage failed", e);
      }
    }
    await Effect.runPromise(dispatchTriggers(eventChannel, props.column.triggers));
  } catch (e) {
    console.error("[shwfed-table] switch onChange failed", e);
    toast.error("\u8BF7\u6C42\u5931\u8D25");
  } finally {
    pending.value = false;
  }
}
</script>

<template>
  <span :class="['w-full py-2 px-1 flex items-center text-xs', justifyClass]">
    <span
      v-if="isMissing"
      class="font-mono text-zinc-300 select-none"
    >-</span>
    <Switch
      v-else
      size="sm"
      :model-value="checked"
      :disabled="isDisabled"
      @update:model-value="(v) => onUpdate(v)"
    />
  </span>
</template>
