<?php
// manage_packing_list_items.php - Interaktive Verwaltung der Packlisten-Artikel
// Refactored to "Virtual Table" workflow

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}
if (!isset($_SESSION['user_id'])) {
    header("Location: login.php");
    exit;
}
require_once 'db_connect.php';
require_once 'header.php';

$current_user_id = $_SESSION['user_id'];
$packing_list_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$can_edit = false;

// Lade Packliste und prüfe Berechtigung
$stmt_list = $conn->prepare("SELECT * FROM packing_lists WHERE id = ?");
$stmt_list->bind_param("i", $packing_list_id);
$stmt_list->execute();
$result = $stmt_list->get_result();
if ($result->num_rows === 0) die("Packliste nicht gefunden.");
$packing_list = $result->fetch_assoc();
$stmt_list->close();

$stmt_household = $conn->prepare("SELECT household_id FROM users WHERE id = ?");
$stmt_household->bind_param("i", $current_user_id);
$stmt_household->execute();
$current_user_household_id = $stmt_household->get_result()->fetch_assoc()['household_id'];
$stmt_household->close();

$is_owner = ($packing_list['user_id'] == $current_user_id);
$is_household_list = !empty($packing_list['household_id']);
$is_in_same_household = ($is_household_list && $packing_list['household_id'] == $current_user_household_id);
if ($is_owner || $is_in_same_household) { $can_edit = true; }
if (!$can_edit) { die("Zugriff verweigert."); }

$phase = isset($_GET['phase']) ? intval($_GET['phase']) : 0;
$col_class_lager = ($phase == 1) ? 'col-lg-6' : (($phase == 2) ? 'd-none' : 'col-lg-4');
$col_class_table = ($phase == 1 || $phase == 2) ? 'col-lg-6' : 'col-lg-4';
$col_class_rucksack = ($phase == 2) ? 'col-lg-6' : (($phase == 1) ? 'd-none' : 'col-lg-4');

$phase_title_suffix = ($phase == 1) ? " - Auswahl (Lager)" : (($phase == 2) ? " - Packen (Rucksack)" : "");
$page_title = "Packliste bearbeiten: " . htmlspecialchars($packing_list['name']) . $phase_title_suffix;

$household_member_ids = [$current_user_id];
if ($current_user_household_id) {
    $stmt_members = $conn->prepare("SELECT id FROM users WHERE household_id = ?");
    $stmt_members->bind_param("i", $current_user_household_id);
    $stmt_members->execute();
    $result_members = $stmt_members->get_result();
    while ($row = $result_members->fetch_assoc()) { if (!in_array($row['id'], $household_member_ids)) { $household_member_ids[] = $row['id']; } }
    $stmt_members->close();
}
$placeholders = implode(',', array_fill(0, count($household_member_ids), '?'));
$types = str_repeat('i', count($household_member_ids));

$sql_all_articles = "SELECT a.id, a.name, a.weight_grams, a.quantity_owned, a.product_designation, a.consumable, a.parent_article_id, a.image_url, c.name as category_name, m.name as manufacturer_name, sl.name as storage_location_name 
                  FROM articles a 
                  LEFT JOIN categories c ON a.category_id = c.id
                  LEFT JOIN manufacturers m ON a.manufacturer_id = m.id 
                  LEFT JOIN storage_locations sl ON a.storage_location_id = sl.id
                  WHERE a.user_id IN ($placeholders)";
$all_params = $household_member_ids;
$all_types = $types;
if ($current_user_household_id) {
    $sql_all_articles .= " OR a.household_id = ?";
    $all_params[] = $current_user_household_id;
    $all_types .= 'i';
}
$stmt_all_articles = $conn->prepare($sql_all_articles);
$stmt_all_articles->bind_param($all_types, ...$all_params);
$stmt_all_articles->execute();
$all_articles_raw = $stmt_all_articles->get_result()->fetch_all(MYSQLI_ASSOC);
$stmt_all_articles->close();

