/**
 * 메뉴 관리 페이지 전용 SortableJS 초기화 스크립트
 * HTMX hx-boost 네비게이션에서도 동작하도록 전역으로 정의
 * - 그룹 드래그: 상위 메뉴 드래그 시 하위 메뉴 자동 포함
 */

// 드래그 상태 관리
let dragStartX = 0;
let dragIndicator = null;
let currentDragItem = null;
let lastHighlightedRow = null;
let groupDragItems = []; // 그룹 드래그 대상 행들
const INDENT_THRESHOLD = 40; // px - 인덴트 임계값

// 드래그 인디케이터 생성
function createDragIndicator() {
    const indicator = document.createElement('div');
    indicator.className = 'drag-indicator reorder';
    indicator.innerHTML = '↕️ 순서 변경';
    indicator.style.display = 'none';
    document.body.appendChild(indicator);
    return indicator;
}

// 드래그 인디케이터 업데이트
function updateDragIndicator(deltaX, mouseX, mouseY, canIndent, canOutdent, targetName) {
    if (!dragIndicator) return;

    dragIndicator.style.display = 'block';
    dragIndicator.style.left = (mouseX + 15) + 'px';
    dragIndicator.style.top = (mouseY - 15) + 'px';

    const groupCount = groupDragItems.length;
    const groupLabel = groupCount > 1 ? ` <span style="background:rgba(255,255,255,0.3);padding:1px 6px;border-radius:10px;margin-left:4px;font-size:11px;">${groupCount}개</span>` : '';

    // 클래스 및 텍스트 업데이트
    dragIndicator.classList.remove('indent', 'outdent', 'reorder');

    if (deltaX > INDENT_THRESHOLD && canIndent) {
        dragIndicator.classList.add('indent');
        dragIndicator.innerHTML = `→ <b>${targetName}</b>의 하위로${groupLabel}`;
    } else if (deltaX < -INDENT_THRESHOLD && canOutdent) {
        dragIndicator.classList.add('outdent');
        dragIndicator.innerHTML = `← 상위 레벨로${groupLabel}`;
    } else {
        dragIndicator.classList.add('reorder');
        dragIndicator.innerHTML = `↕️ 순서 변경${groupLabel}`;
    }
}

// 행 하이라이트 업데이트
function updateRowHighlight(prevRow, draggedRow, deltaX, canIndent, canOutdent) {
    // 이전 하이라이트 제거
    if (lastHighlightedRow) {
        lastHighlightedRow.classList.remove('drag-target-indent', 'drag-target-outdent');
    }

    // 새 하이라이트 적용
    if (deltaX > INDENT_THRESHOLD && canIndent && prevRow) {
        prevRow.classList.add('drag-target-indent');
        lastHighlightedRow = prevRow;
    } else if (deltaX < -INDENT_THRESHOLD && canOutdent && draggedRow) {
        draggedRow.classList.add('drag-target-outdent');
        lastHighlightedRow = draggedRow;
    } else {
        lastHighlightedRow = null;
    }
}

// 드래그 인디케이터 제거
function removeDragIndicator() {
    if (dragIndicator) {
        dragIndicator.remove();
        dragIndicator = null;
    }
    if (lastHighlightedRow) {
        lastHighlightedRow.classList.remove('drag-target-indent', 'drag-target-outdent');
        lastHighlightedRow = null;
    }
}

/**
 * 상위 메뉴 드래그 시 하위 메뉴를 재귀적으로 수집
 * - 자식이 있는 메뉴(상위 메뉴)를 드래그하면 자동으로 모든 하위 포함
 * - 자식이 없는 메뉴(리프 메뉴)는 단독 드래그
 */
