<script setup>
import { computed, ref, watch } from "vue";
import { Icon } from "@iconify/vue";
import { ExpressionEditor } from "../../../../ui/expression-editor";
import { Field, FieldLabel } from "../../../../ui/field";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupNumberField
} 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 { Separator } from "../../../../ui/separator";
import { Switch } from "../../../../ui/switch";
import DerivedValueEditor from "../../../../form/DerivedValueEditor.vue";
import { DataSource } from "../../../schema";
import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
import { schema } from "./schema";
defineOptions({ name: "ShwfedTableTreeComboboxMultiRendererConfig" });
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 ROW_VARS = {
  row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
  index: { type: "number", label: "\u884C\u7D22\u5F15" }
};
const ROW_NODE_VARS = {
  ...ROW_VARS,
  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 ROW_JSON_VARS = {
  ...ROW_VARS,
  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 CASCADE_OPTIONS = [
  {
    value: "independent",
    label: "\u72EC\u7ACB",
    description: "\u52FE\u9009 / \u53D6\u6D88\u53EA\u4F5C\u7528\u4E8E\u5F53\u524D\u8282\u70B9\uFF1B\u7236\u5B50\u4E92\u4E0D\u5F71\u54CD"
  },
  {
    value: "cascade-down",
    label: "\u5411\u4E0B\u7EA7\u8054",
    description: "\u52FE\u9009\u7236\u8282\u70B9\u81EA\u52A8\u52FE\u9009\u5176\u5168\u90E8\u53EF\u9009\u540E\u4EE3\uFF1B\u53D6\u6D88\u65F6\u540C\u7406\u3002\u7236\u8282\u70B9\u7684\u52FE\u9009\u72B6\u6001\u72EC\u7ACB\u8FFD\u8E2A"
  },
  {
    value: "cascade-both",
    label: "\u53CC\u5411\u7EA7\u8054",
    description: "\u5728\u5411\u4E0B\u7EA7\u8054\u57FA\u7840\u4E0A\uFF0C\u7236\u8282\u70B9\u53CD\u6620\u540E\u4EE3\u52FE\u9009\u72B6\u6001\uFF08\u5168\u9009\u2192\u9009\u4E2D\u3001\u90E8\u5206\u2192\u534A\u9009\u3001\u5168\u4E0D\u9009\u2192\u672A\u9009\uFF09"
  }
];
const cascadeOpen = ref(false);
const hoveredCascade = ref(null);
watch(cascadeOpen, (isOpen) => {
  hoveredCascade.value = isOpen ? value.value.cascade ?? "independent" : null;
});
const hoveredCascadeDescription = computed(
  () => CASCADE_OPTIONS.find((o) => o.value === hoveredCascade.value)?.description
);
const bindingText = computed({
  get: () => value.value.binding ?? "",
  set: (v) => {
    const trimmed = v.trim();
    if (trimmed === "") {
      const { binding: _omit, ...rest } = value.value;
      value.value = rest;
    } else {
      value.value = { ...value.value, binding: trimmed };
    }
  }
});
function setOptionalExpression(key, next) {
  if (next.length === 0) {
    const { [key]: _omit, ...rest } = value.value;
    value.value = rest;
  } else {
    value.value = { ...value.value, [key]: next };
  }
}
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 }
    };
  }
}
const derivedModel = computed({
  get: () => value.value.derived,
  set: (v) => {
    if (v == null) {
      const { derived: _omit, ...rest } = value.value;
      value.value = rest;
    } else {
      value.value = { ...value.value, derived: v };
    }
  }
});
</script>

