<script>
  import { onDestroy } from "svelte";
  import BlockCard from "./BlockCard.svelte";

  export let blocks = [];
  export let onChange;
  export let onRemove;
  export let onReorder;
  export let onAdd = null;
  export let blockGroups = [];
  export let colorizeTitles = false;
  export let collapseAll = null;

  let draggingId = null;
  let placeholderIndex = -1;
  let addValue = "";
  const rowRefs = new Map();
  let pointerListenersAttached = false;
  const SEGMENT_LABELS = {
    common: "Общие блоки",
    female: "Женский сегмент",
    male: "Мужской сегмент"
  };

  const findIndexById = (id) => blocks.findIndex((b) => b.id === id);
  $: draggingItem = draggingId ? decoratedBlocks.find((item) => item.block.id === draggingId) : null;

  // Подсчитываем порядковые номера женских/мужских блоков
  let blocksWithSegments = [];
  $: {
    let female = 0;
    let male = 0;
    blocksWithSegments = blocks.map((b) => {
      const seg = b.segment || "common";
      const info = { block: b, femaleIndex: 0, maleIndex: 0 };
      if (seg === "female") info.femaleIndex = ++female;
      if (seg === "male") info.maleIndex = ++male;
      return info;
    });
  }

  let decoratedBlocks = [];
  $: {
    decoratedBlocks = blocksWithSegments.map((item, idx) => {
      const prevSegment = idx > 0 ? (blocks[idx - 1]?.segment || "common") : null;
      const currentSegment = item.block.segment || "common";
      const dividerAllowed = currentSegment === "common" ? idx === 0 : true;
      return {
        ...item,
        segment: currentSegment,
        showDivider: dividerAllowed && prevSegment !== currentSegment,
        dividerLabel: SEGMENT_LABELS[currentSegment] || "Блоки"
      };
    });
  }

  function trackRow(node, id) {
    if (!id) return;
    rowRefs.set(id, node);
    return {
      update(newId) {
        if (newId === id) return;
        rowRefs.delete(id);
        id = newId;
        if (newId) {
          rowRefs.set(newId, node);
        }
      },
      destroy() {
        rowRefs.delete(id);
      }
    };
  }

  const attachPointerListeners = () => {
    if (pointerListenersAttached) return;
    pointerListenersAttached = true;
    window.addEventListener("pointermove", handlePointerMove, { passive: false });
    window.addEventListener("pointerup", handlePointerRelease, { passive: false });
    window.addEventListener("pointercancel", handlePointerRelease, { passive: false });
  };

  const detachPointerListeners = () => {
    if (!pointerListenersAttached) return;
    pointerListenersAttached = false;
    window.removeEventListener("pointermove", handlePointerMove);
    window.removeEventListener("pointerup", handlePointerRelease);
    window.removeEventListener("pointercancel", handlePointerRelease);
  };

  onDestroy(detachPointerListeners);

  const getPointerY = (event) => {
    if (typeof event.clientY === "number") return event.clientY;
    if (event.touches?.length) return event.touches[0].clientY;
    if (event.changedTouches?.length) return event.changedTouches[0].clientY;
    return 0;
  };

  const beginPointerDrag = (id) => (event) => {
    if (event.button !== undefined && event.button !== 0) return;
    draggingId = id;
    const currentIndex = findIndexById(id);
    placeholderIndex = Math.min(blocks.length, currentIndex + 1);
    updatePlaceholderPosition(getPointerY(event));
    event.preventDefault();
    event.stopPropagation();
    attachPointerListeners();
  };

  const handlePointerMove = (event) => {
    if (!draggingId) return;
    event.preventDefault();
    updatePlaceholderPosition(getPointerY(event));
  };

  const handlePointerRelease = (event) => {
    if (!draggingId) return;
    event.preventDefault();
    detachPointerListeners();
    finalizePointerDrag();
  };

  function updatePlaceholderPosition(y) {
    const entries = [];
    blocks.forEach((block, idx) => {
      if (draggingId && block.id === draggingId) return;
      const node = rowRefs.get(block.id);
      if (!node) return;
      const rect = node.getBoundingClientRect();
      entries.push({ idx, mid: rect.top + rect.height / 2 });
    });

    if (!entries.length) {
      placeholderIndex = 0;
      return;
    }

    let target = entries[entries.length - 1].idx + 1;
    for (const entry of entries) {
      if (y < entry.mid) {
        target = entry.idx;
        break;
      }
    }
    placeholderIndex = target;
  }

  function finalizePointerDrag() {
    if (!draggingId || placeholderIndex < 0) {
      resetDragState();
      return;
    }
    const from = findIndexById(draggingId);
    const to = placeholderIndex;
    if (from === -1 || to === -1 || from === to) {
      resetDragState();
      return;
    }
    const copy = [...blocks];
    const [item] = copy.splice(from, 1);
    copy.splice(to > from ? to - 1 : to, 0, item);
    onReorder(copy);
    resetDragState();
  }

  const resetDragState = () => {
    draggingId = null;
    placeholderIndex = -1;
  };