function collectGroupItems(draggedRow) {
    const draggedId = draggedRow.dataset.menuId;

    // 하위 메뉴가 있는지 확인 (DOM에서 data-parent-id로 탐색)
    const directChildren = document.querySelectorAll(`#menu-sortable tr.menu-row[data-parent-id="${draggedId}"]`);
    if (directChildren.length === 0) return [draggedRow];

    // 드래그 항목 + 모든 하위 메뉴를 재귀적으로 수집
    const items = [draggedRow];
    const descendantIds = getDescendantIds(draggedId);
    descendantIds.forEach(id => {
        const row = document.querySelector(`#menu-sortable tr.menu-row[data-menu-id="${id}"]`);
        if (row) items.push(row);
    });

    return items;
}

/**
 * 특정 메뉴의 모든 하위 메뉴 ID를 재귀적으로 수집
 */
function getDescendantIds(parentId) {
    const ids = [];
    const children = document.querySelectorAll(`tr.menu-row[data-parent-id="${parentId}"]`);
    children.forEach(child => {
        const childId = child.dataset.menuId;
        ids.push(childId);
        ids.push(...getDescendantIds(childId));
    });
    return ids;
}

// SortableJS 초기화 함수 (전역)
window.initMenuSortable = function() {
    const tbody = document.getElementById('menu-sortable');
    if (!tbody) return;

    // Sortable 라이브러리 체크
    if (typeof Sortable === 'undefined') {
        console.warn('SortableJS not loaded');
        return;
    }

    // 기존 인스턴스 제거
    if (tbody.sortableInstance) {
        tbody.sortableInstance.destroy();
    }

    // 드래그 중 마우스 이동 핸들러
    function onDragMove(e) {
        if (!currentDragItem) return;

        const mouseX = e.clientX || e.touches?.[0]?.clientX || 0;
        const mouseY = e.clientY || e.touches?.[0]?.clientY || 0;
        const deltaX = mouseX - dragStartX;

        const rows = Array.from(tbody.querySelectorAll('tr.menu-row:not(.group-drag-hidden)'));
        const draggedIndex = rows.indexOf(currentDragItem);

        // 위 행 찾기 (드래그 중인 항목 제외)
        let prevRow = null;
        for (let i = draggedIndex - 1; i >= 0; i--) {
            if (rows[i] !== currentDragItem && !rows[i].classList.contains('sortable-ghost')) {
                prevRow = rows[i];
                break;
            }
        }

        // 인덴트/아웃덴트 가능 여부 체크
        const oldParentIdRaw = currentDragItem.dataset.parentId;
        const oldPid = oldParentIdRaw === '' ? null : (oldParentIdRaw ? parseInt(oldParentIdRaw) : null);
        const canIndent = prevRow !== null;
        const canOutdent = oldPid !== null;

        // 타겟 이름 가져오기
        let targetName = '';
        if (prevRow && canIndent) {
            const nameCell = prevRow.querySelector('td:nth-child(3) span');
            targetName = nameCell?.textContent?.trim() || '위 항목';
        }

        updateDragIndicator(deltaX, mouseX, mouseY, canIndent, canOutdent, targetName);
        updateRowHighlight(prevRow, currentDragItem, deltaX, canIndent, canOutdent);
    }

    // CSRF 토큰 가져오기
    const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';

    // SortableJS 초기화 - 노션 스타일 인덴트
    tbody.sortableInstance = new Sortable(tbody, {
        handle: '.drag-handle',
        animation: 150,
        forceFallback: true,
        fallbackClass: 'sortable-fallback',
        fallbackOnBody: true,
        ghostClass: 'bg-blue-50',
        chosenClass: 'bg-blue-100',
        dragClass: 'shadow-lg',

        // 드래그 시작 시
        onStart: function(evt) {
            dragStartX = evt.originalEvent?.clientX || evt.originalEvent?.touches?.[0]?.clientX || 0;
            currentDragItem = evt.item;
            dragIndicator = createDragIndicator();

            // 드래그 중 텍스트 선택 방지
            document.body.classList.add('is-dragging');

            // 그룹 드래그 처리
            groupDragItems = collectGroupItems(currentDragItem);

            if (groupDragItems.length > 1) {
                const draggedId = currentDragItem.dataset.menuId;

                // 드래그 중인 항목 제외한 그룹 항목들 숨기기
                groupDragItems.forEach(row => {
                    if (row !== currentDragItem) {
                        row.classList.add('group-drag-hidden');
                        row.style.display = 'none';
                    }
                });

                // 드래그 항목에 그룹 뱃지 추가
                const badge = document.createElement('span');
                badge.className = 'group-drag-badge';
                badge.textContent = groupDragItems.length + '개 항목';
                const nameCell = currentDragItem.querySelector('td:nth-child(4)');
                if (nameCell) nameCell.appendChild(badge);
            }

            // 마우스 이동 이벤트 리스너 추가
            document.addEventListener('mousemove', onDragMove);
            document.addEventListener('touchmove', onDragMove);
        },

        // 드래그 종료 시 처리
        onEnd: function(evt) {
            // 이벤트 리스너 및 인디케이터 정리
            document.removeEventListener('mousemove', onDragMove);
            document.removeEventListener('touchmove', onDragMove);
            removeDragIndicator();

            // 드래그 중 텍스트 선택 방지 해제
            document.body.classList.remove('is-dragging');

            // 그룹 뱃지 제거
            document.querySelectorAll('.group-drag-badge').forEach(b => b.remove());

            // 숨긴 행 복원
            document.querySelectorAll('.group-drag-hidden').forEach(row => {
                row.classList.remove('group-drag-hidden');
                row.style.display = '';
            });

            const movedItem = evt.item;
            const menuId = parseInt(movedItem.dataset.menuId);
            const oldParentIdRaw = movedItem.dataset.parentId;
            const oldPid = oldParentIdRaw === '' ? null : (oldParentIdRaw ? parseInt(oldParentIdRaw) : null);

            const rows = Array.from(tbody.querySelectorAll('tr.menu-row'));
            const newIndex = rows.indexOf(movedItem);

            // X 이동량 계산
            const dragEndX = evt.originalEvent?.clientX || evt.originalEvent?.changedTouches?.[0]?.clientX || dragStartX;
            const deltaX = dragEndX - dragStartX;

            let newParentId = oldPid;
            let sortOrder = 1;

            // 오른쪽으로 이동 → 인덴트 (위 항목의 자식으로)
            if (deltaX > INDENT_THRESHOLD && newIndex > 0) {
                const prevRow = rows[newIndex - 1];
                if (prevRow) {
                    const prevId = parseInt(prevRow.dataset.menuId);
                    if (prevId !== menuId) {
                        newParentId = prevId;
                    }
                }
            }
            // 왼쪽으로 이동 → 아웃덴트 (부모의 형제로)
            else if (deltaX < -INDENT_THRESHOLD && oldPid !== null) {
                const parentRow = rows.find(r => parseInt(r.dataset.menuId) === oldPid);
                if (parentRow) {
                    const grandParentIdRaw = parentRow.dataset.parentId;
                    newParentId = grandParentIdRaw === '' ? null : (grandParentIdRaw ? parseInt(grandParentIdRaw) : null);
                } else {
                    newParentId = null;
                }
            }

            const parentChanged = oldPid !== newParentId;
            const isGroupDrag = groupDragItems.length > 1;

            // 그룹 드래그인 경우: 모든 체크된 항목의 ID 수집
            const groupMenuIds = isGroupDrag
                ? groupDragItems.map(r => parseInt(r.dataset.menuId))
                : [menuId];

            // 상태 초기화
            groupDragItems = [];
            currentDragItem = null;

            if (parentChanged) {
                // 새 부모 하위에서의 순서 계산
                const existingSiblings = rows.filter(row => {
                    if (row === movedItem) return false;
                    const rowParentId = row.dataset.parentId || '';
                    const rowPid = rowParentId === '' ? null : parseInt(rowParentId);
                    return rowPid === newParentId;
                });

                let siblingsBeforeMe = 0;
                for (const sibling of existingSiblings) {
                    if (rows.indexOf(sibling) < newIndex) {
                        siblingsBeforeMe++;
                    }
                }
                sortOrder = siblingsBeforeMe + 1;

                if (isGroupDrag) {
                    // 그룹 이동: 대표 항목(드래그한 항목)만 이동 후 새로고침
                    // 나머지 체크된 항목도 순차적으로 이동
                    window.moveMenuGroup(groupMenuIds, menuId, newParentId, sortOrder, csrfToken);
                } else {
                    window.moveMenu(menuId, newParentId, sortOrder, csrfToken);
                }
            } else {
                // 같은 레벨 내 순서 변경
                const siblingRows = rows.filter(row => {
                    const rowParentId = row.dataset.parentId || '';
                    const rowPid = rowParentId === '' ? null : parseInt(rowParentId);
                    return rowPid === oldPid;
                });

                const items = siblingRows.map((row, index) => ({
                    id: parseInt(row.dataset.menuId),
                    sort_order: index + 1
                }));

                window.saveMenuOrder(items, csrfToken);
            }
        }
    });
};

