<script setup>
import { computed } from "vue";
import { ExpressionEditor } from "../../../../ui/expression-editor";
import DerivedValueEditor from "../../../DerivedValueEditor.vue";
import ValidationRulesField from "../../../ValidationRulesField.vue";
import { Field, FieldLabel } from "../../../../ui/field";
import { InputGroup, InputGroupInput } from "../../../../ui/input-group";
import { Locale as LocaleField } from "../../../../ui/locale";
import { Markdown } from "../../../../ui/markdown";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from "../../../../ui/select";
import { Switch } from "../../../../ui/switch";
import { getStructFieldDescription, getStructFieldTitle } from "../../../schema";
import { DataSource } from "../../../../table/schema";
import { schema } from "./schema";
defineOptions({ name: "ShwfedTreeMultiFieldConfig" });
const value = defineModel({ type: null, ...{ required: true } });
const fieldSchema = schema(() => {
});
const fieldTitle = (f) => getStructFieldTitle(fieldSchema, f) ?? f;
const fieldDescription = (f) => getStructFieldDescription(fieldSchema, f);
const dataSourceSchema = DataSource(() => {
});
const dataSourceFieldTitle = (f) => getStructFieldTitle(dataSourceSchema, f) ?? f;
const dataSourceFieldDescription = (f) => getStructFieldDescription(dataSourceSchema, f);
const filterSchema = fieldSchema.fields.filter.from;
const filterFieldTitle = (f) => getStructFieldTitle(filterSchema, f) ?? f;
const filterFieldDescription = (f) => getStructFieldDescription(filterSchema, f);
const nodeExtraVars = {
  node: {
    type: "dyn",
    label: "\u5F53\u524D\u8282\u70B9",
    description: "\u7531 `\u6570\u636E` \u8868\u8FBE\u5F0F\u8FD4\u56DE\u7684\u6BCF\u4E00\u9879\uFF1B\u7C7B\u578B\u5728\u914D\u7F6E\u65F6\u672A\u77E5\uFF08`dyn`\uFF09"
  }
};
const jsonExtraVars = {
  json: {
    type: "optional<dyn>",
    label: "HTTP \u54CD\u5E94\u4F53",
    description: "\u5DF2\u89E3\u6790\u7684 JSON \u54CD\u5E94\uFF1B\u672A\u914D\u7F6E `request` \u65F6\u4E3A `none`"
  }
};
const bindingText = computed({
  get: () => value.value.binding ?? "",
  set: (next) => {
    const trimmed = next.trim();
    if (trimmed.length === 0) {
      const { binding: _omit, ...rest } = value.value;
      value.value = rest;
    } else {
      value.value = { ...value.value, binding: trimmed };
    }
  }
});
const CASCADE_OPTIONS = [
  { value: "independent", label: "\u72EC\u7ACB" },
  { value: "cascade-down", label: "\u5411\u4E0B\u7EA7\u8054" },
  { value: "cascade-both", label: "\u53CC\u5411\u7EA7\u8054" }
];
function setDataSourceData(next) {
  value.value = {
    ...value.value,
    dataSource: { ...value.value.dataSource, data: next }
  };
}
function setDataSourceRequest(next) {
  const trimmed = next.trim();
  if (trimmed.length === 0) {
    const { request: _omit, ...rest } = value.value.dataSource;
    value.value = { ...value.value, dataSource: rest };
  } else {
    value.value = {
      ...value.value,
      dataSource: { ...value.value.dataSource, request: next }
    };
  }
}
function setOptionalExpression(key, next) {
  if (next.length === 0) {
    const { [key]: _omit, ...rest } = value.value;
    value.value = rest;
  } else {
    value.value = { ...value.value, [key]: next };
  }
}
const filter = computed(() => value.value.filter);
function setFilterEnabled(next) {
  if (next) {
    value.value = {
      ...value.value,
      filter: { ...value.value.filter ?? {}, enabled: true }
    };
  } else {
    const { filter: _omit, ...rest } = value.value;
    value.value = rest;
  }
}
function setFilterLabel(label) {
  const cur = value.value.filter;
  if (!cur) return;
  const isEmpty = !label || label.every((l) => l.message.trim().length === 0);
  if (isEmpty) {
    const { label: _omit, ...rest } = cur;
    value.value = { ...value.value, filter: rest };
  } else {
    value.value = { ...value.value, filter: { ...cur, label } };
  }
}
function setFilterKeywords(next) {
  const cur = value.value.filter;
  if (!cur) return;
  if (next.length === 0) {
    const { keywords: _omit, ...rest } = cur;
    value.value = { ...value.value, filter: rest };
  } else {
    value.value = { ...value.value, filter: { ...cur, keywords: next } };
  }
}
</script>

