import { Effect, Schema } from "effect";
import { Expression, LocaleMarkdown } from "../../../../../share/expression.js";
import { Locale } from "../../../../../share/locale.js";
import { interpolateMarkdown } from "../../../../table/utils/runtime.js";
import { commonFieldFields, derivedField, FieldOrientationSchema } from "../../../utils/common.js";
export const type = "com.shwfed.form.field.combobox.single";
export const compatibilityDate = "2026-04-29";
export const metadata = {
  name: "\u4E0B\u62C9\u5355\u9009\uFF08\u786C\u7F16\u7801\uFF09",
  icon: "fluent:chevron-down-20-regular",
  w: { initial: 8, min: 4, max: Infinity },
  h: { initial: 2, min: 2, max: 2 }
};
export function itemSchema(configure) {
  const LocaleMd = LocaleMarkdown({ configure });
  const TextValue = Schema.Struct({
    kind: Schema.Literal("text"),
    value: Schema.String
  });
  const NumberValue = Schema.Struct({
    kind: Schema.Literal("number"),
    value: Schema.Number
  });
  const ItemValue = Schema.Union(TextValue, NumberValue).annotations({
    title: "\u503C",
    description: "\u9009\u9879\u7ED1\u5B9A\u7684\u503C\uFF0C\u53EF\u4EE5\u662F\u6587\u672C\u6216\u6570\u5B57"
  });
  return Schema.Struct({
    id: Schema.UUID.annotations({ description: "\u9009\u9879\u552F\u4E00\u6807\u8BC6\uFF0C\u7528\u4E8E\u7A33\u5B9A\u7684 v-for key" }),
    label: LocaleMd.annotations({
      title: "\u6807\u7B7E",
      description: "\u9009\u9879\u5C55\u793A\u7684\u672C\u5730\u5316\u6587\u672C\uFF0C\u652F\u6301 Markdown \u4E0E `{{ form.foo }}` \u63D2\u503C"
    }),
    value: ItemValue,
    tooltip: Schema.optional(LocaleMd.annotations({
      title: "\u63D0\u793A",
      description: "\u9F20\u6807\u60AC\u505C\u5728\u9009\u9879\u4E0A\u65F6\u5C55\u793A\u7684\u672C\u5730\u5316\u63D0\u793A\uFF0C\u652F\u6301 Markdown"
    }))
  }).annotations({
    title: "ComboboxSingleItem"
  });
}
export function schema(configure) {
  const CelBool = Expression({ configure, resultType: "bool" });
  const Item = itemSchema(configure);
  return Schema.Struct({
    type: Schema.Literal(type),
    compatibilityDate: Schema.Literal(compatibilityDate),
    ...commonFieldFields(configure),
    label: Schema.optional(Locale.annotations({
      title: "\u6807\u7B7E",
      description: "\u5B57\u6BB5\u524D\u5C55\u793A\u7684\u6587\u672C\uFF1B\u7559\u7A7A\u5219\u4E0D\u6E32\u67D3\u6807\u7B7E"
    })),
    placeholder: Schema.optional(Locale.annotations({
      title: "\u5360\u4F4D\u7B26",
      description: "\u672A\u9009\u4E2D\u4EFB\u4F55\u9009\u9879\u65F6\u8F93\u5165\u6846\u4E2D\u7684\u5360\u4F4D\u6587\u672C"
    })),
    tooltip: Schema.optional(Locale.annotations({
      title: "\u63D0\u793A",
      description: "\u9F20\u6807\u60AC\u505C\u5728\u6807\u7B7E\u4E0A\u65F6\u5C55\u793A\u7684\u8BF4\u660E"
    })),
    orientation: Schema.optional(FieldOrientationSchema),
    binding: Schema.optional(Schema.String.pipe(Schema.minLength(1)).annotations({
      title: "\u7ED1\u5B9A\u8DEF\u5F84",
      description: "\u5199\u5165\u8868\u5355\u72B6\u6001\u7684 `dot-prop` \u8DEF\u5F84\uFF0C\u4F8B\u5982 `user.role`\uFF1B\u7559\u7A7A\u5219\u4E3A\u975E\u53D7\u63A7\u5B57\u6BB5"
    })),
    disabled: Schema.optional(CelBool.annotations({
      title: "\u7981\u7528\u6761\u4EF6",
      description: "\u8FD4\u56DE `true` \u65F6\u4E0B\u62C9\u6846\u4ECD\u7136\u6E32\u67D3\u4F46\u4E0D\u53EF\u9009\u62E9"
    })),
    readonly: Schema.optional(CelBool.annotations({
      title: "\u53EA\u8BFB\u6761\u4EF6",
      description: "\u8FD4\u56DE `true` \u65F6\u4EC5\u4EE5\u7EAF\u6587\u672C\u5C55\u793A\u5F53\u524D\u9009\u9879\u7684\u6807\u7B7E"
    })),
    derived: derivedField(configure, "dyn"),
    items: Schema.optionalWith(Schema.Array(Item).annotations({
      title: "\u9009\u9879",
      description: "\u4E0B\u62C9\u6846\u53EF\u9009\u9879\u5217\u8868"
    }), { default: () => [] })
  }).annotations({
    title: "ComboboxSingleField",
    description: "\u4E0B\u62C9\u5355\u9009\u8F93\u5165"
  });
}
function newId() {
  return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
    const r = Math.random() * 16 | 0;
    const v = c === "x" ? r : r & 3 | 8;
    return v.toString(16);
  });
}
function formatErrorMessage(err) {
  if (err instanceof Error) return err.message;
  if (typeof err === "string") return err;
  try {
    return JSON.stringify(err);
  } catch {
    return String(err);
  }
}
export const migrate = (prev, ctx) => {
  const legacy = prev;
  return Effect.gen(function* () {
    const rawOptions = yield* Effect.mapError(
      ctx.$cel(legacy.options, { form: {} }),
      (err) => new Error(`\u9009\u9879\u8868\u8FBE\u5F0F\u6C42\u503C\u5931\u8D25\uFF1A${formatErrorMessage(err)}`)
    );
    if (!Array.isArray(rawOptions)) {
      return yield* Effect.fail(new Error(
        `\u9009\u9879\u8868\u8FBE\u5F0F\u672A\u8FD4\u56DE\u5217\u8868\uFF08\u5B9E\u9645\u4E3A ${typeof rawOptions}\uFF09`
      ));
    }
    const items = [];
    for (const option of rawOptions) {
      const v = yield* Effect.mapError(
        ctx.$cel(legacy.optionValue, { form: {}, option }),
        (err) => new Error(`\u9009\u9879\u503C\u8868\u8FBE\u5F0F\u6C42\u503C\u5931\u8D25\uFF1A${formatErrorMessage(err)}`)
      );
      let labelMessages;
      try {
        labelMessages = legacy.optionLabel.map(({ locale, message }) => ({
          locale,
          message: interpolateMarkdown(message, ctx.$cel, { form: {}, option })
        }));
      } catch (err) {
        return yield* Effect.fail(new Error(`\u9009\u9879\u6807\u7B7E\u63D2\u503C\u5931\u8D25\uFF1A${formatErrorMessage(err)}`));
      }
      const value = typeof v === "number" && Number.isFinite(v) ? { kind: "number", value: v } : { kind: "text", value: v == null ? "" : String(v) };
      items.push({ id: newId(), label: labelMessages, value });
    }
    const {
      options: _options,
      optionValue: _optionValue,
      optionLabel: _optionLabel,
      compatibilityDate: _legacyDate,
      ...carryover
    } = legacy;
    return {
      ...carryover,
      compatibilityDate,
      items
    };
  });
};