$sql_items = "SELECT pli.id, pli.article_id, pli.quantity, pli.parent_packing_list_item_id, pli.carrier_user_id, pli.backpack_id, pli.backpack_compartment_id, 
COALESCE(
    a.name, 
    bc.name,
    CASE WHEN b.name IS NOT NULL THEN CONCAT('Rucksack: ', b.name) ELSE NULL END,
    pli.name
) as name, 
a.weight_grams, a.product_designation, a.consumable, m.name as manufacturer_name 
FROM packing_list_items pli 
LEFT JOIN articles a ON pli.article_id = a.id 
LEFT JOIN manufacturers m ON a.manufacturer_id = m.id 
LEFT JOIN backpacks b ON pli.backpack_id = b.id
LEFT JOIN backpack_compartments bc ON pli.backpack_compartment_id = bc.id
WHERE pli.packing_list_id = ? 
ORDER BY pli.order_index ASC";

$stmt_items = $conn->prepare($sql_items);
$stmt_items->bind_param("i", $packing_list_id);
$stmt_items->execute();
$packed_items_raw = $stmt_items->get_result()->fetch_all(MYSQLI_ASSOC);
$stmt_items->close();

$carriers_data = [];
$stmt_carriers = $conn->prepare("SELECT u.id, u.username FROM users u JOIN packing_list_carriers plc ON u.id = plc.user_id WHERE plc.packing_list_id = ? ORDER BY u.username");
$stmt_carriers->bind_param("i", $packing_list_id);
$stmt_carriers->execute();
$carriers_result = $stmt_carriers->get_result();
while ($row = $carriers_result->fetch_assoc()) { $carriers_data[] = $row; }
$stmt_carriers->close();

$categories = array_unique(array_filter(array_column($all_articles_raw, 'category_name')));
sort($categories);
$manufacturers = array_unique(array_filter(array_column($all_articles_raw, 'manufacturer_name')));
sort($manufacturers);

$conn->close();
?>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/tom-select@2.2.2/dist/css/tom-select.bootstrap5.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/tom-select@2.2.2/dist/js/tom-select.complete.min.js"></script>

<style>
    .nested-sortable {
        min-height: 10px;
        padding-left: 20px;
        border-left: 2px solid rgba(0,0,0,0.05);
        margin-top: 5px;
    }
    .table-nested-sortable {
        min-height: 100px;
        padding: 10px;
        background: rgba(0,0,0,0.02);
        border: 1px dashed rgba(0,0,0,0.1);
        border-radius: 6px;
    }
    .packed-item-container { margin-bottom: 5px; }
    .packed-item-content {
        display: flex; align-items: center; padding: 8px;
        background-color: #fff; border: 1px solid rgba(0,0,0,0.1);
        border-radius: 6px; transition: box-shadow 0.2s;
    }
    .packed-item-content:hover { box-shadow: 0 2px 5px rgba(0,0,0,0.05); }
    .nested-sortable.sortable-ghost {
        background-color: rgba(59, 74, 35, 0.1); border: 1px dashed var(--color-primary);
    }
    .nested-sortable:empty {
        min-height: 30px; background-color: rgba(0,0,0,0.02);
        border: 1px dashed rgba(0,0,0,0.1); border-radius: 4px; margin-top: 5px;
    }
    .backpack-root-item { background-color: #e8f5e9; border: 1px solid #2e7d32; }
    .compartment-item { background-color: #f1f8e9; border-left: 3px solid #7cb342; }

    /* Lager Grid */
    .lager-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
        gap: 12px; padding: 5px;
    }
    .lager-card {
        border: 1px solid #eee; border-radius: 8px; padding: 12px;
        text-align: center; background: #fff; display: flex; flex-direction: column;
        transition: transform 0.1s, box-shadow 0.1s;
    }
    .lager-card:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.05); }
    .lager-img-wrapper {
        height: 220px; margin-bottom: 8px; display: flex;
        align-items: center; justify-content: center;
    }
    .lager-img-wrapper img {
        max-height: 100%; max-width: 100%; object-fit: contain; border-radius: 4px; cursor: pointer;
    }
    .lager-title {
        font-size: 0.85em; font-weight: 600; margin-bottom: 4px;
        line-height: 1.2; flex-grow: 1; word-wrap: break-word;
    }
    .lager-controls {
        display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 8px;
    }
    .table-status-text {
        font-size: 0.75em; color: #2e7d32; font-weight: 600;
        min-height: 1.2em; margin-top: 6px; visibility: hidden;
    }
    .table-status-text.visible { visibility: visible; }
    
    .editor-pane { display: flex; flex-direction: column; height: 100%; }
    .pane-content { flex-grow: 1; overflow-y: auto; padding: 10px; }
    
    /* Remove empty dropzone on the table specifically */
    #table-container > .packed-item-container > .nested-sortable:empty {
        min-height: 0;
        border: none;
        background: transparent;
        margin: 0;
    }
    #table-container > .packed-item-container > .nested-sortable:empty::after {
        display: none;
    }
    
    /* Grab cursor for items */
    .packed-item-content { cursor: grab; }
    .packed-item-content:active { cursor: grabbing; }