<template>
  <div class="space-y-5">
    <!-- Identity: title + binding + placeholder + size -->
    <div class="grid grid-cols-2 gap-x-6 gap-y-4">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('title')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('title')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("title") }}
        </FieldLabel>
        <LocaleField v-model="value.title" />
      </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
          v-model="value.tooltip"
          markdown
        />
      </Field>
    </div>
    <div class="grid grid-cols-2 gap-x-6 gap-y-4">
      <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>
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('placeholder')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('placeholder')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("placeholder") }}
        </FieldLabel>
        <LocaleField v-model="value.placeholder" />
      </Field>
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('size')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('size')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("size") }}
        </FieldLabel>
        <InputGroup>
          <InputGroupNumberField
            :model-value="value.size"
            :disabled="value.grow"
            :min="0"
            @update:model-value="(v) => value = { ...value, size: v }"
          />
          <InputGroupAddon align="inline-end">
            <InputGroupButton
              :variant="value.grow ? 'primary' : 'ghost'"
              size="xs"
              @click="value = { ...value, grow: !value.grow }"
            >
              <Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
              {{ fieldTitle("grow") }}
            </InputGroupButton>
          </InputGroupAddon>
        </InputGroup>
      </Field>
    </div>

    <!-- 数据源 -->
    <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"
        :extra-vars="ROW_VARS"
        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="ROW_JSON_VARS"
        @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="ROW_NODE_VARS"
          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="ROW_NODE_VARS"
          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>

    <!-- 搜索: 额外关键词（节点作用域，返回字符串列表） -->
    <Field orientation="vertical">
      <FieldLabel class="text-xs text-zinc-500">
        <template
          v-if="fieldDescription('keywords')"
          #tooltip
        >
          <Markdown
            :source="fieldDescription('keywords')"
            block
            class="prose prose-sm prose-zinc"
          />
        </template>
        {{ fieldTitle("keywords") }}
      </FieldLabel>
      <ExpressionEditor
        :model-value="value.keywords ?? ''"
        placeholder="例：[node.code, node.pinyin]"
        result-type="list"
        :extra-vars="ROW_NODE_VARS"
        class="min-h-10"
        @update:model-value="(v) => setOptionalExpression('keywords', v)"
      />
    </Field>

    <!-- 行为: 节点可选条件 + 级联模式 + 默认全部展开 -->
    <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="例：!has(node.disabled) || !node.disabled"
          result-type="bool"
          :extra-vars="ROW_NODE_VARS"
          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
          v-model:open="cascadeOpen"
          :model-value="value.cascade ?? 'independent'"
          @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"
              @mouseenter="hoveredCascade = opt.value"
              @focus="hoveredCascade = opt.value"
            >
              {{ opt.label }}
            </SelectItem>
            <div
              v-if="hoveredCascadeDescription"
              data-slot="cascade-description"
              class="mt-1 border-t border-zinc-200 px-2 py-1.5 text-xs text-zinc-500"
            >
              {{ hoveredCascadeDescription }}
            </div>
          </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>

    <!-- 通用: 隐藏 / 禁用 / 只读 + 派生值 -->
    <div class="grid grid-cols-2 gap-x-6 gap-y-4">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('hidden')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('hidden')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("hidden") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.hidden ?? ''"
          placeholder="例：row.archived"
          result-type="bool"
          :extra-vars="ROW_VARS"
          @update:model-value="(v) => setOptionalExpression('hidden', v)"
        />
      </Field>
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('disabled')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('disabled')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("disabled") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.disabled ?? ''"
          placeholder="例：row.locked"
          result-type="bool"
          :extra-vars="ROW_VARS"
          @update:model-value="(v) => setOptionalExpression('disabled', v)"
        />
      </Field>
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('readonly')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('readonly')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("readonly") }}
        </FieldLabel>
        <ExpressionEditor
          :model-value="value.readonly ?? ''"
          placeholder="例：row.id != null"
          result-type="bool"
          :extra-vars="ROW_VARS"
          @update:model-value="(v) => setOptionalExpression('readonly', v)"
        />
      </Field>
      <Field
        orientation="vertical"
        class="col-span-2"
      >
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('derived')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('derived')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("derived") }}
        </FieldLabel>
        <DerivedValueEditor
          v-model="derivedModel"
          result-type="list"
          placeholder="例：row.defaultIds"
        />
      </Field>
    </div>

    <Separator />
    <div class="flex flex-wrap gap-x-8 gap-y-3">
      <Field
        orientation="vertical"
        class="w-full max-w-xs"
      >
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('enableSorting')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('enableSorting')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("enableSorting") }}
        </FieldLabel>
        <InputGroup>
          <InputGroupInput
            :model-value="value.sortKey"
            placeholder="例：created_at"
            @update:model-value="(v) => value = { ...value, sortKey: v || void 0 }"
          />
          <InputGroupAddon align="inline-end">
            <InputGroupButton
              :variant="value.enableSorting ? 'primary' : 'ghost'"
              size="xs"
              @click="value = { ...value, enableSorting: !value.enableSorting }"
            >
              <Icon :icon="value.enableSorting ? 'fluent:arrow-sort-up-16-regular' : 'fluent:arrow-sort-16-regular'" />
              {{ fieldTitle("enableSorting") }}
            </InputGroupButton>
          </InputGroupAddon>
        </InputGroup>
      </Field>
    </div>
  </div>
</template>
