<?php
// manage_packing_list_items.php - Interaktive Verwaltung der Packlisten-Artikel
// FINALE, REKURSIVE NESTED-SORTABLE VERSION

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."); }

$page_title = "Packliste bearbeiten: " . htmlspecialchars($packing_list['name']);

$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 
                  FROM articles a 
                  LEFT JOIN categories c ON a.category_id = c.id
                  LEFT JOIN manufacturers m ON a.manufacturer_id = m.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 = [];
// KORREKTUR: Nur Träger anzeigen, die dieser Liste zugewiesen sind
$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();
$carriers_data[] = ['id' => null, 'username' => 'Sonstiges'];

$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>
<!-- Tom Select CSS/JS -->
<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>

<div class="card">
    <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>Packliste bearbeiten: <?php echo htmlspecialchars($packing_list['name']); ?></h2>
        <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>
    </div>
    <div class="card-body">
        <div class="editor-container">
            <div class="editor-pane">
                <div class="pane-header">
                    <h5 class="mb-0">Verfügbare Artikel</h5>
                    <div class="row g-2 mt-2">
                        <div class="col-12"><input type="text" id="filter-text" class="form-control form-control-sm" placeholder="Artikel, Hersteller, Modell suchen..."></div>
                        <div class="col-md-6"><select id="filter-category" class="form-select form-select-sm"><option value="">-- Alle Kategorien --</option><?php foreach($categories as $c) echo '<option>'.htmlspecialchars($c).'</option>'; ?></select></div>
                        <div class="col-md-6"><select id="filter-manufacturer" class="form-select form-select-sm"><option value="">-- Alle Hersteller --</option><?php foreach($manufacturers as $m) echo '<option>'.htmlspecialchars($m).'</option>'; ?></select></div>
                    </div>
                </div>
                <div class="pane-content" id="available-items-list"></div>
            </div>
            <div class="editor-pane">
                <div class="pane-header"><h5 class="mb-0">Gepackte Artikel</h5></div>
                <div class="pane-content" id="carriers-container"></div>
            </div>
        </div>
    </div>
</div>

<!-- Modals and Feedback remain unchanged -->
<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 zur Packliste hinzugefügt werden?
        <ul id="children-list" class="list-group mt-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 hinzufügen</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>

<style>
    /* Nested Sortable Specific Styles */
    .nested-sortable {
        min-height: 10px;
        padding-left: 20px; /* Indent child items */
        border-left: 2px solid rgba(0,0,0,0.05);
        margin-top: 5px;
    }
    .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);
    }
    /* Highlight drop targets */
    .nested-sortable.sortable-ghost {
        background-color: rgba(59, 74, 35, 0.1);
        border: 1px dashed var(--color-primary);
    }
    /* Empty nested containers should have a hint of height to be droppable */
    .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;
    }
    .nested-sortable:empty::after {
        content: 'Hier ablegen';
        display: block;
        text-align: center;
        color: #aaa;
        font-size: 0.8em;
        padding-top: 5px;
    }
    
    /* Backpack & Compartment Styles */
    .backpack-root-item {
        background-color: #e8f5e9;
        border: 1px solid #2e7d32;
    }
    .compartment-item {
        background-color: #f1f8e9;
        border-left: 3px solid #7cb342;
    }
</style>