</style>

<div class="card mb-3">
    <div class="card-header d-flex justify-content-between align-items-center">
        <h2 class="h4 mb-0"><i class="fas fa-edit me-2"></i><?php echo $page_title; ?></h2>
        <div>
            <?php if($phase == 1): ?>
                <a href="manage_packing_list_items.php?id=<?php echo $packing_list_id; ?>&phase=2" class="btn btn-success"><i class="fas fa-arrow-right me-2"></i>Weiter zu Phase 2 (Packen)</a>
            <?php elseif($phase == 2): ?>
                <a href="manage_packing_list_items.php?id=<?php echo $packing_list_id; ?>&phase=1" class="btn btn-info text-white"><i class="fas fa-arrow-left me-2"></i>Zurück zu Phase 1 (Auswahl)</a>
                <a href="packing_list_detail.php?id=<?php echo $packing_list_id; ?>" class="btn btn-secondary ms-2"><i class="fas fa-check me-2"></i>Fertig</a>
            <?php else: ?>
                <a href="packing_list_detail.php?id=<?php echo $packing_list_id; ?>" class="btn btn-secondary"><i class="fas fa-eye me-2"></i>Zur Ansicht</a>
            <?php endif; ?>
        </div>
    </div>
</div>

<div class="row g-3" style="height: 75vh; min-height: 600px;">
    <!-- LAGER -->
    <div class="<?php echo $col_class_lager; ?> h-100">
        <div class="card h-100">
            <div class="card-header bg-light">
                <h5 class="mb-2"><i class="fas fa-boxes me-2"></i>Lagerbestand</h5>
                <div class="row g-2">
                    <div class="col-12"><input type="text" id="filter-text" class="form-control form-control-sm" placeholder="Artikel suchen..."></div>
                    <div class="col-sm-6 col-md-3"><select id="filter-category" class="form-select form-select-sm"><option value="">-- Kategorien --</option><?php foreach($categories as $c) echo '<option>'.htmlspecialchars($c).'</option>'; ?></select></div>
                    <div class="col-sm-6 col-md-3"><select id="filter-manufacturer" class="form-select form-select-sm"><option value="">-- Hersteller --</option><?php foreach($manufacturers as $m) echo '<option>'.htmlspecialchars($m).'</option>'; ?></select></div>
                    <div class="col-sm-6 col-md-3"><select id="group-by" class="form-select form-select-sm"><option value="">Keine Gruppe</option><option value="category_name">Kategorie</option><option value="manufacturer_name">Hersteller</option><option value="storage_location_name">Lagerort</option></select></div>
                    <div class="col-sm-6 col-md-3"><select id="sort-by" class="form-select form-select-sm"><option value="name_asc">Alphabet (A-Z)</option><option value="weight_asc">Gewicht (Leicht->Schwer)</option><option value="weight_desc">Gewicht (Schwer->Leicht)</option><option value="quantity_desc">Anzahl (Viele->Wenige)</option></select></div>
                </div>
            </div>
            <div class="card-body pane-content" id="lager-container"></div>
        </div>
    </div>

    <!-- TISCH -->
    <div class="<?php echo $col_class_table; ?> h-100">
        <div class="card h-100 border-info">
            <div class="card-header bg-info text-white">
                <h5 class="mb-0"><i class="fas fa-table me-2"></i>Auf dem Tisch</h5>
            </div>
            <div class="card-body pane-content table-nested-sortable" id="table-container" data-carrier-id="null">
                <!-- Items dropped here get carrier_id=null -->
            </div>
        </div>
    </div>

    <!-- RUCKSACK -->
    <div class="<?php echo $col_class_rucksack; ?> h-100">
        <div class="card h-100 border-success">
            <div class="card-header bg-success text-white">
                <h5 class="mb-0"><i class="fas fa-backpack me-2"></i>Rucksäcke</h5>
            </div>
            <div class="card-body pane-content" id="carriers-container"></div>
        </div>
    </div>
