<script setup>
import { Icon } from "@iconify/vue";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import {
  useTreeDnd
} from "../../composables/useTreeDnd";
defineOptions({ name: "ShwfedBlockLayoutEditorSidebar" });
const layouts = defineModel({ type: Array, ...{ required: true } });
const activeIndex = defineModel("activeIndex", { type: Number, ...{ default: 0 } });
const props = defineProps({
  active: { type: Boolean, required: false, default: true }
});
const emit = defineEmits(["select"]);
const ROW_KIND = "layout-row";
function selectIndex(i) {
  if (i < 0 || i >= layouts.value.length) return;
  activeIndex.value = i;
  emit("select", i);
}
function addLayout() {
  const next = {
    name: "\u65B0\u5E03\u5C40",
    layout: { columns: 1, placements: {} }
  };
  layouts.value = [...layouts.value, next];
  activeIndex.value = layouts.value.length - 1;
  emit("select", layouts.value.length - 1);
}
function duplicateAt(i) {
  const src = layouts.value[i];
  if (!src) return;
  const placements = Object.fromEntries(
    Object.entries(src.layout.placements).map(([id, p]) => {
      const [[x1, y1], [x2, y2]] = p.area;
      return [id, { ...p, area: [[x1, y1], [x2, y2]] }];
    })
  );
  const next = {
    ...src,
    name: `${src.name} \u526F\u672C`,
    layout: { ...src.layout, placements }
  };
  const arr = [...layouts.value];
  arr.splice(i + 1, 0, next);
  layouts.value = arr;
  activeIndex.value = i + 1;
  emit("select", i + 1);
}
function deleteAt(i) {
  if (layouts.value.length <= 1) return;
  if (i < 0 || i >= layouts.value.length) return;
  const arr = layouts.value.filter((_, idx) => idx !== i);
  layouts.value = arr;
  if (activeIndex.value === i) activeIndex.value = Math.max(0, i - 1);
  else if (activeIndex.value > i) activeIndex.value = activeIndex.value - 1;
}
function moveLayout(from, to) {
  if (from === to) return;
  if (from < 0 || to < 0) return;
  if (from >= layouts.value.length || to >= layouts.value.length) return;
  const next = [...layouts.value];
  const [item] = next.splice(from, 1);
  if (!item) return;
  next.splice(to, 0, item);
  layouts.value = next;
  if (activeIndex.value === from) activeIndex.value = to;
  else if (from < activeIndex.value && to >= activeIndex.value) activeIndex.value -= 1;
  else if (from > activeIndex.value && to <= activeIndex.value) activeIndex.value += 1;
}
function onRowDrop(e) {
  if (e.source.kind !== ROW_KIND || e.target.kind !== ROW_KIND) return;
  const from = layouts.value.findIndex((_, i) => rowId(i) === e.source.id);
  const to = layouts.value.findIndex((_, i) => rowId(i) === e.target.id);
  if (from < 0 || to < 0) return;
  if (e.instruction === "reorder-above") moveLayout(from, from < to ? to - 1 : to);
  else if (e.instruction === "reorder-below") moveLayout(from, from <= to ? to : to + 1);
}
const dnd = useTreeDnd({ onRowDrop });
const pickDragHandle = (el) => el.querySelector(".drag-handle");
function rowId(i) {
  return `row-${i}`;
}
function rowConfig(i) {
  return {
    kind: ROW_KIND,
    canDrop: (src) => src.kind === ROW_KIND,
    blockInstructions: (src) => {
      const block = ["make-child", "reparent"];
      if (src.id === rowId(i)) block.push("reorder-above", "reorder-below");
      return block;
    },
    dragHandle: pickDragHandle
  };
}
defineExpose({ addLayout });
</script>

<template>
  <div class="flex flex-col gap-0.5">
    <div
      v-for="(ls, i) in layouts"
      :key="rowId(i)"
      :ref="dnd.rowRef(rowId(i), rowConfig(i))"
      class="row group"
      :class="[
  props.active && activeIndex === i ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-700 hover:bg-zinc-50'
]"
      :data-instruction="dnd.instructionFor(rowId(i)) ?? void 0"
      @click="selectIndex(i)"
    >
      <Icon
        icon="fluent:re-order-dots-vertical-20-regular"
        class="drag-handle size-4 shrink-0 cursor-grab text-zinc-400"
      />

      <span class="flex-1 truncate">{{ ls.name || "\u672A\u547D\u540D\u5E03\u5C40" }}</span>

      <span
        class="ml-auto flex items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100"
        @click.stop
      >
        <Tooltip :delay-duration="180">
          <TooltipTrigger as-child>
            <button
              type="button"
              class="inline-flex size-6 items-center justify-center rounded text-zinc-400 hover:bg-zinc-100 hover:text-zinc-700"
              @click.stop="duplicateAt(i)"
            >
              <Icon
                icon="fluent:copy-20-regular"
                class="size-3.5"
              />
            </button>
          </TooltipTrigger>
          <TooltipContent side="right">
            复制布局
          </TooltipContent>
        </Tooltip>
        <Tooltip
          v-if="layouts.length > 1"
          :delay-duration="180"
        >
          <TooltipTrigger as-child>
            <button
              type="button"
              class="inline-flex size-6 items-center justify-center rounded text-zinc-300 hover:bg-red-50 hover:text-red-500"
              @click.stop="deleteAt(i)"
            >
              <Icon
                icon="fluent:delete-20-regular"
                class="size-3.5"
              />
            </button>
          </TooltipTrigger>
          <TooltipContent side="right">
            删除布局
          </TooltipContent>
        </Tooltip>
      </span>
    </div>
  </div>
</template>

<style scoped>
.row{align-items:center;border-radius:.25rem;cursor:pointer;display:flex;font-size:.875rem;gap:.375rem;padding-block:.375rem;padding-left:.5rem;padding-right:.5rem;position:relative;transition:background-color .1s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none}[data-instruction=reorder-above]:before,[data-instruction=reorder-below]:after{background:var(--primary,#2563eb);content:"";height:2px;left:.5rem;pointer-events:none;position:absolute;right:.5rem;z-index:1}[data-instruction=reorder-above]:before{top:-1px}[data-instruction=reorder-below]:after{bottom:-1px}
</style>