<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;

    document.addEventListener('DOMContentLoaded', () => {
        // Initialize Tom Select for filters with allowEmptyOption
        const tsOptions = {
            create: false,
            sortField: { field: "text", direction: "asc" },
            allowEmptyOption: true,
            onChange: function(value) {
                // Propagate change
                this.input.dispatchEvent(new Event('change'));
            }
        };
        new TomSelect('#filter-category', tsOptions);
        new TomSelect('#filter-manufacturer', tsOptions);

        // Tooltip Logic
        const tooltip = document.getElementById('image-preview-tooltip');
        if (tooltip) {
            // Delegation for dynamically added items
            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, renderAvailableItems);
            document.getElementById('filter-category').addEventListener(evt, renderAvailableItems);
            document.getElementById('filter-manufacturer').addEventListener(evt, renderAvailableItems);
        });
        document.getElementById('carriers-container').addEventListener('click', handlePackedItemActions);
        document.getElementById('carriers-container').addEventListener('change', handleQuantityChange);
        fullRender();
    });

    function fullRender() {
        renderAvailableItems();
        renderCarriersAndPackedItems();
    }
    
    function renderAvailableItems() {
        const filterText = document.getElementById('filter-text').value.toLowerCase();
        const filterCategory = document.getElementById('filter-category').value;
        const filterManufacturer = document.getElementById('filter-manufacturer').value;
        const availableListEl = document.getElementById('available-items-list');
        
        const packedQuantities = {};
        packedItems.forEach(item => {
            const aid = String(item.article_id);
            packedQuantities[aid] = (packedQuantities[aid] || 0) + parseInt(item.quantity || 1, 10);
        });

        let html = '';
        allArticles.forEach(article => {
            if (article.parent_article_id) return;
            
            const aid = String(article.id);
            const packedQty = packedQuantities[aid] || 0;
            const ownedQty = parseInt(article.quantity_owned || 1, 10);
            const isConsumable = article.consumable == 1;

            if (isConsumable || packedQty < ownedQty) {
                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 details = [article.manufacturer_name, article.product_designation].filter(Boolean).join(' - ');
                     const imgUrl = article.image_url ? article.image_url : 'assets/images/keinbild.png';
                     html += `
                        <div class="available-item-card d-flex align-items-center" data-article-id="${article.id}">
                            <img src="${imgUrl}" class="article-image-trigger me-2 rounded" style="width: 30px; height: 30px; object-fit: cover; cursor: pointer;" data-preview-url="${imgUrl}">
                            <div class="flex-grow-1">
                                ${article.name} 
                                <small class="text-muted d-block" style="line-height: 1;">(${details || '---'} | ${article.weight_grams}g)</small>
                            </div>
                        </div>`;
                }
            }
        });
        availableListEl.innerHTML = html;
        
        new Sortable(availableListEl, {
            group: { name: 'nested', pull: 'clone', put: false },
            animation: 150,
            sort: false
        });
    }

    function renderCarriersAndPackedItems() {
        const container = document.getElementById('carriers-container');
        container.innerHTML = '';
        
        sortableInstances.forEach(s => s.destroy());
        sortableInstances = [];

        carriers.forEach(carrier => {
            const carrierId = carrier.id === null ? 'null' : carrier.id;
            const carrierDiv = document.createElement('div');
            carrierDiv.className = 'carrier-box';
            carrierDiv.innerHTML = `<div class="carrier-header"><h6>${carrier.username}</h6></div>`;
            
            const carrierRootList = document.createElement('div');
            carrierRootList.className = 'carrier-list nested-sortable';
            carrierRootList.dataset.carrierId = carrierId;
            carrierDiv.appendChild(carrierRootList);
            container.appendChild(carrierDiv);

            const itemsForCarrier = packedItems.filter(item => (item.carrier_user_id === null ? 'null' : 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);
            initNestedSortable(carrierRootList);
        });
    }

    function renderRecursive(items, container) {
        items.forEach(item => {
            const itemEl = createPackedItemDOM(item);
            container.appendChild(itemEl);
            const nestedContainer = itemEl.querySelector('.nested-sortable');
            if (item.children && item.children.length > 0) {
                renderRecursive(item.children, nestedContainer);
            }
            initNestedSortable(nestedContainer);
        });
    }

    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';
        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">
            <button class="btn btn-sm btn-outline-danger remove-item-btn"><i class="fas fa-trash"></i></button>
        `;

        // Special styling for Containers
        if (item.backpack_id) {
            contentClass += ' backpack-root-item';
            iconClass = 'fas fa-hiking handle me-2';
            nameDisplay = `<strong>${item.name}</strong>`;
            metaDisplay = '';
            // Disable controls for structural items
            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 = '';
            // Disable controls for structural items
            controls = '';
        }

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

    function initNestedSortable(element) {
        const s = new Sortable(element, {
            group: 'nested',
            animation: 150,
            handle: '.handle',
            fallbackOnBody: true,
            swapThreshold: 0.65,
            ghostClass: 'sortable-ghost',
            onAdd: function (evt) {
                if (evt.from.id === 'available-items-list') {
                    const articleId = evt.item.dataset.articleId;
                    const originalArticleData = allArticles.find(a => String(a.id) === articleId);
                    
                    const newItemData = {
                        id: 'new-' + Date.now(),
                        article_id: articleId,
                        name: originalArticleData.name,
                        manufacturer_name: originalArticleData.manufacturer_name,
                        quantity: 1,
                        consumable: originalArticleData.consumable,
                        children: []
                    };
                    
                    const newDOM = createPackedItemDOM(newItemData);
                    evt.item.replaceWith(newDOM);
                    initNestedSortable(newDOM.querySelector('.nested-sortable'));
                    
                    const childArticles = allArticles.filter(a => String(a.parent_article_id) === articleId);
                    if (childArticles.length > 0) {
                        handleChildArticlesPrompt(childArticles, newDOM);
                    } else {
                        syncListState();
                    }
                } else {
                    syncListState();
                }
            },
            onEnd: function (evt) {
                if (evt.from.id !== 'available-items-list') {
                    syncListState();
                }
            }
        });
        sortableInstances.push(s);
    }

    function handleChildArticlesPrompt(childArticles, parentElement) {
        if (!childrenModal) childrenModal = new bootstrap.Modal(document.getElementById('includeChildrenModal'));
        document.getElementById('children-list').innerHTML = childArticles.map(c => `<li class="list-group-item">${c.name}</li>`).join('');
        
        document.getElementById('add-with-children').onclick = () => {
            childrenModal.hide();
            const nestedContainer = parentElement.querySelector('.nested-sortable');
            childArticles.forEach(child => {
                const childItemData = {
                    id: 'new-child-' + Date.now() + Math.random(),
                    article_id: child.id,
                    name: child.name,
                    manufacturer_name: child.manufacturer_name,
                    quantity: 1,
                    consumable: child.consumable,
                    children: []
                };
                const childDOM = createPackedItemDOM(childItemData);
                nestedContainer.appendChild(childDOM);
                initNestedSortable(childDOM.querySelector('.nested-sortable'));
            });
            syncListState();
        };
        
        document.getElementById('add-without-children').onclick = () => {
            childrenModal.hide();
            syncListState();
        };
        childrenModal.show();
    }

    function syncListState() {
        const payload = { action: 'sync_list', list: [] };
        
        document.querySelectorAll('.carrier-list').forEach(rootList => {
            const carrierId = rootList.dataset.carrierId;
            
            function traverse(container, 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, pliId);
                    }
                });
            }
            
            traverse(rootList, null);
        });
        
        sendApiRequest(payload).then(newItems => {
            packedItems = newItems;
            // Save scroll positions
            const scrollPos = {
                avail: document.getElementById('available-items-list').scrollTop,
                carrier: document.getElementById('carriers-container').scrollTop 
            };
            const panes = document.querySelectorAll('.pane-content');
            const scrollMap = Array.from(panes).map(p => p.scrollTop);

            fullRender();
            
            // Restore scroll positions
            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.");
        });
    }

    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 Packliste entfernen?')) {
                itemEl.remove();
                sendApiRequest({ action: 'delete_item', item_id: itemId });
            }
        }
    }
    
    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 });
            }, 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') {
                 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'; ?>