</div>

<div class="modal fade" id="includeChildrenModal" tabindex="-1" aria-labelledby="includeChildrenModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="includeChildrenModalLabel">Komponenten hinzufügen</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        Dieser Artikel hat zugehörige Komponenten. Sollen diese ebenfalls auf den Tisch gelegt werden?
        <ul id="children-list" class="list-group mt-2 mb-2"></ul>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" id="add-without-children">Nein, nur diesen Artikel</button>
        <button type="button" class="btn btn-primary" id="add-with-children">Ja, alle auf den Tisch</button>
      </div>
    </div>
  </div>
</div>

<div id="save-feedback" class="save-feedback">Änderungen gespeichert!</div>
<div id="image-preview-tooltip" class="image-preview-tooltip"></div>

<script>
    let packedItems = <?php echo json_encode($packed_items_raw); ?>;
    const allArticles = <?php echo json_encode($all_articles_raw); ?>;
    const carriers = <?php echo json_encode($carriers_data); ?>;
    const packingListId = <?php echo $packing_list_id; ?>;
    let sortableInstances = {};
    let childrenModal = null;
    let pendingArticleIdForTable = null;

    document.addEventListener('DOMContentLoaded', () => {
        const tsOptions = { create: false, sortField: { field: "text", direction: "asc" }, allowEmptyOption: true, onChange: function() { this.input.dispatchEvent(new Event('change')); } };
        new TomSelect('#filter-category', tsOptions);
        new TomSelect('#filter-manufacturer', tsOptions);
        new TomSelect('#group-by', tsOptions);
        new TomSelect('#sort-by', { create: false, allowEmptyOption: false, onChange: function() { this.input.dispatchEvent(new Event('change')); } });

        const tooltip = document.getElementById('image-preview-tooltip');
        if (tooltip) {
            document.body.addEventListener('mouseover', e => {
                if (e.target.classList.contains('article-image-trigger')) {
                    const url = e.target.getAttribute('data-preview-url');
                    if (url && !url.endsWith('assets/images/keinbild.png')) {
                        tooltip.style.backgroundImage = `url('${url}')`;
                        tooltip.style.display = 'block';
                    }
                }
            });
            document.body.addEventListener('mousemove', e => {
                if (tooltip.style.display === 'block') {
                    tooltip.style.left = e.pageX + 15 + 'px'; tooltip.style.top = e.pageY + 15 + 'px';
                }
            });
            document.body.addEventListener('mouseout', e => {
                if (e.target.classList.contains('article-image-trigger')) tooltip.style.display = 'none';
            });
        }

        ['input', 'change'].forEach(evt => {
            document.getElementById('filter-text').addEventListener(evt, renderLager);
            document.getElementById('filter-category').addEventListener(evt, renderLager);
            document.getElementById('filter-manufacturer').addEventListener(evt, renderLager);
            document.getElementById('group-by').addEventListener(evt, renderLager);
            document.getElementById('sort-by').addEventListener(evt, renderLager);
        });

        document.getElementById('table-container').addEventListener('click', handlePackedItemActions);
        document.getElementById('carriers-container').addEventListener('click', handlePackedItemActions);
        document.getElementById('table-container').addEventListener('change', handleQuantityChange);
        document.getElementById('carriers-container').addEventListener('change', handleQuantityChange);
        
        fullRender();
    });

    function fullRender() {
        renderLager();
        renderTable();
        renderCarriersAndPackedItems();
    }
    
    function renderLager() {
        const filterText = document.getElementById('filter-text').value.toLowerCase();
        const filterCategory = document.getElementById('filter-category').value;
        const filterManufacturer = document.getElementById('filter-manufacturer').value;
        const groupBy = document.getElementById('group-by').value;
        const sortBy = document.getElementById('sort-by').value;
        
        const tableQuantities = {};
        const backpackQuantities = {};
        
        packedItems.forEach(item => {
            const aid = String(item.article_id);
            const qty = parseInt(item.quantity || 1, 10);
            const isTable = (item.carrier_user_id == null && !item.backpack_id && !item.backpack_compartment_id && !item.parent_packing_list_item_id);
            if (isTable) {
                tableQuantities[aid] = (tableQuantities[aid] || 0) + qty;
            } else {
                backpackQuantities[aid] = (backpackQuantities[aid] || 0) + qty;
            }
        });

        let groups = {};

        let sortedArticles = [...allArticles];
        sortedArticles.sort((a, b) => {
            if (sortBy === 'name_asc') return a.name.localeCompare(b.name);
            if (sortBy === 'weight_asc') return parseInt(a.weight_grams) - parseInt(b.weight_grams);
            if (sortBy === 'weight_desc') return parseInt(b.weight_grams) - parseInt(a.weight_grams);
            if (sortBy === 'quantity_desc') return parseInt(b.quantity_owned || 1) - parseInt(a.quantity_owned || 1);
            return 0;
        });

        sortedArticles.forEach(article => {
            if (article.parent_article_id) return;
            
            const matchesText = article.name.toLowerCase().includes(filterText) || (article.manufacturer_name && article.manufacturer_name.toLowerCase().includes(filterText)) || (article.product_designation && article.product_designation.toLowerCase().includes(filterText));
            const matchesCategory = !filterCategory || article.category_name === filterCategory;
            const matchesManufacturer = !filterManufacturer || article.manufacturer_name === filterManufacturer;
            
            if (matchesText && matchesCategory && matchesManufacturer) {
                const aid = String(article.id);
                const qtyTable = tableQuantities[aid] || 0;
                const qtyBackpack = backpackQuantities[aid] || 0;
                const qtyTotal = qtyTable + qtyBackpack;
                const ownedQty = parseInt(article.quantity_owned || 1, 10);
                const isConsumable = article.consumable == 1;
                
                const disablePlus = !isConsumable && qtyTotal >= ownedQty;
                const disableMinus = qtyTable <= 0;
                
                const imgUrl = article.image_url ? article.image_url : 'assets/images/keinbild.png';
                const plusBtnClass = qtyTable > 0 ? 'btn-success' : 'btn-outline-primary';
                
                const cardHtml = `
                <div class="lager-card">
                    <div class="lager-img-wrapper">
                        <img src="${imgUrl}" class="article-image-trigger" data-preview-url="${imgUrl}">
                    </div>
                    <div class="lager-title">${article.name}</div>
                    <small class="text-muted d-block mb-1">${article.weight_grams}g</small>
                    <div class="lager-controls">
                        <button class="btn btn-sm btn-outline-secondary" onclick="adjustTable(${aid}, -1)" ${disableMinus ? 'disabled' : ''}><i class="fas fa-minus"></i></button>
                        <button class="btn btn-sm ${plusBtnClass}" onclick="triggerAddTable(${aid})" ${disablePlus ? 'disabled' : ''}><i class="fas fa-plus"></i></button>
                    </div>
                    <div class="table-status-text ${qtyTable > 0 ? 'visible' : ''}">
                        ${qtyTable} auf dem Tisch
                    </div>
                </div>`;
                
                let groupKey = groupBy ? (article[groupBy] || 'Ohne Zuordnung') : 'Alle Artikel';
                if (!groups[groupKey]) groups[groupKey] = '';
                groups[groupKey] += cardHtml;
            }
        });

        let html = '';
        Object.keys(groups).sort().forEach(key => {
            if (groupBy) html += `<h6 class="w-100 mt-3 mb-2 ps-2 border-bottom pb-1 text-secondary">${key}</h6>`;
            html += `<div class="lager-grid">${groups[key]}</div>`;
        });
        document.getElementById('lager-container').innerHTML = html;
    }

    function triggerAddTable(articleId) {
        const aidStr = String(articleId);
        const childArticles = allArticles.filter(a => String(a.parent_article_id) === aidStr);
        if (childArticles.length > 0) {
            pendingArticleIdForTable = articleId;
            if (!childrenModal) childrenModal = new bootstrap.Modal(document.getElementById('includeChildrenModal'));
            document.getElementById('children-list').innerHTML = childArticles.map(c => `<li class="list-group-item py-1">${c.name} <small class="text-muted">(${c.weight_grams}g)</small></li>`).join('');
            
            document.getElementById('add-with-children').onclick = () => {
                childrenModal.hide();
                adjustTable(pendingArticleIdForTable, 1, true);
            };
            document.getElementById('add-without-children').onclick = () => {
                childrenModal.hide();
                adjustTable(pendingArticleIdForTable, 1, false);
            };
            childrenModal.show();
        } else {
            adjustTable(articleId, 1, false);
        }
    }

    function adjustTable(articleId, delta, includeChildren = false) {
        sendApiRequest({ action: 'adjust_table_quantity', article_id: articleId, delta: delta, include_children: includeChildren })
        .then(() => {
            return fetch('api_packing_list_handler.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ action: 'get_items', packing_list_id: packingListId }) // Fallback to get items
            });
        })
        .then(res => res.json())
        .then(newItems => {
            if(Array.isArray(newItems)) packedItems = newItems;
            // Restore scroll positions
            const panes = document.querySelectorAll('.pane-content');
            const scrollMap = Array.from(panes).map(p => p.scrollTop);
            fullRender();
            Array.from(panes).forEach((p, i) => { if (scrollMap[i] !== undefined) p.scrollTop = scrollMap[i]; });
        });
    }

    function renderTable() {
        const container = document.getElementById('table-container');
        
        Object.keys(sortableInstances).forEach(k => {
            if (k === 'table' || k.startsWith('table_nested_')) {
                if(sortableInstances[k]) {
                    try { sortableInstances[k].destroy(); } catch(e){}
                }
                delete sortableInstances[k];
            }
        });
        
        container.innerHTML = '';
        
        const tableItems = packedItems.filter(item => item.carrier_user_id == null && !item.backpack_id && !item.backpack_compartment_id && !item.parent_packing_list_item_id);
        
        renderRecursive(tableItems, container, packedItems, 'table_');

        sortableInstances['table'] = new Sortable(container, {
            group: 'nested',
            animation: 150,
            handle: '.packed-item-content',
            fallbackOnBody: true,
            swapThreshold: 0.65,
            ghostClass: 'sortable-ghost',
            onEnd: function() { syncListState(); }
        });
    }

    function renderCarriersAndPackedItems() {
        const container = document.getElementById('carriers-container');
        
        Object.keys(sortableInstances).forEach(k => {
            if (k.startsWith('carrier_')) {
                if(sortableInstances[k]) {
                    try { sortableInstances[k].destroy(); } catch(e){}
                }
                delete sortableInstances[k];
            }
        });
        
        container.innerHTML = '';

        carriers.forEach(carrier => {
            const carrierId = carrier.id; // Sonstiges removed, so carrier.id is never null
            const carrierDiv = document.createElement('div');
            carrierDiv.className = 'carrier-box mb-3';
            carrierDiv.innerHTML = `<div class="p-2 bg-light border rounded mb-2 fw-bold text-dark"><i class="fas fa-user me-2"></i>${carrier.username}</div>`;
            
            const carrierRootList = document.createElement('div');
            carrierRootList.className = 'carrier-list nested-sortable pb-3';
            carrierRootList.dataset.carrierId = carrierId;
            carrierDiv.appendChild(carrierRootList);
            container.appendChild(carrierDiv);

            const itemsForCarrier = packedItems.filter(item => String(item.carrier_user_id) === String(carrierId));
            const itemsById = itemsForCarrier.reduce((acc, item) => ({...acc, [item.id]: {...item, children: []}}), {});
            const rootItems = [];
            
            Object.values(itemsById).forEach(item => {
                if (item.parent_packing_list_item_id && itemsById[item.parent_packing_list_item_id]) {
                    itemsById[item.parent_packing_list_item_id].children.push(item);
                } else {
                    rootItems.push(item);
                }
            });

            renderRecursive(rootItems, carrierRootList, itemsById, 'carrier_');
            
            sortableInstances['carrier_'+carrierId] = new Sortable(carrierRootList, {
                group: 'nested',
                animation: 150,
                handle: '.packed-item-content',
                fallbackOnBody: true,
                swapThreshold: 0.65,
                ghostClass: 'sortable-ghost',
                onEnd: function() { syncListState(); }
            });
        });
    }

    function renderRecursive(items, container, contextMap, prefix) {
        items.forEach(item => {
            let children = item.children || [];
            if (!item.children && Array.isArray(contextMap)) {
               children = contextMap.filter(i => i.parent_packing_list_item_id === item.id);
            }
            
            const itemEl = createPackedItemDOM(item);
            container.appendChild(itemEl);
            const nestedContainer = itemEl.querySelector('.nested-sortable');
            if (children && children.length > 0) {
                renderRecursive(children, nestedContainer, contextMap, prefix);
            }
            
            sortableInstances[prefix + 'nested_'+item.id] = new Sortable(nestedContainer, {
                group: 'nested', animation: 150, handle: '.packed-item-content',
                fallbackOnBody: true, swapThreshold: 0.65, ghostClass: 'sortable-ghost',
                onEnd: function() { syncListState(); }
            });
        });
    }

    function createPackedItemDOM(item) {
        const div = document.createElement('div');
        div.className = 'packed-item-container';
        div.dataset.itemId = item.id;
        div.dataset.articleId = item.article_id;
        if(item.backpack_id) div.dataset.backpackId = item.backpack_id;
        if(item.backpack_compartment_id) div.dataset.backpackCompartmentId = item.backpack_compartment_id;
        
        let contentClass = 'packed-item-content';
        let iconClass = 'fas fa-grip-vertical handle text-secondary';
        let nameDisplay = item.name;
        let metaDisplay = item.manufacturer_name ? `<small class="text-muted">(${item.manufacturer_name})</small>` : '';
        let controls = `
            <input type="number" class="form-control form-control-sm quantity-input text-center mx-2" value="${item.quantity}" min="1" style="width:60px;">
            <button class="btn btn-sm btn-outline-danger remove-item-btn"><i class="fas fa-trash"></i></button>
        `;

        if (item.backpack_id) {
            contentClass += ' backpack-root-item';
            iconClass = 'fas fa-hiking handle me-2 text-success';
            nameDisplay = `<strong>${item.name}</strong>`;
            metaDisplay = ''; controls = ''; 
        } else if (item.backpack_compartment_id) {
            contentClass += ' compartment-item';
            iconClass = 'fas fa-folder-open handle me-2 text-success';
            nameDisplay = `<span class="fw-bold text-dark">${item.name}</span>`;
            metaDisplay = ''; controls = '';
        }

        div.innerHTML = `
            <div class="${contentClass}">
                <i class="${iconClass}"></i>
                <span class="item-name ms-2">${nameDisplay} ${metaDisplay}</span>
                <div class="item-controls ms-auto d-flex align-items-center">
                    ${controls}
                </div>
            </div>
            <div class="nested-sortable"></div>
        `;
        return div;
    }

    let syncTimeout = null;
    function syncListState() {
        if (syncTimeout) clearTimeout(syncTimeout);
        syncTimeout = setTimeout(() => {
            const payload = { action: 'sync_list', list: [] };
            
            function traverse(container, carrierId, parentId) {
                Array.from(container.children).forEach(child => {
                    if (!child.classList.contains('packed-item-container')) return;
                    const pliId = child.dataset.itemId;
                    const articleId = child.dataset.articleId;
                    
                    payload.list.push({
                        pli_id: pliId,
                        article_id: articleId,
                        carrier_id: carrierId,
                        parent_pli_id: parentId,
                        backpack_id: child.dataset.backpackId || null,
                        backpack_compartment_id: child.dataset.backpackCompartmentId || null
                    });
                    
                    const nestedContainer = child.querySelector('.nested-sortable');
                    if (nestedContainer) traverse(nestedContainer, carrierId, pliId);
                });
            }
            
            const tableList = document.getElementById('table-container');
            if (tableList) traverse(tableList, 'null', null);
            
            document.querySelectorAll('.carrier-list').forEach(rootList => {
                const carrierId = rootList.dataset.carrierId;
                traverse(rootList, carrierId, null);
            });
            
            sendApiRequest(payload).then(newItems => {
                if(Array.isArray(newItems)) packedItems = newItems;
                const panes = document.querySelectorAll('.pane-content');
                const scrollMap = Array.from(panes).map(p => p.scrollTop);
                fullRender();
                Array.from(panes).forEach((p, i) => { if (scrollMap[i] !== undefined) p.scrollTop = scrollMap[i]; });
            }).catch(err => {
                console.error("Sync failed:", err);
                alert("Fehler beim Speichern! Bitte Seite neu laden.");
            });
        }, 300);
    }

    function handlePackedItemActions(e) {
        const button = e.target.closest('button');
        if (!button) return;
        const itemEl = button.closest('.packed-item-container');
        if (!itemEl) return;
        const itemId = itemEl.dataset.itemId;
        
        if (button.classList.contains('remove-item-btn')) {
            if (confirm('Diesen Artikel wirklich aus der Liste entfernen?')) {
                itemEl.remove();
                sendApiRequest({ action: 'delete_item', item_id: itemId }).then(newItems => {
                    if(Array.isArray(newItems)) packedItems = newItems;
                    fullRender();
                });
            }
        }
    }
    
    function handleQuantityChange(e) {
        const input = e.target;
        if (input.classList.contains('quantity-input')) {
            const itemEl = input.closest('.packed-item-container');
            const itemId = itemEl.dataset.itemId;
            const newQuantity = input.value;
            clearTimeout(input.dataset.timeout);
            input.dataset.timeout = setTimeout(() => {
                sendApiRequest({ action: 'update_quantity', item_id: itemId, quantity: newQuantity }).then(newItems => {
                     if(Array.isArray(newItems)) packedItems = newItems;
                     fullRender();
                });
            }, 500);
        }
    }

    async function sendApiRequest(data) {
        data.packing_list_id = packingListId;
        try {
            const response = await fetch('api_packing_list_handler.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(data)
            });
            if (!response.ok) {
                const errorData = await response.json().catch(() => ({error: 'Serverfehler'}));
                console.error(errorData);
                return Promise.reject(errorData);
            }
            const json = await response.json();
            if (data.action !== 'update_quantity' && data.action !== 'get_items') {
                 const fb = document.getElementById('save-feedback');
                 fb.style.opacity = '1';
                 setTimeout(() => { fb.style.opacity = '0'; }, 1500);
            }
            return json;
        } catch(error) {
            console.error(error);
            return Promise.reject(error);
        }
    }
</script>

<?php require_once 'footer.php'; ?>