<template>
  <div class="flex flex-col gap-3">
    <!-- Row 1: 内部名称 + 绑定路径 -->
    <div class="grid grid-cols-2 gap-3">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('displayName')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('displayName')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("displayName") }}
        </FieldLabel>
        <InputGroup>
          <InputGroupInput
            :model-value="value.displayName ?? ''"
            placeholder="例：所属部门"
            @update:model-value="(v) => {
  const s = String(v ?? '');
  value = { ...value, displayName: s.length > 0 ? s : void 0 };
}"
          />
        </InputGroup>
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('binding')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('binding')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("binding") }}
        </FieldLabel>
        <InputGroup>
          <InputGroupInput
            v-model="bindingText"
            placeholder="例：user.departmentIds"
            class="font-mono"
          />
        </InputGroup>
      </Field>
    </div>

    <!-- Row 2: 标签 + 提示 -->
    <div class="grid grid-cols-2 gap-3">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('label')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('label')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("label") }}
        </FieldLabel>
        <LocaleField
          translate-hint="form field label"
          :model-value="value.label"
          @update:model-value="(v) => value = { ...value, label: v }"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('tooltip')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('tooltip')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("tooltip") }}
        </FieldLabel>
        <LocaleField
          markdown
          translate-hint="form field tooltip"
          :model-value="value.tooltip"
          @update:model-value="(v) => value = { ...value, tooltip: v }"
        />
      </Field>
    </div>

    <!-- 数据源: request (optional) + data -->
    <h3 class="text-xs font-medium text-zinc-500">
      {{ fieldTitle("dataSource") }}
    </h3>

    <Field orientation="vertical">
      <FieldLabel class="text-xs text-zinc-500">
        <template
          v-if="dataSourceFieldDescription('request')"
          #tooltip
        >
          <Markdown
            :source="dataSourceFieldDescription('request')"
            block
            class="prose prose-sm prose-zinc"
          />
        </template>
        {{ dataSourceFieldTitle("request") }}
      </FieldLabel>
      <ExpressionEditor
        :model-value="value.dataSource.request ?? ''"
        placeholder="如 http.get('/api/departments/tree')"
        result-type="HttpRequest"
        multiline
        class="min-h-20"
        @update:model-value="setDataSourceRequest"
      />
    </Field>

    <Field orientation="vertical">
      <FieldLabel class="text-xs text-zinc-500">
        <template
          v-if="dataSourceFieldDescription('data')"
          #tooltip
        >
          <Markdown
            :source="dataSourceFieldDescription('data')"
            block
            class="prose prose-sm prose-zinc"
          />
        </template>
        {{ dataSourceFieldTitle("data") }}
      </FieldLabel>
      <ExpressionEditor
        :model-value="value.dataSource.data"
        placeholder="如 json.?value.roots.orValue([])"
        result-type="list"
        :extra-vars="jsonExtraVars"
        @update:model-value="setDataSourceData"
      />
    </Field>

    <!-- 节点表达式 -->
    <h3 class="text-xs font-medium text-zinc-500">
      节点
    </h3>

    <div class="grid grid-cols-2 gap-3">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('nodeKey')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('nodeKey')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("nodeKey") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.nodeKey"
          placeholder="例：string(node.id)"
          :result-type="['string', 'number', 'dyn']"
          :extra-vars="nodeExtraVars"
          class="min-h-10"
          @update:model-value="(v) => value = { ...value, nodeKey: v }"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('nodeChildren')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('nodeChildren')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("nodeChildren") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.nodeChildren"
          placeholder="例：has(node.children) ? node.children : null"
          result-type="list"
          :extra-vars="nodeExtraVars"
          class="min-h-10"
          @update:model-value="(v) => value = { ...value, nodeChildren: v }"
        />
      </Field>
    </div>

    <div class="grid grid-cols-2 gap-3">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('nodeLabel')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('nodeLabel')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("nodeLabel") }}
        </FieldLabel>
        <LocaleField
          markdown
          translate-hint="tree node label"
          :model-value="value.nodeLabel"
          @update:model-value="(v) => value = { ...value, nodeLabel: v }"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('nodeTooltip')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('nodeTooltip')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("nodeTooltip") }}
        </FieldLabel>
        <LocaleField
          markdown
          translate-hint="tree node tooltip"
          :model-value="value.nodeTooltip"
          @update:model-value="(v) => value = { ...value, nodeTooltip: v }"
        />
      </Field>
    </div>

    <!-- 行为: 节点可选条件 + 级联模式 + 默认全部展开 -->
    <div class="grid grid-cols-3 gap-3">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('nodeSelectable')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('nodeSelectable')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("nodeSelectable") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.nodeSelectable ?? ''"
          placeholder="例：node.kind == 'leaf'"
          result-type="bool"
          :extra-vars="nodeExtraVars"
          class="min-h-10"
          @update:model-value="(v) => setOptionalExpression('nodeSelectable', v)"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('cascade')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('cascade')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("cascade") }}
        </FieldLabel>
        <Select
          :model-value="value.cascade ?? 'cascade-both'"
          @update:model-value="(v) => value = { ...value, cascade: v }"
        >
          <SelectTrigger class="w-full">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem
              v-for="opt in CASCADE_OPTIONS"
              :key="opt.value"
              :value="opt.value"
            >
              {{ opt.label }}
            </SelectItem>
          </SelectContent>
        </Select>
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('expandAll')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('expandAll')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("expandAll") }}
        </FieldLabel>
        <div>
          <Switch
            :model-value="value.expandAll ?? false"
            @update:model-value="(v) => value = { ...value, expandAll: v }"
          />
        </div>
      </Field>
    </div>

    <!-- 过滤 (collapsible optional): toggle inlined with the section heading -->
    <div class="flex items-center gap-2">
      <h3 class="text-xs font-medium text-zinc-500">
        {{ fieldTitle("filter") }}
      </h3>
      <Switch
        size="sm"
        :model-value="filter?.enabled ?? false"
        :aria-label="filterFieldTitle('enabled')"
        @update:model-value="setFilterEnabled"
      />
    </div>

    <div
      v-if="filter?.enabled"
      class="grid grid-cols-2 gap-3"
    >
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="filterFieldDescription('label')"
            #tooltip
          >
            <Markdown
              :source="filterFieldDescription('label')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ filterFieldTitle("label") }}
        </FieldLabel>
        <LocaleField
          translate-hint="tree filter input label"
          :model-value="filter.label"
          @update:model-value="setFilterLabel"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="filterFieldDescription('keywords')"
            #tooltip
          >
            <Markdown
              :source="filterFieldDescription('keywords')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ filterFieldTitle("keywords") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="filter.keywords ?? ''"
          placeholder="例：[node.code, node.alias]"
          result-type="list"
          :extra-vars="nodeExtraVars"
          class="min-h-10"
          @update:model-value="setFilterKeywords"
        />
      </Field>
    </div>

    <!-- 通用：隐藏 / 禁用 / 只读 + 派生值 — conventionally last -->
    <div class="grid grid-cols-3 gap-3">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template #tooltip>
            <Markdown
              :source="fieldDescription('required') ?? '\u8FD4\u56DE `true` \u65F6\u663E\u793A\u5FC5\u586B\u661F\u53F7\u5E76\u8981\u6C42\u975E\u7A7A'"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("required") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.required ?? ''"
          placeholder="例：form.type == 'company'"
          result-type="bool"
          class="min-h-10"
          @update:model-value="(v) => value = { ...value, required: v.length > 0 ? v : void 0 }"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template #tooltip>
            <Markdown
              :source="fieldDescription('hidden') ?? '\u8FD4\u56DE `true` \u65F6\u5B57\u6BB5\u5728\u6240\u6709\u5E03\u5C40\u4E2D\u90FD\u4E0D\u6E32\u67D3'"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("hidden") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.hidden ?? ''"
          placeholder="例：form.role == 'guest'"
          result-type="bool"
          class="min-h-10"
          @update:model-value="(v) => setOptionalExpression('hidden', v)"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template #tooltip>
            <Markdown
              :source="fieldDescription('disabled') ?? '\u8FD4\u56DE `true` \u65F6\u4ECD\u6E32\u67D3\u4F46\u4E0D\u53EF\u52FE\u9009'"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("disabled") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.disabled ?? ''"
          placeholder="例：form.status == 'locked'"
          result-type="bool"
          class="min-h-10"
          @update:model-value="(v) => setOptionalExpression('disabled', v)"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template #tooltip>
            <Markdown
              :source="fieldDescription('readonly') ?? '\u8FD4\u56DE `true` \u65F6\u4EC5\u4EE5\u7EAF\u6587\u672C\u5C55\u793A\u5F53\u524D\u5DF2\u52FE\u9009\u8282\u70B9\u7684\u6807\u7B7E'"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("readonly") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.readonly ?? ''"
          placeholder="例：form.id != null"
          result-type="bool"
          class="min-h-10"
          @update:model-value="(v) => setOptionalExpression('readonly', v)"
        />
      </Field>
    </div>

    <Field orientation="vertical">
      <FieldLabel class="text-xs text-zinc-500">
        <template #tooltip>
          <Markdown
            :source="fieldDescription('derived')"
            block
            class="prose prose-sm prose-zinc"
          />
        </template>
        {{ fieldTitle("derived") }}
      </FieldLabel>
      <DerivedValueEditor
        :model-value="value.derived"
        result-type="dyn"
        placeholder="例：form.defaultDepartmentIds"
        @update:model-value="(v) => value = { ...value, derived: v }"
      />
    </Field>

    <Field orientation="vertical">
      <FieldLabel class="text-xs text-zinc-500">
        <template #tooltip>
          <Markdown
            :source="fieldDescription('validations')"
            block
            class="prose prose-sm prose-zinc"
          />
        </template>
        {{ fieldTitle("validations") }}
      </FieldLabel>
      <ValidationRulesField
        :model-value="value.validations"
        @update:model-value="(v) => value = { ...value, validations: v.length > 0 ? v : void 0 }"
      />
    </Field>
  </div>
</template>