</script>

<div class="blocks-container" role="list">
  {#if blocks.length === 0}
    <div class="hint">Добавляй блоки в нужном порядке.</div>
  {/if}

  {#each decoratedBlocks as item, index (item.block.id)}
    {#if item.showDivider}
      <div class="segment-divider" data-segment={item.segment}>
        <span>{item.dividerLabel}</span>
      </div>
    {/if}
    {#if draggingId && placeholderIndex === index && draggingItem}
      <div role="listitem" use:trackRow={draggingItem.block.id}>
        <BlockCard
          block={draggingItem.block}
          index={index}
          femaleIndex={draggingItem.femaleIndex}
          maleIndex={draggingItem.maleIndex}
          onChange={onChange}
          onRemove={onRemove}
          onHandlePointerDown={beginPointerDrag(draggingItem.block.id)}
          forceCollapse={collapseAll}
          {colorizeTitles}
          isDragging={true}
        />
      </div>
    {/if}
    {#if item.block.id !== draggingId}
      <div
        role="listitem"
        use:trackRow={item.block.id}
      >
        <BlockCard
          block={item.block}
          {index}
          femaleIndex={item.femaleIndex}
          maleIndex={item.maleIndex}
          onChange={onChange}
          onRemove={onRemove}
          onHandlePointerDown={beginPointerDrag(item.block.id)}
          forceCollapse={collapseAll}
          {colorizeTitles}
          isDragging={false}
        />
      </div>
    {/if}
  {/each}
  {#if draggingId && draggingItem && placeholderIndex === decoratedBlocks.length}
    <div role="listitem" use:trackRow={draggingItem.block.id}>
      <BlockCard
        block={draggingItem.block}
        index={placeholderIndex - 1}
        femaleIndex={draggingItem.femaleIndex}
        maleIndex={draggingItem.maleIndex}
        onChange={onChange}
        onRemove={onRemove}
        onHandlePointerDown={beginPointerDrag(draggingItem.block.id)}
        forceCollapse={collapseAll}
        {colorizeTitles}
        isDragging={true}
      />
    </div>
  {/if}

  <div class="add-bottom">
    <div class="quick-add">
      <button type="button" class="btn icon-only" title="Баннер с ссылкой" on:click={() => onAdd && onAdd("banner")}>
        <svg class="icon" viewBox="0 0 16 16" aria-hidden="true">
          <rect x="2.5" y="3.5" width="11" height="9" rx="1.4" />
          <path d="M3.5 5.5h9" />
          <path d="M4.3 10.5 6.6 8l2.1 2.3 1.5-1.3 1.5 1.5" />
          <circle cx="5.4" cy="6.8" r="0.6" />
        </svg>
      </button>
      <button type="button" class="btn icon-only" title="Текстовый блок" on:click={() => onAdd && onAdd("paragraph")}>
        <svg class="icon" viewBox="0 0 16 16" aria-hidden="true">
          <path d="M4 4.5h8" />
          <path d="M8 4.5v7.5" />
        </svg>
      </button>
      <button type="button" class="btn icon-only" title="4 товара в ряд" on:click={() => onAdd && onAdd("products4Row")}>
        <svg class="icon" viewBox="0 0 16 16" aria-hidden="true">
          <rect x="2" y="6" width="2.8" height="4" rx="0.5" />
          <rect x="5" y="6" width="2.8" height="4" rx="0.5" />
          <rect x="8" y="6" width="2.8" height="4" rx="0.5" />
          <rect x="11" y="6" width="2.8" height="4" rx="0.5" />
        </svg>
      </button>
      <button type="button" class="btn icon-only" title="3 товара + картинка слева" on:click={() => onAdd && onAdd("productsImageLeft3")}>
        <svg class="icon" viewBox="0 0 16 16" aria-hidden="true">
          <rect x="2" y="3" width="5.5" height="10" rx="0.8" />
          <rect x="9" y="3.5" width="3" height="2.5" rx="0.5" />
          <rect x="9" y="6.5" width="3" height="2.5" rx="0.5" />
          <rect x="9" y="9.5" width="3" height="2.5" rx="0.5" />
        </svg>
      </button>
      <button type="button" class="btn icon-only" title="3 товара + картинка справа" on:click={() => onAdd && onAdd("productsImageRight3")}>
        <svg class="icon" viewBox="0 0 16 16" aria-hidden="true">
          <rect x="9" y="3" width="5.5" height="10" rx="0.8" />
          <rect x="4" y="3.5" width="3" height="2.5" rx="0.5" />
          <rect x="4" y="6.5" width="3" height="2.5" rx="0.5" />
          <rect x="4" y="9.5" width="3" height="2.5" rx="0.5" />
        </svg>
      </button>
      <button type="button" class="btn icon-only" title="Кнопка по центру" on:click={() => onAdd && onAdd("buttonSingle")}>
        <svg class="icon" viewBox="0 0 16 16" aria-hidden="true">
          <rect x="3" y="6.5" width="10" height="3" rx="1.2" />
        </svg>
      </button>
    </div>
    <select
      class="btn add-bottom-select"
      bind:value={addValue}
      on:change={(e) => {
        const val = e.target.value;
        if (val && onAdd) onAdd(val);
        addValue = "";
      }}
    >
      <option value="">+ Добавить блок</option>
      {#each blockGroups as group}
        <optgroup label={group.label}>
          {#each group.options as option}
            <option value={option.value}>{option.label}</option>
          {/each}
        </optgroup>
      {/each}
    </select>
  </div>
</div>

<style>
  .add-bottom {
    padding: 12px 4px 18px;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 6px;
  }

  .add-bottom-select {
    width: auto;
    min-width: 180px;
    max-width: 220px;
    justify-content: center;
    font-weight: 600;
    letter-spacing: 0.01em;
    appearance: none;
    text-align: center;
    padding-inline: 10px;
  }

  .quick-add {
    display: inline-flex;
    align-items: center;
    gap: 6px;
  }

  .quick-add .btn.icon-only {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    width: 34px;
    min-width: 34px;
    height: 32px;
    padding: 0;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    transition: border-color 140ms ease, background 140ms ease, color 140ms ease;
  }

  .quick-add .btn.icon-only .icon {
    width: 22px;
    height: 22px;
    display: block;
  }

  .quick-add .btn.icon-only .icon rect,
  .quick-add .btn.icon-only .icon path {
    stroke: currentColor;
    stroke-width: 0.6;
    fill: none;
  }

  .quick-add .btn.icon-only:hover {
    border-color: var(--accent);
    background: var(--pill);
    color: var(--text);
  }
</style>
