import { Effect, Either, Option } from "effect";
import { Fetch } from "fx-fetch";
import { toast } from "vue-sonner";
import { asRequest } from "../../../../share/request.js";
import { getLocalizedText } from "../../../../share/locale.js";
import { interpolateMarkdown } from "../../../../share/interpolate.js";
class HttpRequestHalted {
  constructor(reason) {
    this.reason = reason;
  }
  _tag = "HttpRequestHalted";
}
const TOAST_STYLES = /* @__PURE__ */ new Set(["success", "error", "warning", "info"]);
export const handler = (params, ctx) => {
  const { expression, resultExpression, titleExpression, description } = params ?? {};
  if (!expression || expression.trim().length === 0) return Effect.void;
  const program = Effect.gen(function* () {
    const steps = ctx.step?.outputs() ?? {};
    const evaluated = yield* ctx.cel(expression, { steps });
    const request = asRequest(evaluated);
    if (Option.isNone(request)) return;
    const outcome = yield* Effect.either(request.value.json());
    const json = Either.isRight(outcome) ? outcome.right : null;
    if (Either.isRight(outcome)) ctx.step?.publish(json);
    const result = Either.isLeft(outcome) ? "error" : resultExpression === void 0 ? "success" : yield* ctx.cel(resultExpression, { json, steps });
    const kind = TOAST_STYLES.has(result) ? result : "success";
    if (titleExpression !== void 0) {
      const title = yield* ctx.cel(titleExpression, { json, result, steps });
      if (title.length > 0) {
        const raw = getLocalizedText(description, ctx.locale()) ?? "";
        const body = raw.length === 0 ? void 0 : interpolateMarkdown(raw, ctx.cel, { json, result, steps });
        toast[kind](title, body === void 0 ? void 0 : { description: body });
      }
    }
    if (Either.isLeft(outcome)) {
      if (import.meta.dev) console.warn("[shwfed-operations] http request failed", outcome.left);
      return yield* Effect.die(new HttpRequestHalted(outcome.left));
    }
    if (kind === "error") return yield* Effect.die(new HttpRequestHalted("error result"));
  });
  return program.pipe(
    // The bus's handler contract has no requirements channel, so the host
    // can't thread a Fetch layer through — the op provides its own, same layer
    // the button runner uses.
    Effect.provide(Fetch.layer),
    // What remains on the error channel is CEL evaluation failure (request /
    // result / title expression) — a config bug, not a runtime outcome. Mirror
    // the button runner: silent in prod, console in dev; the chain still
    // halts so later requests don't fire off a broken step.
    Effect.catchAll((error) => Effect.zipRight(
      Effect.sync(() => {
        if (import.meta.dev) console.warn("[shwfed-operations] http request op failed", error);
      }),
      Effect.die(new HttpRequestHalted(error))
    ))
  );
};
