<script setup>
import { computed, inject, onBeforeUnmount, ref, watch } from "vue";
import { Icon } from "@iconify/vue";
import { defaultSlot } from "../../../../../share/layout";
import BlockLayoutEditor from "../../../../block-layout-editor/index.vue";
import LayoutsSidebar from "../../../../block-layout-editor/sidebar.vue";
import LayoutMetaStrip from "../../../../block-layout-editor/meta-strip.vue";
import { Button } from "../../../../ui/button";
import { ScrollArea } from "../../../../ui/scroll-area";
import { Field, FieldLabel } from "../../../../ui/field";
import { Input } from "../../../../ui/input";
import { Locale as LocaleField } from "../../../../ui/locale";
import { Markdown } from "../../../../ui/markdown";
import { BREADCRUMB_EXTENSION_KEY } from "../../../../config/breadcrumb-extension";
import { SIDEBAR_TAKEOVER_KEY } from "../../../../sidebar-takeover";
import { lookupFindBlock } from "../../../../config/utils/block-ref-cache";
import { useSlotEditor } from "../../../../config/use-editor";
import { getStructFieldDescription, getStructFieldTitle } from "../../../schema";
import { schema } from "./schema";
defineOptions({ name: "ShwfedModalLayoutActionConfig" });
const value = defineModel({ type: null, ...{ required: true } });
const props = defineProps({
  configure: { type: Function, required: false }
});
const configure = computed(() => props.configure ?? (() => {
}));
const actionSchema = schema(() => {
});
const fieldTitle = (f) => getStructFieldTitle(actionSchema, f) ?? f;
const fieldDescription = (f) => getStructFieldDescription(actionSchema, f);
const slot = computed({
  get: () => value.value.slot ?? defaultSlot(),
  set: (next) => {
    value.value = { ...value.value, slot: next };
  }
});
const editor = useSlotEditor(slot, { configure: configure.value });
function setModalTitle(next) {
  value.value = { ...value.value, modalTitle: next };
}
function setOptional(key, next) {
  const trimmed = next.trim();
  const draft = { ...value.value };
  if (trimmed.length === 0) Reflect.deleteProperty(draft, key);
  else draft[key] = trimmed;
  value.value = draft;
}
function addLayout() {
  const cur = editor.layouts.value;
  editor.layouts.value = [
    ...cur,
    { name: "\u65B0\u5E03\u5C40", layout: { columns: 1, placements: {} } }
  ];
  editor.activeLayoutIndex.value = cur.length;
}
function addBlock(entry, options) {
  editor.addBlock(entry, options);
}
function deleteBlock(id) {
  editor.removeBlock(id);
}
function deleteBlocks(ids) {
  editor.removeBlocks(ids);
}
const drilledBlockId = ref(null);
const drilledBlock = computed(() => {
  const id = drilledBlockId.value;
  if (!id) return null;
  return editor.blocks.value.find((b) => b.id === id) ?? null;
});
const drilledEntry = computed(() => {
  const b = drilledBlock.value;
  if (!b) return null;
  return lookupFindBlock()?.(b.type, b.compatibilityDate) ?? null;
});
function onDrillDown(id) {
  drilledBlockId.value = id;
}
function popDrill() {
  drilledBlockId.value = null;
}
watch(
  () => editor.blocks.value.map((b) => b.id),
  (ids) => {
    const id = drilledBlockId.value;
    if (id && !ids.includes(id)) drilledBlockId.value = null;
  }
);
function updateDrilledBlock(next) {
  const id = drilledBlockId.value;
  if (!id) return;
  editor.updateBlock(id, next);
}
const breadcrumbExt = inject(BREADCRUMB_EXTENSION_KEY, null);
if (breadcrumbExt) {
  const blockCrumb = breadcrumbExt.add();
  watch(
    drilledBlock,
    (drilled) => {
      if (drilled) {
        blockCrumb.label.value = editor.getBlockLabel(drilled);
        blockCrumb.back.value = popDrill;
      } else {
        blockCrumb.label.value = null;
        blockCrumb.back.value = null;
      }
    },
    { immediate: true }
  );
  onBeforeUnmount(() => {
    blockCrumb.dispose();
  });
}
const takeover = inject(SIDEBAR_TAKEOVER_KEY, null);
const takeoverTarget = computed(() => takeover?.target.value ?? null);
watch(drilledBlockId, (id) => {
  if (takeover?.drilled) takeover.drilled.value = !!id;
}, { immediate: true });
onBeforeUnmount(() => {
  if (takeover?.drilled) takeover.drilled.value = false;
});
</script>