// 메뉴 이동 API 호출 (계층 변경)
window.moveMenu = function(menuId, newParentId, sortOrder, csrfToken) {
    fetch('/api/admin/menus/move', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': csrfToken,
            'Accept': 'application/json'
        },
        body: JSON.stringify({
            menu_id: menuId,
            new_parent_id: newParentId,
            sort_order: sortOrder
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            htmx.trigger('#menu-table', 'filterSubmit');
        } else {
            showToast('메뉴 이동 실패: ' + (data.message || ''), 'error');
            htmx.trigger('#menu-table', 'filterSubmit');
        }
    })
    .catch(error => {
        console.error('moveMenu API Error:', error);
        showToast('메뉴 이동 중 오류 발생', 'error');
        htmx.trigger('#menu-table', 'filterSubmit');
    });
};

// 그룹 메뉴 이동 (체크된 항목들 순차 이동)
window.moveMenuGroup = function(groupMenuIds, leadId, newParentId, sortOrder, csrfToken) {
    // 대표 항목 먼저 이동
    const movePromise = fetch('/api/admin/menus/move', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': csrfToken,
            'Accept': 'application/json'
        },
        body: JSON.stringify({
            menu_id: leadId,
            new_parent_id: newParentId,
            sort_order: sortOrder
        })
    }).then(r => r.json());

    // 나머지 항목들도 동일한 부모 아래로 이동 (대표 항목 이후 순서로)
    const otherIds = groupMenuIds.filter(id => id !== leadId);

    if (otherIds.length === 0) {
        movePromise.then(() => htmx.trigger('#menu-table', 'filterSubmit'));
        return;
    }

    movePromise.then(() => {
        // 나머지 항목을 순차적으로 이동
        const promises = otherIds.map((id, idx) =>
            fetch('/api/admin/menus/move', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': csrfToken,
                    'Accept': 'application/json'
                },
                body: JSON.stringify({
                    menu_id: id,
                    new_parent_id: newParentId,
                    sort_order: sortOrder + idx + 1
                })
            }).then(r => r.json())
        );

        return Promise.all(promises);
    })
    .then(() => {
        htmx.trigger('#menu-table', 'filterSubmit');
    })
    .catch(error => {
        console.error('moveMenuGroup error:', error);
        showToast('그룹 이동 중 오류 발생', 'error');
        htmx.trigger('#menu-table', 'filterSubmit');
    });
};

// 메뉴 순서 저장 API 호출 (같은 레벨)
window.saveMenuOrder = function(items, csrfToken) {
    fetch('/api/admin/menus/reorder', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': csrfToken,
            'Accept': 'application/json'
        },
        body: JSON.stringify({ items: items })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            htmx.trigger('#menu-table', 'filterSubmit');
        } else {
            showToast('순서 변경 실패: ' + (data.message || ''), 'error');
            htmx.trigger('#menu-table', 'filterSubmit');
        }
    })
    .catch(error => {
        console.error('Error:', error);
        showToast('순서 변경 중 오류 발생', 'error');
        htmx.trigger('#menu-table', 'filterSubmit');
    });
};
