<?php
$machineQuery = "
    SELECT id, resource_code
    FROM station_detail_table
    WHERE machine_type = 2
      AND hide = 0
    ORDER BY resource_code
";
$machineResult = $conn->query($machineQuery);
$machineRows = [];
while ($m = $machineResult->fetch_assoc()) {
    $machineRows[] = $m;
}
?>

<style>
    .container {
        max-width: 100%;
        margin: 0 auto;
        background: white;
        border-radius: 10px;
        box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        overflow: hidden;
    }
    .header {
        background: #2c3e50;
        color: white;
        padding: 2px 30px;
    }
    .header h1 { font-size: 21px; margin-bottom: 2px; margin-top: 5px; }
    .header p  { opacity: 0.9; font-size: 14px; }
    .filters {
        padding: 20px 30px;
        background: #f8f9fa;
        border-bottom: 1px solid #e9ecef;
        display: flex;
        gap: 15px;
        flex-wrap: wrap;
        align-items: center;
    }
    .filter-group { display: flex; flex-direction: column; gap: 5px; }
    .filter-group label { font-size: 12px; font-weight: 600; color: #495057; text-transform: uppercase; }
    .filter-group input, .filter-group select {
        padding: 8px 12px;
        border: 1px solid #ced4da;
        border-radius: 5px;
        font-size: 14px;
        min-width: 180px;
    }
    .filter-group input:focus, .filter-group select:focus {
        outline: none;
        border-color: #667eea;
        box-shadow: 0 0 0 3px rgba(102,126,234,0.1);
    }
    .btn-reset {
        padding: 8px 20px;
        background: #6c757d;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 14px;
        margin-top: 20px;
        transition: background 0.3s;
    }
    .btn-reset:hover { background: #5a6268; }
    .btn-dnd {
        padding: 8px 20px;
        background: #2c3e50;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 14px;
        margin-top: 20px;
        transition: background 0.3s;
        display: inline-flex;
        align-items: center;
        gap: 7px;
    }
    .btn-dnd:hover { background: #1a252f; }
    .stats {
        padding: 15px 30px;
        background: #fff3cd;
        border-bottom: 1px solid #ffeaa7;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    .stats-item { display: flex; align-items: center; gap: 8px; }
    .stats-item strong { color: #856404; }
    .table-wrapper {
        overflow-x: auto;
        padding: 20px 30px;
        min-height: 400px;
        position: relative;
    }
    .loading-overlay {
        position: absolute;
        top: 0; left: 0; right: 0; bottom: 0;
        background: rgba(255,255,255,0.9);
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        z-index: 100;
    }
    .loading-overlay.hidden { display: none; }
    .spinner {
        border: 4px solid #f3f3f3;
        border-top: 4px solid #667eea;
        border-radius: 50%;
        width: 50px; height: 50px;
        animation: spin 1s linear infinite;
    }
    @keyframes spin { 0%{transform:rotate(0deg)} 100%{transform:rotate(360deg)} }
    table { width: 100%; border-collapse: collapse; font-size: 14px; }
    thead { background: #f8f9fa; position: sticky; top: 0; z-index: 10; }
    th { padding: 12px 10px; text-align: left; font-weight: 600; color: #495057; border-bottom: 2px solid #dee2e6; white-space: nowrap; }
    td { padding: 12px 10px; border-bottom: 1px solid #e9ecef; color: #212529; }
    tbody tr { transition: background 0.2s; }
    tbody tr:hover { background: #f8f9fa; }
    .priority-badge { display: inline-block; padding: 4px 10px; border-radius: 12px; font-size: 12px; font-weight: 600; text-align: center; min-width: 60px; }
    .priority-1 { background: #dc3545; color: white; }
    .priority-2 { background: #fd7e14; color: white; }
    .priority-3 { background: #ffc107; color: #000; }
    .priority-4 { background: #28a745; color: white; }
    .priority-5 { background: #17a2b8; color: white; }
    .status-badge { display: inline-block; padding: 4px 12px; border-radius: 12px; font-size: 12px; font-weight: 600; }
    .status-finished   { background: #28a745; color: white; }
    .status-in-progress{ background: #007bff; color: white; }
    .status-pending    { background: #ffc107; color: #000; }
    .no-data { text-align: center; padding: 60px 20px; color: #6c757d; }
    .text-muted  { color: #6c757d; font-size: 12px; }
    .text-center { text-align: center; }
    .text-right  { text-align: right; }
    .pagination-wrapper {
        padding: 20px 30px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-top: 1px solid #e9ecef;
        background: #f8f9fa;
    }
    .pagination { display: flex; gap: 5px; align-items: center; }
    .pagination a, .pagination span {
        padding: 8px 12px;
        border: 1px solid #dee2e6;
        background: white;
        color: #495057;
        text-decoration: none;
        border-radius: 5px;
        font-size: 14px;
        transition: all 0.2s;
        cursor: pointer;
    }
    .pagination a:hover { background: #667eea; color: white; border-color: #667eea; }
    .pagination .active { background: #667eea; color: white; border-color: #667eea; font-weight: 600; }
    .pagination .disabled { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
    .per-page-selector { display: flex; align-items: center; gap: 10px; }
    .per-page-selector select { padding: 8px 12px; border: 1px solid #ced4da; border-radius: 5px; font-size: 14px; }
    .hidden { display: none !important; }

    /* ── DnD Modal ── */
    .dnd-overlay {
        position: fixed; inset: 0;
        background: rgba(0,0,0,0.5);
        z-index: 99999;
        display: flex; align-items: center; justify-content: center;
        opacity: 0; pointer-events: none;
        transition: opacity 0.2s;
    }
    .dnd-overlay.open { opacity: 1; pointer-events: all; }
    .dnd-modal {
        background: #fff;
        border-radius: 12px;
        width: min(1300px, 98vw);
        height: min(850px, 95vh);
        display: flex; flex-direction: column;
        box-shadow: 0 20px 60px rgba(0,0,0,0.25);
        transform: translateY(20px);
        transition: transform 0.22s;
        overflow: hidden;
    }
    .dnd-overlay.open .dnd-modal { transform: translateY(0); }
    .dnd-modal-header {
        background: #2c3e50; color: white;
        padding: 14px 22px;
        display: flex; align-items: center; justify-content: space-between;
        flex-shrink: 0;
    }
    .dnd-modal-header h3 { margin: 0; font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
    .dnd-close {
        background: rgba(255,255,255,0.15); border: none; color: white;
        width: 30px; height: 30px; border-radius: 50%; font-size: 16px;
        cursor: pointer; display: flex; align-items: center; justify-content: center;
        transition: background 0.2s;
    }
    .dnd-close:hover { background: rgba(255,255,255,0.3); }
    .dnd-machine-selectors {
        padding: 14px 20px; border-bottom: 1px solid #e9ecef;
        display: flex; gap: 16px; background: #f8f9fa; flex-shrink: 0;
    }
    .dnd-sel-group { flex: 1; display: flex; flex-direction: column; gap: 5px; }
    .dnd-sel-group label { font-size: 11px; font-weight: 700; color: #6c757d; text-transform: uppercase; letter-spacing: 0.05em; }
    .dnd-sel-group select {
        padding: 8px 12px; border: 1px solid #ced4da; border-radius: 6px;
        font-size: 14px; background: white; color: #212529; width: 100%; cursor: pointer;
    }
    .dnd-sel-group select:focus { outline: none; border-color: #667eea; box-shadow: 0 0 0 3px rgba(102,126,234,0.15); }
    .dnd-columns { display: flex; flex: 1; overflow: hidden; }
    .dnd-col { flex: 1; display: flex; flex-direction: column; min-width: 0; }
    .dnd-col:first-child { border-right: 1px solid #dee2e6; }
    .dnd-col-header {
        padding: 10px 16px; background: #f8f9fa; border-bottom: 1px solid #e9ecef;
        display: flex; align-items: center; justify-content: space-between; flex-shrink: 0;
    }
    .dnd-col-machine-name { font-weight: 700; font-size: 14px; color: #2c3e50; }
    .dnd-col-count { font-size: 11px; background: #dee2e6; color: #495057; padding: 2px 8px; border-radius: 10px; font-weight: 600; }
    .dnd-col-body {
        flex: 1; overflow-y: auto; padding: 10px;
        display: flex; flex-direction: column; gap: 7px;
        min-height: 100px; transition: background 0.15s;
    }
    .dnd-col-body.drag-over { background: #eef2ff; }
    .task-card {
        background: white; border: 1px solid #e9ecef;
        border-left: 4px solid #667eea; border-radius: 7px;
        padding: 10px 12px; cursor: grab; user-select: none;
        transition: box-shadow 0.15s, opacity 0.15s, transform 0.1s;
    }
    .task-card:hover { box-shadow: 0 2px 10px rgba(0,0,0,0.1); transform: translateY(-1px); }
    .task-card:active { cursor: grabbing; }
    .task-card.dragging { opacity: 0.3; box-shadow: none; transform: none; }
    .task-card.border-p1 { border-left-color: #dc3545; }
    .task-card.border-p2 { border-left-color: #fd7e14; }
    .task-card.border-p3 { border-left-color: #ffc107; }
    .task-card.border-p4 { border-left-color: #28a745; }
    .task-card.border-p5 { border-left-color: #17a2b8; }
    .task-card.drag-placeholder {
        border: 2px dashed #667eea; background: #f0f3ff;
        border-left: 2px dashed #667eea; height: 64px;
        border-radius: 7px; pointer-events: none;
    }
    .tc-wo   { font-size: 13px; font-weight: 700; color: #212529; margin-bottom: 3px; }
    .tc-prod { font-size: 12px; color: #6c757d; margin-bottom: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .dnd-empty   { text-align: center; padding: 50px 16px; color: #adb5bd; font-size: 13px; }
    .dnd-loading { text-align: center; padding: 50px 16px; font-size: 13px; color: #6c757d; }
    .dnd-footer {
        padding: 10px 20px; border-top: 1px solid #e9ecef; background: #f8f9fa;
        display: flex; align-items: center; justify-content: space-between; flex-shrink: 0;
    }
    .dnd-status { font-size: 12px; color: #6c757d; }
    .dnd-status.ok     { color: #155724; font-weight: 600; }
    .dnd-status.err    { color: #721c24; font-weight: 600; }
    .dnd-status.saving { color: #004085; font-weight: 600; }
    .btn-dnd-refresh {
        padding: 6px 16px; font-size: 12px; background: white;
        border: 1px solid #ced4da; border-radius: 5px; cursor: pointer;
        color: #495057; transition: background 0.2s;
    }
    .btn-dnd-refresh:hover { background: #e9ecef; }
    #dndGhost {
        position: fixed; pointer-events: none; z-index: 999999;
        background: white; border: 1px solid #dee2e6;
        border-left: 4px solid #667eea; border-radius: 7px;
        padding: 8px 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.18);
        font-size: 12px; max-width: 240px; display: none; transform: rotate(2deg);
    }
    #dndGhost .g-wo   { font-weight: 700; color: #212529; }
    #dndGhost .g-prod { color: #6c757d; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
</style>

<!-- Main container -->
<div class="container">
    <div class="header">
        <h1>🔧 Assembly Scheduler - Work Order List</h1>
        <p>View and filter Assembly machine work orders</p>
    </div>

    <div class="filters">
        <div class="filter-group">
            <label>Search Work Order</label>
            <input type="text" id="filterWorkOrder" placeholder="Enter work order number...">
        </div>
        <div class="filter-group">
            <label>Product Name</label>
            <input type="text" id="filterProduct" placeholder="Search product...">
        </div>
        <div class="filter-group">
            <label>Machine</label>
            <select id="filterMachine">
                <option value="">All Machines</option>
                <?php foreach ($machineRows as $machine): ?>
                    <option value="<?= $machine['id'] ?>"><?= htmlspecialchars($machine['resource_code']) ?></option>
                <?php endforeach; ?>
            </select>
        </div>
        <div class="filter-group hide">
            <label>Priority</label>
            <select id="filterPriority">
                <option value="">All Priorities</option>
                <option value="1">Priority 1 (Highest)</option>
                <option value="2">Priority 2</option>
                <option value="3">Priority 3</option>
                <option value="4">Priority 4</option>
                <option value="5">Priority 5 (Lowest)</option>
            </select>
        </div>
        <div class="filter-group">
            <label>Start Date From</label>
            <input type="date" id="filterStartDate" value="<?php echo date('Y-m-d'); ?>">
        </div>
        <button class="btn-reset" onclick="resetFilters()">🔄 Reset Filters</button>
        <button class="btn-dnd" onclick="openDnd()">
            <svg width="15" height="15" viewBox="0 0 16 16" fill="none">
                <rect x="1" y="2.5" width="6" height="11" rx="1.5" stroke="white" stroke-width="1.3"/>
                <rect x="9" y="2.5" width="6" height="11" rx="1.5" stroke="white" stroke-width="1.3"/>
                <path d="M7 8H9M9 8L7.5 6.5M9 8L7.5 9.5" stroke="white" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            Drag &amp; Drop
        </button>
    </div>

    <div class="stats">
        <div class="stats-item"><strong>Total Work Orders:</strong><span id="totalCount">0</span></div>
        <div class="stats-item"><strong>Showing:</strong><span id="showingRange">0 - 0</span></div>
        <div class="stats-item"><strong>Page:</strong><span id="pageInfo">0 of 0</span></div>
    </div>

    <div class="table-wrapper">
        <div id="loadingOverlay" class="loading-overlay">
            <div class="spinner"></div>
            <p style="margin-top:15px;color:#667eea;font-weight:600;">Loading work orders...</p>
        </div>
        <div id="noDataMessage" class="no-data hidden">
            <h3>No Work Orders Found</h3>
            <p>There are no scheduled work orders matching your criteria.</p>
        </div>
        <table id="workOrderTable">
            <thead>
                <tr>
                    <th>Work Order No.</th>
                    <th>Product Name</th>
                    <th>Machine</th>
                    <th class="text-center">Quantity</th>
                    <th class="text-center">Qty Made</th>
                    <th class="text-center">Status</th>
                    <th>Required Date</th>
                    <th>Start Date</th>
                    <th>End Date</th>
                    <th class="text-right">Total Hours</th>
                    <th class="text-right">Setup Hours</th>
                    <th>Customer Orders</th>
                </tr>
            </thead>
            <tbody id="tableBody"></tbody>
        </table>
    </div>

    <div id="paginationWrapper" class="pagination-wrapper hidden">
        <div class="per-page-selector">
            <label><strong>Records per page:</strong></label>
            <select id="perPageSelect" onchange="changePerPage(this.value)">
                <option value="25">25</option>
                <option value="50" selected>50</option>
                <option value="100">100</option>
                <option value="200">200</option>
                <option value="500">500</option>
            </select>
        </div>
        <div id="paginationControls" class="pagination"></div>
    </div>
</div>

<!-- DnD Modal -->
<div class="dnd-overlay" id="dndOverlay">
    <div class="dnd-modal" role="dialog" aria-modal="true">
        <div class="dnd-modal-header">
            <h3>
                <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                    <rect x="1" y="2.5" width="6" height="11" rx="1.5" stroke="white" stroke-width="1.3"/>
                    <rect x="9" y="2.5" width="6" height="11" rx="1.5" stroke="white" stroke-width="1.3"/>
                    <path d="M7 8H9M9 8L7.5 6.5M9 8L7.5 9.5" stroke="white" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                Drag &amp; Drop Task Scheduler
            </h3>
            <button class="dnd-close" onclick="closeDnd()">&times;</button>
        </div>

        <div class="dnd-machine-selectors">
            <div class="dnd-sel-group">
                <label>Left Machine</label>
                <select id="dndMachineLeft" onchange="dndLoadColumn('left')">
                    <option value="">— Select a machine —</option>
                    <?php foreach ($machineRows as $machine): ?>
                        <option value="<?= $machine['id'] ?>"><?= htmlspecialchars($machine['resource_code']) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="dnd-sel-group">
                <label>Right Machine</label>
                <select id="dndMachineRight" onchange="dndLoadColumn('right')">
                    <option value="">— Select a machine —</option>
                    <?php foreach ($machineRows as $machine): ?>
                        <option value="<?= $machine['id'] ?>"><?= htmlspecialchars($machine['resource_code']) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
        </div>

        <div class="dnd-columns">
            <div class="dnd-col">
                <div class="dnd-col-header">
                    <span class="dnd-col-machine-name" id="dndColLeftName">Left Machine</span>
                    <span class="dnd-col-count" id="dndColLeftCount">0</span>
                </div>
                <div class="dnd-col-body" id="dndBodyLeft" data-side="left">
                    <div class="dnd-empty">Select a machine above</div>
                </div>
            </div>
            <div class="dnd-col">
                <div class="dnd-col-header">
                    <span class="dnd-col-machine-name" id="dndColRightName">Right Machine</span>
                    <span class="dnd-col-count" id="dndColRightCount">0</span>
                </div>
                <div class="dnd-col-body" id="dndBodyRight" data-side="right">
                    <div class="dnd-empty">Select a machine above</div>
                </div>
            </div>
        </div>

        <div class="dnd-footer">
            <span class="dnd-status" id="dndStatus">Select machines above to load tasks</span>
            <button class="btn-dnd-refresh" onclick="dndRefreshBoth()">&#8635; Refresh</button>
        </div>
    </div>
</div>

<div id="dndGhost">
    <div class="g-wo" id="dndGhostWo"></div>
    <div class="g-prod" id="dndGhostProd"></div>
</div>

<script>
/* ── Table / filter / pagination ── */
let currentPage = 1;
let perPage     = 50;
let totalPages  = 0;

document.addEventListener('DOMContentLoaded', loadData);
document.getElementById('filterWorkOrder').addEventListener('input',  debounce(loadData, 500));
document.getElementById('filterProduct').addEventListener('input',    debounce(loadData, 500));
document.getElementById('filterMachine').addEventListener('change',   loadData);
document.getElementById('filterPriority').addEventListener('change',  loadData);
document.getElementById('filterStartDate').addEventListener('change', loadData);

function debounce(func, wait) {
    let t;
    return function(...args) { clearTimeout(t); t = setTimeout(() => func(...args), wait); };
}

function loadData(resetPage = true) {
    if (resetPage) currentPage = 1;
    const params = new URLSearchParams({
        current_page: currentPage,
        per_page:     perPage,
        start_date:   document.getElementById('filterStartDate').value,
        work_order:   document.getElementById('filterWorkOrder').value,
        product:      document.getElementById('filterProduct').value,
        machine:      document.getElementById('filterMachine').value,
        priority:     document.getElementById('filterPriority').value
    });
    document.getElementById('loadingOverlay').classList.remove('hidden');
    document.getElementById('noDataMessage').classList.add('hidden');
    document.getElementById('workOrderTable').style.opacity = '0.3';

    const url = site_url + '/modules/machines_management/index.php?page=ajax_assbly_list_data&' + params;
    fetch(url)
        .then(r => r.json())
        .then(data => {
            if (data.success) {
                renderTable(data.data);
                updatePagination(data.pagination);
                updateStats(data.pagination);
            } else {
                alert('Error: ' + data.error);
            }
        })
        .catch(err => alert('Network error: ' + err.message))
        .finally(() => {
            document.getElementById('loadingOverlay').classList.add('hidden');
            document.getElementById('workOrderTable').style.opacity = '1';
        });
}

function renderTable(workOrders) {
    const tbody    = document.getElementById('tableBody');
    const noDataMsg= document.getElementById('noDataMessage');
    if (!workOrders.length) { tbody.innerHTML = ''; noDataMsg.classList.remove('hidden'); return; }
    noDataMsg.classList.add('hidden');
    tbody.innerHTML = workOrders.map(row => {
        const startDate = new Date(row.start_date);
        const endDate   = new Date(row.end_date);
        const startTime = row.start_time ? formatTime(row.start_time) : '';

        let statusText = 'Pending', statusClass = 'status-pending';
        if (row.finished == 1)              { statusText = 'Finished';    statusClass = 'status-finished'; }
        else if ((row.quantity_made||0) > 0){ statusText = 'In Progress'; statusClass = 'status-in-progress'; }

        return `<tr>
            <td><strong>${escapeHtml(row.work_order_name || row.work_order_no)}</strong></td>
            <td>${escapeHtml(row.product_name || row.work_order_name || '')}</td>
            <td>${escapeHtml(row.machine_name || row.task)}</td>
            <td class="text-center"><strong>${formatNumber(row.quantity)}</strong></td>
            <td class="text-center"><strong>${formatNumber(row.quantity_made || 0)}</strong></td>
            <td class="text-center"><span class="status-badge ${statusClass}">${statusText}</span></td>
            <td>${row.require_date ? formatDate(new Date(row.require_date)) : '-'}</td>
            <td>${formatDate(startDate)}${startTime ? '<br><span class="text-muted">'+startTime+'</span>' : ''}</td>
            <td>${formatDate(endDate)}</td>
            <td class="text-right"><strong>${formatNumber(row.total_hours, 2)}</strong> hrs</td>
            <td class="text-right">${formatNumber(row.setup_hours, 2)} hrs</td>
            <td>${escapeHtml(row.customer_order_nos || '-')}</td>
        </tr>`;
    }).join('');
}

function updatePagination(pagination) {
    totalPages = pagination.total_pages;
    const wrapper  = document.getElementById('paginationWrapper');
    const controls = document.getElementById('paginationControls');
    if (totalPages <= 1) { wrapper.classList.add('hidden'); return; }
    wrapper.classList.remove('hidden');
    let html = '';
    if (currentPage > 1) {
        html += `<a onclick="goToPage(1)">« First</a><a onclick="goToPage(${currentPage-1})">‹ Prev</a>`;
    } else {
        html += `<span class="disabled">« First</span><span class="disabled">‹ Prev</span>`;
    }
    const sp = Math.max(1, currentPage-2), ep = Math.min(totalPages, currentPage+2);
    if (sp > 1) html += '<span>...</span>';
    for (let i = sp; i <= ep; i++)
        html += i === currentPage ? `<span class="active">${i}</span>` : `<a onclick="goToPage(${i})">${i}</a>`;
    if (ep < totalPages) html += '<span>...</span>';
    if (currentPage < totalPages) {
        html += `<a onclick="goToPage(${currentPage+1})">Next ›</a><a onclick="goToPage(${totalPages})">Last »</a>`;
    } else {
        html += `<span class="disabled">Next ›</span><span class="disabled">Last »</span>`;
    }
    controls.innerHTML = html;
}

function updateStats(p) {
    document.getElementById('totalCount').textContent  = formatNumber(p.total_records);
    document.getElementById('showingRange').textContent= `${formatNumber(p.showing_from)} - ${formatNumber(p.showing_to)}`;
    document.getElementById('pageInfo').textContent    = `${p.current_page} of ${p.total_pages}`;
}

function goToPage(p)         { currentPage = p; loadData(false); }
function changePerPage(v)    { perPage = parseInt(v); currentPage = 1; loadData(false); }
function resetFilters() {
    document.getElementById('filterWorkOrder').value  = '';
    document.getElementById('filterProduct').value    = '';
    document.getElementById('filterMachine').value    = '';
    document.getElementById('filterPriority').value   = '';
    document.getElementById('filterStartDate').value  = '<?php echo date('Y-m-d'); ?>';
    loadData();
}
function escapeHtml(t) { if(!t) return ''; const d=document.createElement('div'); d.textContent=t; return d.innerHTML; }
function formatNumber(n, dec=0) { if(!n) return '0'; return parseFloat(n).toLocaleString('en-IN',{minimumFractionDigits:dec,maximumFractionDigits:dec}); }
function formatDate(d) { return d.toLocaleDateString('en-GB',{day:'2-digit',month:'short',year:'numeric'}); }
function formatTime(t) { const [h,m]=t.split(':'); const hr=parseInt(h); return `${hr%12||12}:${m} ${hr>=12?'PM':'AM'}`; }


/* ── Drag & Drop ── */
const DND_URL = site_url + '/modules/machines_management/index.php?page=ajax_assbly_list_data';

let dndTasks      = { left: [], right: [] };
let dndMachineIds = { left: 0, right: 0 };
let dndDragging   = null;
let dndDragSide   = null;
let dndPlaceholder= null;
const dndGhost    = document.getElementById('dndGhost');

function openDnd()  { document.getElementById('dndOverlay').classList.add('open'); }
function closeDnd() { document.getElementById('dndOverlay').classList.remove('open'); }
document.getElementById('dndOverlay').addEventListener('click', e => { if (e.target === document.getElementById('dndOverlay')) closeDnd(); });

async function dndLoadColumn(side) {
    const selEl = document.getElementById(side === 'left' ? 'dndMachineLeft' : 'dndMachineRight');
    const mid   = selEl.value;
    const mname = selEl.options[selEl.selectedIndex]?.text || '';
    dndMachineIds[side] = parseInt(mid) || 0;

    document.getElementById(side === 'left' ? 'dndColLeftName' : 'dndColRightName').textContent = mname || side + ' machine';
    const bodyEl = document.getElementById(side === 'left' ? 'dndBodyLeft' : 'dndBodyRight');

    if (!mid) { dndRenderColumn(side, []); return; }
    bodyEl.innerHTML = '<div class="dnd-loading">⏳ Loading tasks…</div>';

    try {
        const res = await fetch(DND_URL + `&machine=${mid}&per_page=500&current_page=1`);
        const dat = await res.json();
        dndTasks[side] = dat.success ? dat.data : [];
        dndRenderColumn(side, dndTasks[side]);
    } catch { bodyEl.innerHTML = '<div class="dnd-empty">Failed to load tasks.</div>'; }
}

function dndRenderColumn(side, rows) {
    const bodyEl  = document.getElementById(side === 'left' ? 'dndBodyLeft'     : 'dndBodyRight');
    const countEl = document.getElementById(side === 'left' ? 'dndColLeftCount' : 'dndColRightCount');
    countEl.textContent = rows.length;
    if (!rows.length) {
        bodyEl.innerHTML = '<div class="dnd-empty">No tasks found for this machine</div>';
        dndSetupDropZone(bodyEl, side);
        return;
    }
    bodyEl.innerHTML = '';
    rows.forEach((row, idx) => bodyEl.appendChild(dndMakeCard(row, side, idx)));
    dndSetupDropZone(bodyEl, side);
}

function dndMakeCard(row, side) {
    const card = document.createElement('div');
    const pNum = Math.min(Math.max(parseInt(row.priority)||1, 1), 5);
    card.className  = `task-card border-p${pNum}`;
    card.draggable  = true;
    card.dataset.taskId      = row.id || row.task_id || '';
    card.dataset.workOrderId = row.work_order_id || '';
    card.dataset.partId      = row.part_id || '';
    card.dataset.priority    = row.priority || 0;
    card.dataset.side        = side;

    let stText = 'Pending', stColor = '#856404', stBg = '#fff3cd';
    if (row.finished == 1)              { stText = 'Done';        stColor = '#155724'; stBg = '#d4edda'; }
    else if ((row.quantity_made||0) > 0){ stText = 'In Progress'; stColor = '#004085'; stBg = '#cce5ff'; }

    card.innerHTML = `
    <div style="display:flex;align-items:flex-start;gap:10px;">
        <div style="flex:1;min-width:0;">
            <div class="tc-wo">${escapeHtml(row.work_order_name || row.work_order_no || '—')}</div>
            <div class="tc-prod" title="${escapeHtml(row.product_name||'')}">
                ${escapeHtml(row.product_name || row.work_order_name || '—')}
            </div>
            <div style="font-size:11px;color:#6c757d;margin-bottom:2px;">
                Required: ${row.require_date ? formatDate(new Date(row.require_date)) : '—'}
            </div>
            <div style="font-size:11px;color:#495057;font-weight:600;">
                Qty: ${formatNumber(row.quantity||0)}
            </div>
            <div style="font-size:10px;color:#adb5bd;font-weight:600;margin-top:2px;">
                ${parseFloat(row.total_hours||0).toFixed(1)} hrs
            </div>
        </div>
        <div style="flex-shrink:0;text-align:right;">
            <span style="display:inline-block;padding:3px 10px;border-radius:10px;font-size:11px;font-weight:700;background:${stBg};color:${stColor};">
                ${stText}
            </span>
            <div style="font-size:10px;color:#6c757d;margin-top:6px;">
                Made: <strong>${formatNumber(row.quantity_made||0)}</strong>
            </div>
        </div>
    </div>`;

    card.addEventListener('dragstart', dndOnDragStart);
    card.addEventListener('dragend',   dndOnDragEnd);
    return card;
}

function dndSetupDropZone(bodyEl, side) {
    const fresh = bodyEl.cloneNode(true);
    bodyEl.parentNode.replaceChild(fresh, bodyEl);
    fresh.querySelectorAll('.task-card').forEach(c => {
        c.addEventListener('dragstart', dndOnDragStart);
        c.addEventListener('dragend',   dndOnDragEnd);
    });
    fresh.addEventListener('dragover', e => {
        e.preventDefault();
        fresh.classList.add('drag-over');
        if (dndPlaceholder) {
            const after = dndGetAfterElement(fresh, e.clientY);
            after ? fresh.insertBefore(dndPlaceholder, after) : fresh.appendChild(dndPlaceholder);
        }
    });
    fresh.addEventListener('dragleave', e => { if (!fresh.contains(e.relatedTarget)) fresh.classList.remove('drag-over'); });
    fresh.addEventListener('drop', e => {
        e.preventDefault();
        fresh.classList.remove('drag-over');
        if (!dndDragging) return;
        const destMachineId = dndMachineIds[side];
        if (!destMachineId) { dndSetStatus('Please select a machine for this column.', 'err'); return; }

        const after    = dndGetAfterElement(fresh, e.clientY);
        const allCards = [...fresh.querySelectorAll('.task-card:not(.dragging):not(.drag-placeholder)')];
        let leftNeighborCard = null;
        if (after) {
            const idx = allCards.indexOf(after);
            leftNeighborCard = idx > 0 ? allCards[idx - 1] : null;
        } else {
            leftNeighborCard = allCards.length ? allCards[allCards.length - 1] : null;
        }
        dndSaveMove(dndDragging, destMachineId, leftNeighborCard);
    });
}

function dndOnDragStart(e) {
    dndDragging = e.currentTarget;
    dndDragSide = dndDragging.dataset.side;
    setTimeout(() => { if (dndDragging) dndDragging.classList.add('dragging'); }, 0);
    dndPlaceholder = document.createElement('div');
    dndPlaceholder.className = 'task-card drag-placeholder';
    dndGhost.style.display = 'block';
    document.getElementById('dndGhostWo').textContent   = dndDragging.querySelector('.tc-wo')?.textContent   || '';
    document.getElementById('dndGhostProd').textContent = dndDragging.querySelector('.tc-prod')?.textContent || '';
}
function dndOnDragEnd() {
    if (dndDragging) dndDragging.classList.remove('dragging');
    if (dndPlaceholder?.parentNode) dndPlaceholder.parentNode.removeChild(dndPlaceholder);
    document.querySelectorAll('.dnd-col-body').forEach(b => b.classList.remove('drag-over'));
    dndGhost.style.display = 'none';
    dndDragging = dndPlaceholder = null;
}
document.addEventListener('dragover', e => {
    dndGhost.style.left = (e.clientX + 16) + 'px';
    dndGhost.style.top  = (e.clientY + 10) + 'px';
});

function dndGetAfterElement(container, y) {
    return [...container.querySelectorAll('.task-card:not(.dragging):not(.drag-placeholder)')]
        .reduce((closest, child) => {
            const box    = child.getBoundingClientRect();
            const offset = y - box.top - box.height / 2;
            return (offset < 0 && offset > closest.offset) ? { offset, element: child } : closest;
        }, { offset: Number.NEGATIVE_INFINITY }).element;
}

async function dndSaveMove(card, destMachineId, leftNeighborCard) {
    const params = new URLSearchParams({
        action:          'update_assmbly_task_priority',
        task_id:         card.dataset.taskId,
        new_machine_id:  destMachineId,
        part_id:         card.dataset.partId,
        work_order_id:   card.dataset.workOrderId,
    });
    if (leftNeighborCard) {
        params.append('left_neighbor_priority', leftNeighborCard.dataset.priority);
        params.append('left_neighbor_task_id',  leftNeighborCard.dataset.taskId);
    }
    dndSetStatus('Saving…', 'saving');
    try {
        const res = await fetch(DND_URL, { method: 'POST', body: params });
        const dat = await res.json();
        if (dat.status === 'success') {
            dndSetStatus('Task moved successfully!', 'ok');
            setTimeout(dndRefreshBoth, 400);
            loadData(false);
        } else {
            dndSetStatus('Error: ' + (dat.message || 'Unknown'), 'err');
            dndRefreshBoth();
        }
    } catch {
        dndSetStatus('Network error — refreshing…', 'err');
        dndRefreshBoth();
    }
}

function dndRefreshBoth() {
    if (dndMachineIds.left)  dndLoadColumn('left');
    if (dndMachineIds.right) dndLoadColumn('right');
}
function dndSetStatus(msg, type) {
    const el = document.getElementById('dndStatus');
    el.textContent = msg;
    el.className   = 'dnd-status ' + (type || '');
}
</script>