<template>
  <!-- Sidebar takeover: layouts rail injected into the host's left column.
       When drilled into a child block we release the target so the child
       (e.g. a form block with its own sidebar) can claim it instead. -->
  <Teleport
    v-if="takeoverTarget && !drilledBlockId"
    :to="takeoverTarget"
  >
    <ScrollArea class="flex-1">
      <LayoutsSidebar
        :model-value="editor.layouts.value"
        :active-index="editor.activeLayoutIndex.value"
        @update:model-value="(v) => {
  editor.layouts.value = v;
}"
        @update:active-index="(v) => {
  editor.activeLayoutIndex.value = v;
}"
      />
    </ScrollArea>
    <Button
      variant="ghost"
      size="sm"
      @click="addLayout()"
    >
      <Icon
        icon="fluent:add-20-regular"
        class="size-4"
      />
      <span>新增布局</span>
    </Button>
  </Teleport>

  <!-- Drilled into a child block — render its config full-width. -->
  <template v-if="drilledBlockId">
    <div
      v-if="!drilledBlock"
      class="flex min-h-96 items-center justify-center p-8 text-sm text-zinc-400"
    >
      块已不存在
    </div>
    <div v-else-if="drilledEntry">
      <component
        :is="drilledEntry.config"
        :model-value="drilledBlock"
        :configure="configure"
        @update:model-value="(next) => updateDrilledBlock(next)"
      />
    </div>
    <div
      v-else
      class="p-6 text-sm text-red-500"
    >
      未注册的块类型：{{ drilledBlock.type }}@{{ drilledBlock.compatibilityDate }}
    </div>
  </template>

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

    <div class="grid grid-cols-2 gap-4">
      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('modalWidth')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('modalWidth')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("modalWidth") }}
        </FieldLabel>
        <Input
          :model-value="value.modalWidth ?? ''"
          placeholder="例：720px / 60vw"
          @update:model-value="(v) => setOptional('modalWidth', String(v))"
        />
      </Field>

      <Field orientation="vertical">
        <FieldLabel class="text-xs text-zinc-500">
          <template
            v-if="fieldDescription('modalMinHeight')"
            #tooltip
          >
            <Markdown
              :source="fieldDescription('modalMinHeight')"
              block
              class="prose prose-sm prose-zinc"
            />
          </template>
          {{ fieldTitle("modalMinHeight") }}
        </FieldLabel>
        <Input
          :model-value="value.modalMinHeight ?? ''"
          placeholder="例：400px / 60vh"
          @update:model-value="(v) => setOptional('modalMinHeight', String(v))"
        />
      </Field>
    </div>

    <!-- Inline layouts rail fallback when no takeover provider exists. -->
    <div
      v-if="!takeoverTarget"
      class="flex gap-2 min-h-96"
    >
      <div class="flex w-56 shrink-0 flex-col">
        <ScrollArea class="flex-1">
          <LayoutsSidebar
            :model-value="editor.layouts.value"
            :active-index="editor.activeLayoutIndex.value"
            @update:model-value="(v) => {
  editor.layouts.value = v;
}"
            @update:active-index="(v) => {
  editor.activeLayoutIndex.value = v;
}"
          />
        </ScrollArea>
        <Button
          variant="ghost"
          size="sm"
          @click="addLayout()"
        >
          <Icon
            icon="fluent:add-20-regular"
            class="size-4"
          />
          <span>新增布局</span>
        </Button>
      </div>

      <div class="flex flex-1 flex-col gap-2">
        <LayoutMetaStrip
          :model-value="editor.layouts.value"
          :index="editor.activeLayoutIndex.value"
          @update:model-value="(v) => {
  editor.layouts.value = v;
}"
        />
        <div class="flex-1">
          <BlockLayoutEditor
            :model-value="editor.layouts.value"
            :active-index="editor.activeLayoutIndex.value"
            :selected-item-ids="editor.selectedBlockIds.value"
            :items="editor.blocks.value"
            :find-entry="editor.findBlockMeta"
            :get-item-label="editor.getBlockLabel"
            :picker-entries="editor.pickerEntries.value"
            :can-delete="true"
            item-noun="块"
            @update:model-value="(v) => {
  editor.layouts.value = v;
}"
            @update:active-index="(v) => {
  editor.activeLayoutIndex.value = v;
}"
            @update:selected-item-ids="(v) => {
  editor.selectedBlockIds.value = v;
}"
            @add-new="addBlock"
            @drill-down="onDrillDown"
            @delete-item="deleteBlock"
            @delete-items="deleteBlocks"
          />
        </div>
      </div>
    </div>

    <!-- Takeover-aware layout: canvas only; layouts rail teleports to host. -->
    <div
      v-else
      class="flex flex-col gap-2"
    >
      <LayoutMetaStrip
        :model-value="editor.layouts.value"
        :index="editor.activeLayoutIndex.value"
        @update:model-value="(v) => {
  editor.layouts.value = v;
}"
      />
      <div class="h-96">
        <BlockLayoutEditor
          :model-value="editor.layouts.value"
          :active-index="editor.activeLayoutIndex.value"
          :selected-item-ids="editor.selectedBlockIds.value"
          :items="editor.blocks.value"
          :find-entry="editor.findBlockMeta"
          :get-item-label="editor.getBlockLabel"
          :picker-entries="editor.pickerEntries.value"
          :can-delete="true"
          item-noun="块"
          @update:model-value="(v) => {
  editor.layouts.value = v;
}"
          @update:active-index="(v) => {
  editor.activeLayoutIndex.value = v;
}"
          @update:selected-item-ids="(v) => {
  editor.selectedBlockIds.value = v;
}"
          @add-new="addBlock"
          @drill-down="onDrillDown"
          @delete-item="deleteBlock"
          @delete-items="deleteBlocks"
        />
      </div>
    </div>
  </div>
</template>
