<?php
/**
 * gantt_chart_assypu.php  (Assypu admin Gantt include + daily batch script)
 * =====================================================================
 * CHANGES FROM ORIGINAL:
 *   - recalculateMachineDatesforassypu() and handleMachineBreakdowns()
 *     removed — now the shared assypu_fullReschedule() and
 *     assypu_handleMachineBreakdowns() from assypu_scheduler_lib.php.
 *   - FIX: the breakdown-processing loop at the bottom of this file
 *     queried `WHERE sd.machine_type = 2` to find machines with active
 *     breakdowns — every other query in this file identifies assypu
 *     machines as `machine_type = 5`. This looks like a copy-paste
 *     leftover from another module; the breakdown-hours accrual loop
 *     never actually ran for assypu's own machines. Changed to
 *     `machine_type = 5`.
 *   - FIX: the overdue-task batch loop's OK-quantity query had no
 *     task-instance scoping at all (the same bug found and fixed in
 *     CNC's and PU's equivalent batch scripts) — summed production
 *     across every instance of a work_order+part combination ever
 *     scheduled, not just this one. Added `assypu_machine_table_id`
 *     (manuf_id) scoping.
 *   - Active-breakdown lookup (used for the machine-label styling
 *     further down) now reads assypu_machine_breakdown_log, consistent
 *     with the shared source of truth used elsewhere (see
 *     ajax_actions_for_assypu.php's start/stop_machine_breakdown, which
 *     now mirror into it).
 * =====================================================================
 */

require_once __DIR__ . '/assypu_scheduler_lib.php';

$today = date('Y-m-d');

/* ---------------------------------------------------------------------
 * PASS 1: mark completed break tasks whose end_date has passed
 * ------------------------------------------------------------------- */
mysqli_query($conn, "
    UPDATE assypu_machine_table
    SET finished = 1
    WHERE end_date <= '$today' AND is_break = 1
");

/* ---------------------------------------------------------------------
 * PASS 2: trim remaining-hours tracking for ongoing (multi-day) breaks
 * ------------------------------------------------------------------- */
$query = "
    SELECT id, remaing_hours, total_hours
    FROM assypu_machine_table
    WHERE DATE(start_date) < '$today'
      AND DATE(end_date) >= '$today'
      AND is_break = 1
";
$result = mysqli_query($conn, $query);

while ($row = mysqli_fetch_assoc($result)) {
    $id = $row['id'];
    $remaingHoursStr = $row['remaing_hours'];
    $totalHours = $row['total_hours'];

    $newRemaingStrParts = [];
    $pastHours = 0;

    foreach (explode(',', $remaingHoursStr) as $pair) {
        if (strpos($pair, '=') !== false) {
            [$date, $hours] = explode('=', $pair);
            if (strtotime($date) < strtotime($today)) {
                $pastHours += floatval($hours);
            } else {
                $newRemaingStrParts[] = "$date=$hours";
            }
        }
    }

    $updatedRemaingStr = implode(',', $newRemaingStrParts);
    $updatedTotalHours = max(0, $totalHours - $pastHours);
    $updatedRemaingStrEsc = mysqli_real_escape_string($conn, $updatedRemaingStr);

    mysqli_query($conn, "
        UPDATE assypu_machine_table
        SET
            remaing_hours       = '$updatedRemaingStrEsc',
            total_hours_update  = '$updatedTotalHours',
            total_hours         = '$updatedTotalHours',
            setup_hours         = 0
        WHERE id = $id
    ");
}

/* ---------------------------------------------------------------------
 * PASS 3: recompute remaining hours for overdue-but-unfinished RUNNING
 * (non-break) tasks
 * ------------------------------------------------------------------- */
$query = "
    SELECT
        v.id,
        v.manuf_id,
        v.work_order_id,
        v.part_id,
        v.quantity,
        v.machine_id,
        v.is_break,
        v.start_date,
        m.total_hours AS hours,
        m.end_date
    FROM assypu_machine_table AS v
    LEFT JOIN manufacture_machine_table AS m
        ON v.work_order_id = m.work_order_id
       AND v.part_id = m.part_id
    WHERE v.finished = 0
      AND v.is_break = 0
      AND v.start_date < '$today'
";
$result = mysqli_query($conn, $query);
$machinesToReschedule = [];

while ($row = mysqli_fetch_assoc($result)) {

    $assypuId    = intval($row['id']);
    $manufId     = intval($row['manuf_id']); // FIX: scopes the count-log lookup below
    $workOrderId = intval($row['work_order_id']);
    $partId      = intval($row['part_id']);
    $machineId   = intval($row['machine_id']);

    $totalQty = floatval($row['quantity']);
    $hours    = floatval($row['hours']);

    $uph = ($hours > 0 && $totalQty > 0) ? ($totalQty / $hours) : 0;
    if ($uph <= 0 || $totalQty <= 0) {
        continue;
    }

    // FIX: scoped by assypu_machine_table_id (= manuf_id), matching
    // every other consumer of assypu_part_count_log. The original query
    // here had no task-instance key at all and summed production across
    // every instance of this work_order+part combination ever scheduled.
    $okQtyQuery = "
        SELECT SUM(quantity) AS ok_qty
        FROM assypu_part_count_log
        WHERE assypu_machine_table_id = $manufId
          AND type = 'ok'
    ";
    $okQtyResult = mysqli_query($conn, $okQtyQuery);
    $okQtyRow    = mysqli_fetch_assoc($okQtyResult);
    $okQty = floatval($okQtyRow['ok_qty'] ?? 0);

    $remainingQty   = max(0, $totalQty - $okQty);
    $remainingHours = ($uph > 0) ? ($remainingQty / $uph) : 0;
    $finishedVal    = ($remainingQty <= 0) ? 1 : 0;

    $updateSql = "
        UPDATE assypu_machine_table
        SET
            total_hours_update = '$remainingHours',
            total_hours        = '$remainingHours',
            setup_hours        = 0,
            finished           = '$finishedVal'
        WHERE id = '$assypuId'
    ";
    mysqli_query($conn, $updateSql);

    $machinesToReschedule[$machineId] = true;
}

foreach (array_keys($machinesToReschedule) as $machineId) {
    assypu_fullReschedule($conn, $machineId);
}

/* ---------------------------------------------------------------------
 * PASS 4: breakdown-hours accrual for active breakdowns
 * FIX: was machine_type = 2 (every other query in this file uses 5)
 * ------------------------------------------------------------------- */
$query = "
    SELECT DISTINCT mb.machine_id, sd.resource_code
    FROM machine_breakdown mb
    JOIN station_detail_table sd ON mb.machine_id = sd.id
    WHERE sd.machine_type = 5 AND mb.is_active = 1
";
$result = mysqli_query($conn, $query);

if ($result && mysqli_num_rows($result) > 0) {
    // handleMachineBreakdowns() itself iterates every active breakdown
    // internally, so it only needs to run once — not once per machine —
    // but recalculation still needs to happen per affected machine.
    assypu_handleMachineBreakdowns($conn);
    while ($machineRow = mysqli_fetch_assoc($result)) {
        assypu_fullReschedule($conn, (int)$machineRow['machine_id']);
    }
}
?>
<div class="container-fluid" style="background-color: #ffe6e6; height: 100vh;">
  <div class="split-container">
    <div class="split-panel" id="left-panel">
<style>
.scrollable-section {
    max-height: 400px; 
    overflow-y: auto;
    border: 1px solid #dee2e6;
    border-radius: 5px;
    background-color: #fff;
}


.spinner-border-sm {
    width: 1rem;
    height: 1rem;
    border-width: 0.15em;
}


.table td, .table th {
  vertical-align: middle !important;
  text-align: center;
}

.table .form-check-input {
  margin: 0 auto;             
  display: block;            
  position: relative;
  top: 0;                     
  transform: translateY(0);   
}


.table {
    margin-bottom: 0;
}

.table thead th {
    position: sticky;
    top: 0;
    background-color: #f8f9fa;
    z-index: 10;
}


.btn-with-spinner {
    position: relative;
}

.btn-spinner {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.btn-text {
    opacity: 1;
    transition: opacity 0.15s ease-in-out;
}

.btn-loading .btn-text {
    opacity: 0;
}

.btn-loading .btn-spinner {
    display: inline-block;
}

.sortable {
    cursor: pointer;
    user-select: none;
    position: relative;
    padding-right: 25px !important;
}

.sortable:hover {
    background-color: #e9ecef !important;
}

.sortable::after {
    content: '⇅';
    position: absolute;
    right: 8px;
    opacity: 0.3;
    font-size: 12px;
}

.sortable.asc::after {
    content: '↑';
    opacity: 1;
    color: #0d6efd;
}

.sortable.desc::after {
    content: '↓';
    opacity: 1;
    color: #0d6efd;
}
</style>

<div class="container mt-4">
    <h3 class="mb-3" style="background-color: #f8d7da;">Assypu Ready Orders</h3>
    <form id="assemblyReadyForm">
        <div id="assembly-ready-container" class="scrollable-section">
            <div class="text-center p-3">
                <div class="spinner-border" role="status">
                    <span class="visually-hidden">Loading...</span>
                </div>
                <p>Loading assembly ready orders...</p>
            </div>
        </div>
        <div class="mt-3 text-end">
            <button type="button" class="btn btn-primary btn-with-spinner" id="showSelectedAssemblyBtn" onclick="showSelectedWorkOrders(this)">
                <span class="btn-text">Show Selected</span>
                <span class="spinner-border spinner-border-sm btn-spinner d-none" role="status" aria-hidden="true"></span>
            </button>
        </div>
    </form>
</div>

<div class="container mt-4">
    <h3 class="mb-3" style="background-color: #ffeb99;">Assypu Not Ready Orders</h3>
    <form id="assemblyNotReadyForm">
        <div id="assembly-not-ready-container" class="scrollable-section">
            <div class="text-center p-3">
                <div class="spinner-border" role="status">
                    <span class="visually-hidden">Loading...</span>
                </div>
                <p>Loading assembly not ready orders...</p>
            </div>
        </div>
        <div class="mt-3 text-end">
            <button type="button" class="btn btn-primary btn-with-spinner" id="showSelectedNotReadyBtn" onclick="showSelectedWorkOrders(this)">
                <span class="btn-text">Show Selected</span>
                <span class="spinner-border spinner-border-sm btn-spinner d-none" role="status" aria-hidden="true"></span>
            </button>
        </div>
    </form>
</div>

<script>
// Global variables
let assemblyMachineList = [];

// Function to load all assembly work orders via AJAX
function loadAssemblyWorkOrders() {
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_get_workorders&action=get_assypu_work_orders",
        method: 'GET',
        dataType: 'json',
        success: function(response) {
            assemblyMachineList = response.machines || [];
            
            renderAssemblyReadyOrders(response.ready_orders);
            renderAssemblyNotReadyOrders(response.not_ready_orders);
        },
        error: function(xhr, status, error) {
            console.error('Error loading assembly work orders:', error);
            // Fallback to PHP rendering if AJAX fails
            renderAssemblyReadyOrdersFromPHP();
            renderAssemblyNotReadyOrdersFromPHP();
        }
    });
}

// Function to render assembly ready orders
function renderAssemblyReadyOrders(orders) {
    if (orders.length === 0) {
        $('#assembly-ready-container').html('<p class="p-3">No assembly ready orders found.</p>');
        return;
    }

    let html = `
        <table class="table table-bordered table-sm mb-0" id="assemblyReadyTable">
            <thead class="table-light">
                <tr>
                    <th>Select</th>
                    <th class="sortable" data-column="work_order_name" data-type="string">WO Number</th>
                    <th class="sortable" data-column="part_number" data-type="string">Part Number</th>
                    <th class="sortable" data-column="product_description" data-type="string">Part Description</th>
                    <th class="sortable" data-column="end_date" data-type="date">Due Date</th>
                    <th class="sortable" data-column="quantity" data-type="number">Qty</th>
                    <th class="sortable" data-column="total_hours" data-type="number">Std Hours</th>
                    <th>Machine</th>
                </tr>
            </thead>
            <tbody>
    `;

    orders.forEach(order => {
        html += `
            <tr data-part-id="${escapeHtml(order.part_id)}" data-wo-id="${escapeHtml(order.work_order_id)}">
                <td class="text-center">
                    <input class="form-check-input" type="checkbox" name="workOrder[]" value="${escapeHtml(order.work_order_id)}" 
                        id="workOrder${escapeHtml(order.work_order_id)}" data-machine-id="${escapeHtml(order.machine_id)}" data-id="${escapeHtml(order.id)}">
                </td>
                <td>${escapeHtml(order.work_order_name)}</td>
                <td>${escapeHtml(order.part_number)}</td>
                <td>${escapeHtml(order.product_description)}</td>
                <td>${escapeHtml(order.end_date)}</td>
                <td>${escapeHtml(order.quantity)}</td>
                <td>${escapeHtml(order.total_hours)}</td>
                <td>${getAssemblyMachineSelectHtml(order.id, order.machine_id)}</td>
            </tr>
        `;
    });

    html += `</tbody></table>`;
    $('#assembly-ready-container').html(html);

    // Initialize Select2 if available
    if (typeof $().select2 !== 'undefined') {
        $('.machine-select').select2();
    }

    // Initialize sorting for this table
    initTableSort('assemblyReadyTable');
}

// Function to render assembly not ready orders
function renderAssemblyNotReadyOrders(orders) {
    if (orders.length === 0) {
        $('#assembly-not-ready-container').html('<p class="p-3">No Assypu not ready orders found.</p>');
        return;
    }

    let html = `
        <table class="table table-bordered table-sm mb-0" id="assemblyNotReadyTable">
            <thead class="table-light">
                <tr>
                    <th>Select</th>
                    <th class="sortable" data-column="work_order_name" data-type="string">WO Number</th>
                    <th class="sortable" data-column="part_number" data-type="string">Part Number</th>
                    <th class="sortable" data-column="product_description" data-type="string">Part Description</th>
                    <th class="sortable" data-column="end_date" data-type="date">Due Date</th>
                    <th class="sortable" data-column="quantity" data-type="number">Qty</th>
                    <th class="sortable" data-column="total_hours" data-type="number">Std Hours</th>
                    <th>Machine</th>
                </tr>
            </thead>
            <tbody>
    `;

    orders.forEach(order => {
        html += `
            <tr data-part-id="${escapeHtml(order.part_id)}" data-wo-id="${escapeHtml(order.work_order_id)}">
                <td class="text-center">
                    <input class="form-check-input" type="checkbox" name="workOrder[]" value="${escapeHtml(order.work_order_id)}" 
                        id="workOrder${escapeHtml(order.work_order_id)}" data-machine-id="${escapeHtml(order.machine_id)}" data-id="${escapeHtml(order.id)}">
                </td>
                <td>${escapeHtml(order.work_order_name)}</td>
                <td>${escapeHtml(order.part_number)}</td>
                <td>${escapeHtml(order.product_description)}</td>
                <td>${escapeHtml(order.end_date)}</td>
                <td>${escapeHtml(order.quantity)}</td>
                <td>${escapeHtml(order.total_hours)}</td>
                <td>${getAssemblyMachineSelectHtml(order.id, order.machine_id)}</td>
            </tr>
        `;
    });

    html += `</tbody></table>`;
    $('#assembly-not-ready-container').html(html);

    // Initialize Select2 if available
    if (typeof $().select2 !== 'undefined') {
        $('.machine-select').select2();
    }

    // Initialize sorting for this table
    initTableSort('assemblyNotReadyTable');
}

// Function to generate machine select HTML for assembly
function getAssemblyMachineSelectHtml(id, selectedMachineId) {
    let options = '<option value="">Select Machine</option>';
    assemblyMachineList.forEach(machine => {
        const selected = machine.id == selectedMachineId ? 'selected' : '';
        options += `<option value="${machine.id}" ${selected}>${escapeHtml(machine.name)}</option>`;
    });

    return `<select class="form-control form-control-sm machine-select" id="machine_id_${id}" name="machine_id_${id}">
        ${options}
    </select>`;
}

// ========== SORTING FUNCTIONALITY ==========
function initTableSort(tableId) {
    const table = document.getElementById(tableId);
    if (!table) return;

    const headers = table.querySelectorAll('th.sortable');
    
    headers.forEach(header => {
        header.addEventListener('click', function() {
            const column = this.dataset.column;
            const type = this.dataset.type;
            const tbody = table.querySelector('tbody');
            const rows = Array.from(tbody.querySelectorAll('tr'));
            
            // Determine sort direction
            let direction = 'asc';
            if (this.classList.contains('asc')) {
                direction = 'desc';
            }
            
            // Remove sort classes from all headers
            headers.forEach(h => h.classList.remove('asc', 'desc'));
            
            // Add sort class to current header
            this.classList.add(direction);
            
            // Get column index
            const columnIndex = Array.from(this.parentElement.children).indexOf(this);
            
            // Sort rows
            rows.sort((a, b) => {
                let aVal = a.children[columnIndex].textContent.trim();
                let bVal = b.children[columnIndex].textContent.trim();
                
                // Handle different data types
                if (type === 'number') {
                    aVal = parseFloat(aVal) || 0;
                    bVal = parseFloat(bVal) || 0;
                } else if (type === 'date') {
                    aVal = new Date(aVal);
                    bVal = new Date(bVal);
                }
                
                if (aVal < bVal) return direction === 'asc' ? -1 : 1;
                if (aVal > bVal) return direction === 'asc' ? 1 : -1;
                return 0;
            });
            
            // Reorder rows in DOM
            rows.forEach(row => tbody.appendChild(row));

            // Reinitialize Select2 after sorting
            if (typeof $().select2 !== 'undefined') {
                $('.machine-select').select2('destroy');
                $('.machine-select').select2();
            }
        });
    });
}

// Fallback functions to render from PHP data if AJAX fails
function renderAssemblyReadyOrdersFromPHP() {
    <?php
    if (!empty($workOrderss_assm_ready)) {
        echo "const phpReadyOrders = " . json_encode($workOrderss_assm_ready) . ";";
        // Add part_number and product_description to PHP data
        echo "phpReadyOrders.forEach(order => {";
        echo "  order.part_number = '" . addslashes(utility::getTableFieldById("item_management", "part_number", "id", "' + order.part_id + '")) . "';";
        echo "  order.product_description = '" . addslashes(utility::getTableFieldById("item_management", "product_description", "id", "' + order.part_id + '")) . "';";
        echo "});";
        echo "renderAssemblyReadyOrders(phpReadyOrders);";
    } else {
        echo "$('#assembly-ready-container').html('<p class=\"p-3\">No assembly ready orders found.</p>');";
    }
    ?>
}

function renderAssemblyNotReadyOrdersFromPHP() {
    <?php
    if (!empty($workOrderss_pending)) {
        echo "const phpNotReadyOrders = " . json_encode($workOrderss_pending) . ";";
        // Add part_number and product_description to PHP data
        echo "phpNotReadyOrders.forEach(order => {";
        echo "  order.part_number = '" . addslashes(utility::getTableFieldById("item_management", "part_number", "id", "' + order.part_id + '")) . "';";
        echo "  order.product_description = '" . addslashes(utility::getTableFieldById("item_management", "product_description", "id", "' + order.part_id + '")) . "';";
        echo "});";
        echo "renderAssemblyNotReadyOrders(phpNotReadyOrders);";
    } else {
        echo "$('#assembly-not-ready-container').html('<p class=\"p-3\">No assembly not ready orders found.</p>');";
    }
    ?>
}

// Helper function to escape HTML
function escapeHtml(text) {
    if (text === null || text === undefined) return '';
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}
</script>
<script>
// Show selected orders with spinner
function showSelectedWorkOrders(button) {
    const workOrders = [];

    $('input[name="workOrder[]"]:checked').each(function () {
        const workOrderId = $(this).val();
        const row = $(this).closest('tr');
        const partId = row.data('part-id');
        const dbId = $(this).data('id');

        // Get the machine ID from the select element by dynamic ID
        const machineSelectId = "machine_id_" + dbId;
        const machineId = $("#" + machineSelectId).val();

        workOrders.push({
            id: dbId,
            work_order_id: workOrderId,
            part_id: partId,
            machine_id: machineId
        });
    });

    console.log(workOrders);

    if (workOrders.length === 0) {
        alert("Please select at least one work order.");
        return;
    }

    // Show spinner on the clicked button
    const $button = $(button);
    const $spinner = $button.find('.btn-spinner');
    const $buttonText = $button.find('.btn-text');
    
    $button.prop('disabled', true);
    $button.addClass('btn-loading');
    $spinner.removeClass('d-none');

    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=select_order_for_assypu",
        method: "POST",
        data: {
            work_orders: JSON.stringify(workOrders)
        },
success: function (response) {
    let res = {};
    try { res = typeof response === "string" ? JSON.parse(response) : response; } catch(e){}
    
    if (res.status === "processing" || res.status === "success") {
        alert("Work orders submitted successfully");
        location.reload();
    } else {
       // alert("Unexpected response from server.");
        console.error("Server response:", response);
    }
},
error: function (xhr, status, error) {
    console.error("AJAX Error:", error, xhr.responseText);
    //alert("Failed to submit work orders.");
	 location.reload();
},

        complete: function() {
            // Re-enable button and hide spinner (in case of error)
            $button.prop('disabled', false);
            $button.removeClass('btn-loading');
            $spinner.addClass('d-none');
        }
    });
}

// Load assembly work orders when page is ready
$(document).ready(function() {
    loadAssemblyWorkOrders();
    setInterval(loadAssemblyWorkOrders, 30000); // Auto-refresh every 30 seconds
});
</script>
</div>
<div class="split-divider" id="divider"></div>
<div class="split-panel" id="right-panel">
<?php
$month = isset($_GET['month']) ? intval($_GET['month']) : date('m');
$year = isset($_GET['year']) ? intval($_GET['year']) : date('Y');

// Generate current and adjacent months
$monthsToShow = [];
$currentDate = new DateTime(); 
for ($i = 0; $i < 3; $i++) {  
    $date = clone $currentDate;
    $date->modify("+$i months");
    $monthsToShow[] = [
        'month' => (int)$date->format('m'),
        'year' => (int)$date->format('Y'),
        'label' => $date->format('F Y')
    ];
}
$currentDateStr = date('Y-m-d');

$query = "SELECT 
    mmt.machine_id AS task, 
    mmt.id as task_id, 
    wo.work_order_no, 
    mmt.part_id,
    mmt.setup_hours, 
    mmt.priority,
    mmt.total_hours AS hours_to_schedule,
    mmt.total_hours, 
    mmt.work_order_id,
    mmt.product_name,
    mmt.quantity,
    mmt.set_id, 
    won.work_order_name,  
    mmt.shift_ids AS shift_name, 
    DATE(mmt.start_date) AS start_date, 
    DATE(mmt.end_date) AS end_date,
    TIME(mmt.start_date) AS start_time,
    mmt.is_break,
    mmt.break_reason,
    mmt.is_breakdown_affected,
    mmt.breakdown_hours,
    mb.id as breakdown_id,
    mb.breakdown_reason as machine_breakdown_reason,
    m.end_date as manufacture_end_date,
    m.description as manufacture_description,
	m.parent_ids,
    im.part_number as parent_part_number,
    GROUP_CONCAT(DISTINCT wocr.work_order_no ORDER BY wocr.work_order_no SEPARATOR ', ') as customer_order_nos
FROM 
    assypu_machine_table mmt
LEFT JOIN 
    work_order wo ON mmt.work_order_id = wo.id
LEFT JOIN 
    work_order_name won ON mmt.work_order_id = won.work_order_id AND mmt.part_id = won.part_id
LEFT JOIN 
    machine_breakdown mb ON mmt.machine_id = mb.machine_id AND mb.is_active = 1
LEFT JOIN (
    SELECT 
        m1.part_id, 
        m1.work_order_id, 
        m1.end_date, 
        m1.description, 
        m1.parent_ids
    FROM manufacture_machine_table m1
    INNER JOIN (
        SELECT 
            part_id, 
            work_order_id, 
            MAX(end_date) as max_end_date
        FROM manufacture_machine_table
        GROUP BY part_id, work_order_id
    ) m2 ON m1.part_id = m2.part_id 
        AND m1.work_order_id = m2.work_order_id 
        AND m1.end_date = m2.max_end_date
) m ON mmt.part_id = m.part_id 
    AND mmt.work_order_id = m.work_order_id
LEFT JOIN 
    item_management im ON m.parent_ids = im.id
LEFT JOIN 
    work_order_customer_ref_mapping wocr ON mmt.work_order_id = wocr.work_order_id
WHERE 
    mmt.end_date >= '$currentDateStr'
GROUP BY 
    mmt.id, mmt.machine_id, wo.work_order_no, mmt.part_id, mmt.setup_hours, mmt.priority, mmt.total_hours, mmt.work_order_id,
    mmt.product_name, mmt.quantity, mmt.set_id,
    won.work_order_name, mmt.shift_ids, mmt.start_date,
    mmt.end_date, mmt.is_break, mmt.break_reason, mmt.is_breakdown_affected,
    mmt.breakdown_hours, mb.id, mb.breakdown_reason, m.end_date,
    m.description, im.part_number
ORDER BY 
    mmt.priority, mmt.machine_id"; 


$workOrders = [];
$tasks = [];
$workOrdersSet = [];

$result = mysqli_query($conn, $query);

if (!$result) {
    die("Query Error: " . mysqli_error($conn));
}

while ($row = mysqli_fetch_assoc($result)) {
    // Check if late
    $isLate = false;
    if (!empty($row['manufacture_end_date']) && $row['end_date'] > $row['manufacture_end_date']) {
        $isLate = true;
    }
    
    $row['is_late'] = $isLate;
    $tasks[] = $row;
    
    $woKey = $row['work_order_no'] . '_' . $row['part_id'];
    if (!isset($workOrdersSet[$woKey])) {
        $workOrdersSet[$woKey] = true;
        $workOrders[] = ['work_order_no' => $row['work_order_no'], 'part_id' => $row['part_id']];
    }
}

$shifts = [];
$shiftHours = [];
$shiftDays = [];
$shiftTimes = [];

$dayMap = [
    0 => "Sunday",
    1 => "Monday",
    2 => "Tuesday",
    3 => "Wednesday",
    4 => "Thursday",
    5 => "Friday",
    6 => "Saturday"
];

$sql = "SELECT shift_name, day_shifts, start_time, end_time, hours FROM working_hours";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        $shiftName = $row['shift_name'];
        $startTime = $row['start_time'];
        $endTime = $row['end_time'];
        $dayIndex = (int)$row['day_shifts'];
        $hours = (float)$row['hours'];

        $shifts[] = $shiftName;
        $shiftHours[$shiftName] = $hours;
        $shiftDays[$shiftName] = $dayMap[$dayIndex];
        $shiftTimes[$shiftName] = [
            'start' => $startTime,
            'end' => $endTime,
            'hours' => $hours
        ];
    }
}

$intervalCache = [];

function generateTimeIntervals($startTime, $endTime) {
    global $intervalCache;
    $cacheKey = $startTime . '-' . $endTime;
    
    if (isset($intervalCache[$cacheKey])) {
        return $intervalCache[$cacheKey];
    }
    
    $intervals = [];
    $current = new DateTime($startTime);
    $end = new DateTime($endTime);
    
    $intervalStart = $current->format('H:i');
    $current->add(new DateInterval('PT30M'));
    
    while ($current <= $end) {
        $intervalEnd = $current->format('H:i');
        $intervals[] = [
            'start' => $intervalStart,
            'end' => $intervalEnd,
            'minutes' => (strtotime($intervalEnd) - strtotime($intervalStart)) / 60
        ];
        $intervalStart = $intervalEnd;
        $current->add(new DateInterval('PT30M'));
    }
    
    if ($intervalStart !== $end->format('H:i')) {
        $intervals[] = [
            'start' => $intervalStart,
            'end' => $end->format('H:i'),
            'minutes' => (strtotime($end->format('H:i')) - strtotime($intervalStart)) / 60
        ];
    }
    
    $intervalCache[$cacheKey] = $intervals;
    return $intervals;
}

$activeBreakdowns = [];
$breakdownQuery = "SELECT machine_id, breakdown_reason FROM machine_breakdown WHERE is_active = 1";
$breakdownResult = mysqli_query($conn, $breakdownQuery);
while ($breakdown = mysqli_fetch_assoc($breakdownResult)) {
    $activeBreakdowns[$breakdown['machine_id']] = $breakdown['breakdown_reason'];
}


function scheduleByPriority($tasks, $activeBreakdowns) {    
    $scheduledTasks = [];
    $machineAllocations = [];
    
    foreach ($tasks as $task) {
        $machineId = $task['task'];
        $hasBreakdown = isset($activeBreakdowns[$machineId]);
        
        if (!isset($machineAllocations[$machineId])) {
            $machineAllocations[$machineId] = [
                'current_time' => 0,
                'tasks' => []
            ];
        }
        
        $scheduledTask = [
            'task' => $machineId,
            'is_late' => $task['is_late'],
            'task_id' => $task['task_id'],
            'allocated_hours' => $task['hours_to_schedule'],
            'start_datetime' => '',
            'end_datetime' => '',
            'work_order_id' => $task['work_order_id'],
            'part_id' => $task['part_id'],
            'setup_hours' => $task['setup_hours'],
            'work_order_no' => $task['work_order_no'],
            'product_name' => $task['product_name'],
            'quantity' => $task['quantity'],
            'work_order_name' => $task['work_order_name'],
            'set_id' => $task['set_id'],
            'parent_ids' => $task['parent_ids'],
            'parent_part_number' => $task['parent_part_number'],
            'is_break' => $task['is_break'],
            'break_reason' => $task['break_reason'],
            'shift_name' => $task['shift_name'],
            'priority' => $task['priority'],
            'is_breakdown_affected' => $task['is_breakdown_affected'],
            'breakdown_hours' => $task['breakdown_hours'],
            'has_breakdown' => $hasBreakdown,
            'breakdown_reason' => $hasBreakdown ? $activeBreakdowns[$machineId] : '',
            'manufacture_end_date' => $task['manufacture_end_date'],
            'manufacture_description' => $task['manufacture_description'],
            'customer_order_nos' => $task['customer_order_nos'],
            'position' => $machineAllocations[$machineId]['current_time']
        ];
        
        $machineAllocations[$machineId]['tasks'][] = $scheduledTask;
        $machineAllocations[$machineId]['current_time'] += $task['hours_to_schedule'];
    }
    

    foreach ($machineAllocations as $allocations) {
        foreach ($allocations['tasks'] as $task) {
            $scheduledTasks[] = $task;
        }
    }
    
    return $scheduledTasks;
}

$distributedTasks = scheduleByPriority($tasks, $activeBreakdowns);

$groupedTasks = [];
foreach ($distributedTasks as $task) {
    $groupedTasks[$task['task']][] = $task;
}

$taskNames = [];
$machineQuery = mysqli_query($conn, "SELECT id, resource_code FROM station_detail_table WHERE machine_type = 5 AND hide = 0");
while ($row = mysqli_fetch_assoc($machineQuery)) {
    $taskNames[$row['id']] = $row['resource_code'];
}

function generateCalendar($month, $year, $shifts, $shiftDays, $shiftTimes) {
    $calendar = [];
    $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
    $validWeekdays = array_unique(array_values($shiftDays));
    
    $today = new DateTime();
    $currentYear = (int)$today->format('Y');
    $currentMonth = (int)$today->format('m');
    $currentDay = (int)$today->format('d');

    $startDay = ($year == $currentYear && $month == $currentMonth) ? $currentDay : 1;

    for ($day = $startDay; $day <= $daysInMonth; $day++) {
        $date = sprintf("%04d-%02d-%02d", $year, $month, $day);
        $timestamp = strtotime($date);
        $dayOfWeek = date("l", $timestamp);

        if (in_array($dayOfWeek, $validWeekdays)) {
            foreach ($shifts as $shift) {
                if ($shiftDays[$shift] === $dayOfWeek) {
                    $intervals = generateTimeIntervals($shiftTimes[$shift]['start'], $shiftTimes[$shift]['end']);
                    $totalMinutes = array_sum(array_column($intervals, 'minutes'));
                    
                    $calendar[] = [
                        "date" => $date,
                        "day" => $day,
                        "dayOfWeek" => $dayOfWeek,
                        "month" => $month,
                        "shift" => $shift,
                        "start_time" => $shiftTimes[$shift]['start'],
                        "end_time" => $shiftTimes[$shift]['end'],
                        "hours" => $shiftTimes[$shift]['hours'],
                        "intervals" => $intervals,
                        "total_intervals" => count($intervals),
                        "total_minutes" => $totalMinutes
                    ];
                }
            }
        }
    }

    return $calendar;
}

$calendarDays = [];
foreach ($monthsToShow as $m) {
    $calendarDays = array_merge(
        $calendarDays,
        generateCalendar($m['month'], $m['year'], $shifts, $shiftDays, $shiftTimes)
    );
}

$totalWidth = 0;
$dayPositions = [];
$dayWidths = [];
$dayMinutes = [];

foreach ($calendarDays as $day) {
    $dayWidth = count($day['intervals']) * 40;
    $key = $day['date'] . '-' . $day['shift'];
    
    $dayPositions[$key] = $totalWidth;
    $dayWidths[$key] = $dayWidth;
    $dayMinutes[$key] = $day['total_minutes'];
    $totalWidth += $dayWidth;
}


$machineColors = [];
$colorPalette = [
    '#e6f5f5', '#f5e6f5', '#e6ffe6', '#fff2e6', '#f0e6ff', 
    '#e6ffff', '#ffe6f2', '#f5f5e6', '#e6f5f5', '#f5e6ff',
    '#e6ffec', '#fff0e6', '#e6f0ff', '#ffe6ff', '#e6ffe6',
    '#f5e6e6', '#e6e6f5', '#f5f5e6', '#e6f5f5', '#f5e6f5'
];
$colorIndex = 0;
$paletteCount = count($colorPalette);

foreach ($taskNames as $machineId => $taskName) {
    $machineColors[$machineId] = $colorPalette[$colorIndex % $paletteCount];
    $colorIndex++;
}

?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
	:root {
		--primary-color: #3498db;
		--secondary-color: #2c3e50;
		--accent-color: #e74c3c;
		--light-bg: #f8f9fa;
		--dark-bg: #343a40;
		--success-color: #2ecc71;
		--warning-color: #f39c12;
		--danger-color: #e74c3c;
		--info-color: #3498db;
		--current-time-color: #e74c3c;
		--time-marker-color: #fff3cd;
		--shift-highlight: #d4edda;
		--time-interval-width: 40px;
		--task-bar-height: 130px;
		--grid-line-color: rgba(0, 0, 0, 0.1);
		--breakdown-color: #ff4444;
	}

	.gantt-container {
		position: relative;
		width: 100%;
		overflow-x: auto;
		margin-top: 20px;
		display: flex;
		background-color: white;
		box-shadow: 0 2px 10px rgba(0,0,0,0.1);
		border-radius: 8px;
	}

	.gantt-labels {
		position: sticky;
		left: 0;
		top: 0;
		width: 270px;
		background: #f9f9f9;
		padding: 15px;
		border-right: 1px solid #ddd;
		z-index: 20;
		height: fit-content;
		flex-shrink: 0;
	}

	.gantt-scrollable-content {
		flex: 1;
		min-width: 0;
		overflow-x: auto;
		position: relative;
	}

	.gantt-grid {
		display: inline-block;
		min-width: <?php echo $totalWidth; ?>px;
		position: relative;
	}

	.gantt-header {
		display: inline-flex;
		background: #f5f5f5;
		border-bottom: 1px solid #ddd;
		position: sticky;
		top: 0;
		z-index: 15;
	}

	.gantt-day {
		display: inline-flex;
		flex-direction: column;
		text-align: center;
		background-color: #fff;
		float: none;
		vertical-align: top;
		position: relative;
	}
	
	.gantt-day strong {
		font-size: 12px;
		color: #333;
		background: #f3f3f3;
		padding: 3px;
		border-radius: 3px;
		margin-bottom: 5px;
	}
	
	.gantt-time-intervals {
		display: flex;
		flex-wrap: nowrap;
		justify-content: flex-start;
		width: 100%;
		background-color: #f8f9fa;
		border-top: 1px solid #dee2e6;
	}

	.gantt-time-interval {
		flex: 0 0 var(--time-interval-width);
		text-align: center;
		font-size: 10px;
		color: #555;
		border-right: 1px solid var(--grid-line-color);
		height: 30px;
		position: relative;
	}

	.gantt-time-interval-label {
		position: absolute;
		font-size: 0.9rem;
		transform: rotate(-45deg);
		transform-origin: left center;
		white-space: nowrap;
		left: 0%;
		bottom: -15px;
		color: #000;
	}

	.gantt-row {
		display: block;
		border-bottom: 1px solid #000;
		min-height: var(--task-bar-height);
		position: relative;
		white-space: nowrap;
		background-image: linear-gradient(to right, var(--grid-line-color) 1px, transparent 1px);
		background-size: var(--time-interval-width) 1px;
		background-position: left center;
	}

	.gantt-task {
		position: absolute;
		height: 100%;
		top: 0;
		background: #3498db;
		color: white;
		text-align: center;
		border-radius: 5px;
		padding: 5px;
		line-height: 1.2;
		font-size: 12px;
		cursor: grab;
		transition: background-color 0.3s ease;
		box-shadow: 1px 1px 3px rgba(0,0,0,0.2);
		z-index: 1;
		overflow: hidden;
		box-sizing: border-box;
	}

	.gantt-task .task-content {
		padding: 1px;
		font-size: 10px;
		height: calc(100% - 20px);
		overflow: hidden;
	}

	.gantt-task .task-hours {
		position: absolute;
		bottom: 0;
		left: 0;
		right: 0;
		background: rgba(0,0,0,0.2);
		text-align: center;
		font-size: 9px;
		padding: 1px 0;
		border-radius: 0 0 4px 4px;
	}

	.task-color-1 { background-color: #FFA500; }
	.task-color-2 { background-color: #32CD32; }
	.task-color-3 { background-color: #ff6b6b; }
	.task-color-4 { background-color: #3498db; }

	.no-tasks {
		color: #999;
		font-style: italic;
		padding: 10px;
		text-align: center;
		width: 100%;
	}

	.dot-indicator {
		position: absolute;
		top: 4px;
		right: 4px;
		width: 40px;
		height: 40px;
		border-radius: 50%;
		border: 3px solid black;
	}

	.green-dot-indicator {
		background-color: #00cc66;
	}

	.red-dot-indicator {
		background-color: #ff3333;
	}

	.blue-dot-indicator {
		background-color: #3399ff;
	}
	
	.hour-indicator {
		position: absolute;
		bottom: 0;
		left: 0;
		right: 0;
		font-size: 0.65rem;
		text-align: center;
		background: rgba(0,0,0,0.15);
		padding: 1px 0;
		border-radius: 0 0 4px 4px;
	}

	.machine-list {
		display: flex;
		flex-direction: column;
		gap: 10px;
	}
	
	.circle-button {
		position: absolute;
		top: 10px;
		right: 10px;
		width: 20px;
		height: 20px;
		border: none;
		border-radius: 50%;
		background-color: #4CAF50;
		cursor: pointer;
		z-index: 10;
	}

	.controls {
		background: white;
		padding: 15px;
		border-radius: 8px;
		margin-bottom: 20px;
		box-shadow: 0 2px 5px rgba(0,0,0,0.1);
	}

	.machine-section {
		margin-bottom: 15px;
	}

	.card {
		border-radius: 8px;
		box-shadow: 0 2px 5px rgba(0,0,0,0.1);
		transition: transform 0.2s;
	}

	.card:hover {
		transform: translateY(-2px);
	}

	.card-header {
		font-weight: 500;
		padding: 8px 12px;
	}

	.form-control {
		font-size: 0.85rem;
		padding: 0.25rem 0.5rem;
	}

	.gantt-task.dragging {
		opacity: 0.5;
		background-color: #f39c12;
	}
   
	.gantt-row.drop-target {
		outline: 2px dashed #007bff;
		background-color: #e6f7ff;
	}

	.gantt-day.today {
		background-color: #fff3cd;
		box-shadow: 0 0 0 2px #ffc107;
	}

	.gantt-day.today strong {
		background-color: #ffc107;
		color: #000;
		font-weight: bold;
	}

	.current-time-marker {
		position: absolute;
		top: 0;
		bottom: 0;
		width: 2px;
		background-color: var(--current-time-color);
		z-index: 10;
	}

	.current-time-marker::after {
		content: '';
		position: absolute;
		top: 0;
		left: -4px;
		width: 10px;
		height: 10px;
		background-color: var(--current-time-color);
		border-radius: 50%;
	}
	.gantt-task {
		border-right: 3px solid rgba(255, 255, 255, 0.5);
		box-sizing: border-box;
	}
	.gantt-task.highlight-border {
		border-right: 100px solid rgba(255, 255, 0, 0.8) !important;
		box-shadow: 0 0 10px rgba(255, 255, 0, 0.5);
		transition: all 0.3s ease;
	}
	.break-task {
		background-color: #999 !important;
		border-left: 3px dashed #fff !important;
		border-right: 3px dashed #fff !important;
		color: #fff !important;
	}
	.breakdown-task {
		background-color: var(--breakdown-color) !important;
		border-left: 3px solid #cc0000 !important;
		border-right: 3px solid #cc0000 !important;
		color: white !important;
	}

	.breakdown-affected {
		background: repeating-linear-gradient(
			45deg,
			#ff6b6b,
			#ff6b6b 10px,
			#ff8e8e 10px,
			#ff8e8e 20px
		) !important;
		border: 2px dashed #ff0000 !important;
	}

	.machine-with-breakdown {
		background-color: #ffe6e6 !important;
		border-left: 4px solid var(--breakdown-color) !important;
	}

	.breakdown-indicator {
		position: absolute;
		top: 5px;
		right: 5px;
		width: 12px;
		height: 12px;
		background-color: var(--breakdown-color);
		border-radius: 50%;
		animation: pulse 1.5s infinite;
	}

	@keyframes pulse {
		0% { opacity: 1; }
		50% { opacity: 0.5; }
		100% { opacity: 1; }
	}

    .gantt-task.late-task {
        background-color: #ff6b6b !important;
        border-left: 3px solid #ff0000 !important;
        border-right: 3px solid #ff0000 !important;
    }
    
    .gantt-task.on-time-task {
        background-color: #78c679 !important;
        border-left: 3px solid #2ecc71 !important;
        border-right: 3px solid #2ecc71 !important;
    }
    
    .gantt-task.break-task {
        background-color: #999 !important;
        border-left: 3px dashed #fff !important;
        border-right: 3px dashed #fff !important;
        color: #fff !important;
    }
</style>

    <div class="container-fluid">
        <div class="controls">
            <div class="row">
                <div class="col-md-6">
                    <h3><i class="fas fa-calendar-day me-2"></i>AssyPu Gantt Chart</h3>
                    <h4><?php echo date('l, F j, Y'); ?></h4>
                </div>
                <div class="col-md-6 text-end">                 
                    <button class="btn btn-primary" onclick="window.location.reload()">
                        <i class="fas fa-sync-alt me-2"></i>Refresh
                    </button>
                    <button class="btn btn-warning ms-2" id="addBreakBtn">
                        <i class="fas fa-clock me-2"></i>Add Break
                    </button>
					 <button class="btn btn-danger ms-2 hide" id="startBreakdownBtn">
        <i class="fas fa-exclamation-triangle me-2"></i>Start Breakdown
    </button>
    <button class="btn btn-success ms-2 hide" id="stopBreakdownBtn">
        <i class="fas fa-check me-2"></i>Stop Breakdown
    </button>
                </div>
            </div>
        </div>

        <div class="gantt-container">
            <!-- Machines Section -->
            <div class="gantt-labels">
                 <h5><i class="fas fa-server me-2"></i>Machine Detail</h5>
                <div style=" margin-bottom: 30px;"></div>
                <div class="machine-list">
                    <?php
                    $renderedMachines = [];
                    foreach ($taskNames as $machineId => $taskName): 
                        if (!in_array($machineId, $renderedMachines)):
						 $hasBreakdown = isset($activeBreakdowns[$machineId]);
                            $renderedMachines[] = $machineId;
                    ?>
                        <div class="machine-section mb-0" style="width: 200px;">
                            <div class="row" style="margin-bottom: 1px; height: 120px;">
                                <div class="card <?php echo $hasBreakdown ? 'machine-with-breakdown' : ''; ?>" 
                                     style="background-color: #e6f2ff; margin-left: 12px; position: relative;">
                                    <?php if ($hasBreakdown): ?>
                                        <div class="breakdown-indicator" title="Machine Breakdown Active"></div>
                                    <?php endif; ?>
                                    <div>
                                        <div style="display: flex; justify-content: center; align-items: center; height: 100%; font-weight: bold;">
                                            <?php echo $taskName; ?>
                                            <?php if ($hasBreakdown): ?>
                                                <br/><small style="color: #ff0000; font-size: 10px;">BREAKDOWN</small>
                                            <?php endif; ?>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    <?php 
                        endif;
                    endforeach; ?>
                </div>
            </div>
            <div class="gantt-scrollable-content">
                <div class="gantt-grid">
                    <!-- Time Slots Header -->
                    <div class="gantt-header">
                        <?php foreach ($calendarDays as $day): 
                            $dayWidth = count($day['intervals']) * 40;
                            $isToday = $day['date'] == date('Y-m-d');
                        ?>
                            <div class="gantt-day <?php echo $isToday ? 'today' : ''; ?>" data-date="<?php echo $day["date"]; ?>" data-shift="<?php echo $day["shift"]; ?>" style="min-width: <?php echo $dayWidth; ?>px;">
                                <div><strong><?php echo $day["date"] . " (" . $day["shift"] . ")"; ?></strong></div>
                                <div class="gantt-time-intervals">
                                    <?php foreach ($day['intervals'] as $interval): ?>
                                        <div class="gantt-time-interval" data-interval="<?php echo $interval['start'] . '-' . $interval['end']; ?>">
                                            <div class="gantt-time-interval-label"><?php echo $interval['start']; ?></div>
                                        </div>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        <?php endforeach; ?>
                    </div>

                    <!-- Task Rows -->
                    <?php foreach ($taskNames as $machineId => $taskName): 
                        $groupKey = $machineId;
                        $rowColor = $machineColors[$machineId];
                    ?>
                        <div class="gantt-row" 
						 data-machine-id="<?php echo $machineId; ?>"  
						 style="background-color: <?php echo $rowColor; ?>;">
						
						<?php if (isset($groupedTasks[$groupKey])): ?>
							<?php 
							$cumulativePosition = 0;
							foreach ($groupedTasks[$groupKey] as $task): 
								$taskWidth = $task['allocated_hours'] * 80;
								$leftPosition = $cumulativePosition;
								$cumulativePosition += $taskWidth;
								
								$part_id = (int)$task["part_id"];
								$work_order_id = $task["work_order_id"];
								$set_id = $task["set_id"];
								$parent_ids = $task["parent_ids"]; 
								$parent_part_number = $task["parent_part_number"];
								$setup_hours = $task["setup_hours"];
								$part_name = $task["product_name"];
								$quantity = $task["quantity"];
								$manufacture_end_date = $task["manufacture_end_date"];
								$route_detail = $task["manufacture_description"];
								$comma_customer_order_nos = $task["customer_order_nos"];
								
								// Use pre-fetched BOM availability
								$dotClass = "red-dot-indicator";
								$tooltipContent = "";
								$allInStock = true;
								$inventoryStatus = [];

								$product_id = intval($task['part_id']); // main product
								$query = "
									SELECT 
										im.part_number,
										COALESCE(i.quantity_in_stock, 0) AS quantity_in_stock
									FROM bom b
									LEFT JOIN inventory i 
										ON b.sub_part_id = i.item_id
									LEFT JOIN item_management im
										ON b.sub_part_id = im.id
									WHERE b.main_product_id = $product_id
								";
								$result = $conn->query($query);
								if (!$result) {
									$tooltipContent = 'Error fetching inventory: ' . $conn->error;
								} 
								elseif ($result->num_rows > 0) {
									while ($row = $result->fetch_assoc()) {
										$partNumber = $row['part_number'] ?: 'Unknown Item';
										$qty = (int)$row['quantity_in_stock'];
										$status = ($qty > 0) ? "In Stock" : "Out of Stock";
										$inventoryStatus[] = "$partNumber: $status (Qty: $qty)";
										if ($qty <= 0) {
											$allInStock = false;
										}
									}
									if ($allInStock) {
										$dotClass = "green-dot-indicator";
									}
									$tooltipContent = "Inventory Status:\n" . implode("\n", $inventoryStatus);
								} else {
									$tooltipContent = "No BOM child parts linked for this product.";
								}
							?> 

							<div class="gantt-task 
								<?php echo $task['is_break'] ? 'break-task' : ''; ?> 
								<?php echo $task['is_late'] ? 'late-task' : 'on-time-task'; ?>"  
								 draggable="true"
								 data-task-id="<?php echo $task["task_id"]; ?>"
								 data-priority="<?php echo $task["priority"]; ?>"
								 data-work-order="<?php echo htmlspecialchars($task["work_order_no"]); ?>" 
								 data-part-id="<?php echo $part_id; ?>" 
								 data-work-order-id="<?php echo $work_order_id; ?>"
								 data-hours="<?php echo $task['allocated_hours']; ?>"
								 data-current-machine="<?php echo $machineId; ?>"
								 style="left: <?php echo $leftPosition; ?>px; width: <?php echo $taskWidth; ?>px;">
								
								<?php if ($task['is_break']): ?>
									<div class="task-content">
										<strong>BREAK</strong><br/>
										<?php echo htmlspecialchars($task['break_reason']); ?><br/>
										Duration: <?php echo $task['allocated_hours']; ?>h
									</div>
								<?php else: ?>
									<div class="dot-indicator <?php echo $dotClass; ?>" 
													 title="<?php echo htmlspecialchars($tooltipContent); ?>"></div>

									<div class="task-content" style="font-size:12px; line-height: 1.4;">
										<div style="margin-bottom: 0px;">
											<?php echo $parent_ids == 0 ? htmlspecialchars($comma_customer_order_nos) : htmlspecialchars($parent_part_number); ?>
										</div>
										
										<div style="margin-bottom: 0px;">
											<?php echo htmlspecialchars($task["work_order_name"]); ?>
										</div>
										
										<div style="margin-bottom: 0px;">
											<strong>Item:</strong> <?php echo htmlspecialchars($part_name); ?>
											&nbsp;&nbsp;|&nbsp;&nbsp;
											<strong>Qty:</strong> <?php echo htmlspecialchars($quantity); ?>
										</div>
										<div style="margin-bottom: 0px;">
											<strong>Set Hours:</strong> <?php echo htmlspecialchars($setup_hours); ?>
										</div>
										<?php if ($task['is_breakdown_affected']): ?>
											<div style="margin-bottom: 0px; color: #ff0000;">
												<strong>Breakdown Delay: +<?php echo $task['breakdown_hours']; ?>h</strong>
											</div>
										<?php endif; ?>
										
										<div style="margin-bottom: 0px;">
											<strong>Desc:</strong> <?php echo htmlspecialchars($route_detail); ?>
										</div>
										<div style="margin-bottom: 0;">
											<strong>Due Date:</strong> 
											<?php echo !empty($manufacture_end_date) ? date('d-M-Y', strtotime($manufacture_end_date)) : 'N/A'; ?>
										</div>
									</div>
								<?php endif; ?>
								<div class="hour-indicator">
									<?php echo $task['allocated_hours']; ?>h
									<?php if ($task['is_breakdown_affected']): ?>
										<br><small>+<?php echo $task['breakdown_hours']; ?>h delay</small>
									<?php endif; ?>
								</div>
							</div>
							<?php endforeach; ?>
						<?php else: ?>
							<div class="no-tasks">No tasks scheduled</div>
						<?php endif; ?>
					</div>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
    </div>
<!-- Break Modal -->
<div class="modal fade" id="workOrderDetailModal" tabindex="-1" aria-labelledby="workOrderDetailModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header bg-primary text-white">
                <h5 class="modal-title" id="workOrderDetailModalLabel">
                    <i class="fas fa-info-circle me-2"></i>Work Order Details
                </h5>
               
				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
				  <span aria-hidden="true">&times;</span>
				</button>
            </div>
            <div class="modal-body">
                <div id="detailLoadingSpinner" class="text-center py-5">
                    <div class="spinner-border text-primary" role="status">
                        <span class="visually-hidden">Loading...</span>
                    </div>
                    <p class="mt-2">Loading details...</p>
                </div>
                <div id="workOrderDetailContent" style="display: none;">
                    <!-- Work Order Information -->
                    <div class="card mb-3">
                        <div class="card-header bg-light">
                            <h6 class="mb-0"><i class="fas fa-clipboard-list me-2"></i>Order Information</h6>
                        </div>
                        <div class="card-body">
                            <div class="row">
                                <div class="col-md-6">
                                   <!-- <p><strong>Work Order No:</strong> <span id="detail_wo_no"></span></p>-->
                                    <p><strong>Customer Order:</strong> <span id="detail_customer_order"></span></p>
                                    <p><strong>Work Order Name:</strong> <span id="detail_wo_name"></span></p>
									<p><strong>Status:</strong> <span id="detail_status" class="badge"></span></p>
                                </div>
                                <div class="col-md-6">
                                    <p><strong>Final Part:</strong> <span id="detail_final_part"></span></p>
                                    <p><strong>Customer code:</strong> <span id="detail_customer_code" class=""></span></p>
									<p><strong>RefSalescode:</strong> <span id="detail_RefSalesCode" class=""></span></p>
                                    
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Part Information -->
                    <div class="card mb-3">
                        <div class="card-header bg-light">
                            <h6 class="mb-0"><i class="fas fa-cog me-2"></i>Part Information</h6>
                        </div>
                        <div class="card-body">
                            <div class="row">
                                <div class="col-md-6">
                                    <p><strong>Part/Set Name:</strong> <span id="detail_part_name"></span></p>
									<p><strong>Desc:</strong> <span id="detail_desc"></span></p>
                                    <p><strong>Quantity:</strong> <span id="detail_quantity"></span></p>
                                   
                                </div>
                                <div class="col-md-6">
                                    <p><strong>Setup Hours:</strong> <span id="detail_setup_hours"></span></p>
                                    <p><strong>Total Hours:</strong> <span id="detail_total_hours"></span></p>
                                    <p><strong>Due Date:</strong> <span id="detail_due_date"></span></p>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Production Details -->
                    <div class="card mb-3">
                        <div class="card-header bg-light">
                            <h6 class="mb-0"><i class="fas fa-wrench me-2"></i>Production Details</h6>
                        </div>
                        <div class="card-body">
                            <p><strong>Description:</strong> <span id="detail_route_desc"></span></p>
                            <div id="breakdown_info" style="display: none;" class="alert alert-danger">
                                <strong><i class="fas fa-exclamation-triangle me-2"></i>Breakdown Impact:</strong>
                                <span id="detail_breakdown_hours"></span> hours delay
                            </div>
                        </div>
                    </div>

                    <!-- Schedule Information -->
                <!--    <div class="card mb-3">
                        <div class="card-header bg-light">
                            <h6 class="mb-0"><i class="fas fa-calendar me-2"></i>Schedule Information</h6>
                        </div>
                        <div class="card-body">
                            <div class="row">
                                <div class="col-md-6">
                                    <p><strong>Start Date:</strong> <span id="detail_start_date"></span></p>
                                    <p><strong>Start Time:</strong> <span id="detail_start_time"></span></p>
                                </div>
                                <div class="col-md-6">
                                    <p><strong>End Date:</strong> <span id="detail_end_date"></span></p>
                                    <p><strong>Shift:</strong> <span id="detail_shift"></span></p>
                                </div>
                            </div>
                        </div>
                    </div>-->
                </div>
                <div id="detailErrorMessage" class="alert alert-danger d-none" role="alert">
                    Failed to load work order details. Please try again.
                </div>
            </div>
            <div class="modal-footer">
				 <button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fas fa-times me-2"></i>Close</button>
                <button type="button" class="btn btn-warning hide" id="editWorkOrderBtn">
                    <i class="fas fa-edit me-2"></i>Edit
                </button>
                <button type="button" class="btn btn-danger" id="deleteWorkOrderBtn">
                    <i class="fas fa-trash me-2"></i>Delete
                </button>
            </div>
        </div>
    </div>
</div>

<!-- Edit Work Order Modal -->
<div class="modal fade" id="editWorkOrderModal" tabindex="-1" aria-labelledby="editWorkOrderModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header bg-warning">
                <h5 class="modal-title" id="editWorkOrderModalLabel">
                    <i class="fas fa-edit me-2"></i>Edit Work Order
                </h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <form id="editWorkOrderForm">
                    <input type="hidden" id="edit_task_id" name="task_id">
                    
                    <div class="row mb-3">
                        <div class="col-md-6">
                            <label for="edit_priority" class="form-label">Priority</label>
                            <input type="number" class="form-control" id="edit_priority" name="priority" min="1">
                        </div>
                        <div class="col-md-6">
                            <label for="edit_machine" class="form-label">Machine</label>
                            <select class="form-control" id="edit_machine" name="machine_id">
                                <?php foreach ($taskNames as $machineId => $taskName): ?>
                                    <option value="<?php echo $machineId; ?>"><?php echo $taskName; ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                    </div>

                    <div class="row mb-3">
                        <div class="col-md-6">
                            <label for="edit_setup_hours" class="form-label">Setup Hours</label>
                            <input type="number" class="form-control" id="edit_setup_hours" name="setup_hours" step="0.5" min="0">
                        </div>
                        <div class="col-md-6">
                            <label for="edit_total_hours" class="form-label">Total Hours</label>
                            <input type="number" class="form-control" id="edit_total_hours" name="total_hours" step="0.5" min="0">
                        </div>
                    </div>

                   

                    <div class="row mb-3">
                        <div class="col-md-6">
                            <label for="edit_start_date" class="form-label">Start Date</label>
                            <input type="date" class="form-control" id="edit_start_date" name="start_date">
                        </div>
                        <div class="col-md-6">
                            <label for="edit_quantity" class="form-label">Quantity</label>
                            <input type="number" class="form-control" id="edit_quantity" name="quantity" min="1">
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-primary" id="saveEditBtn">
                    <i class="fas fa-save me-2"></i>Save Changes
                </button>
            </div>
        </div>
    </div>
</div>

<script>
$('body').addClass('sidebar-collapse');
let currentTaskDetails = null;
document.addEventListener('DOMContentLoaded', function() {
    attachTaskClickHandlers();
});

function attachTaskClickHandlers() {
    document.querySelectorAll('.gantt-task').forEach(task => {
        if (task.classList.contains('break-task')) {
            return;
        }
        
        task.style.cursor = 'pointer';
        
        task.addEventListener('click', function(e) {
            if (task.classList.contains('dragging')) {
                return;
            }
            
            const taskId = this.dataset.taskId;
            const workOrderId = this.dataset.workOrderId;
            const partId = this.dataset.partId;
            const machineId = this.dataset.currentMachine;
            
            loadWorkOrderDetails(taskId, workOrderId, partId, machineId);
        });
    });
}

function loadWorkOrderDetails(taskId, workOrderId, partId, machineId) {
    const modal = new bootstrap.Modal(document.getElementById('workOrderDetailModal'));
    modal.show();
    
    $('#detailLoadingSpinner').show();
    $('#workOrderDetailContent').hide();
    $('#detailErrorMessage').addClass('d-none');
    
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=get_assypu_task_details",
        method: "POST",
        data: {
            task_id: taskId,
            work_order_id: workOrderId,
            part_id: partId,
            machine_id: machineId
        },
        dataType: "json",
        success: function(response) {
            if (response.success) {
                currentTaskDetails = response.data;
                displayWorkOrderDetails(response.data);
                $('#detailLoadingSpinner').hide();
                $('#workOrderDetailContent').show();
            } else {
                $('#detailLoadingSpinner').hide();
                $('#detailErrorMessage').text(response.message || 'Failed to load details').removeClass('d-none');
            }
        },
        error: function(xhr, status, error) {
            console.error("AJAX Error:", error);
            $('#detailLoadingSpinner').hide();
            $('#detailErrorMessage').removeClass('d-none');
        }
    });
}

function displayWorkOrderDetails(data) {
    $('#detail_wo_no').text(data.work_order_no || '-');
    $('#detail_customer_order').text(data.customer_order_nos || '-');
    $('#detail_wo_name').text(data.work_order_name || '-');
    $('#detail_final_part').text(data.parent_part_number || '-');
    $('#detail_customer_code').text(data.customer_code || '-');    
	$('#detail_RefSalesCode').text(data.RefSalesCode || '-');

    const statusBadge = $('#detail_status');
    if (data.is_late) {
        statusBadge.text('Late').removeClass().addClass('badge bg-danger');
    } else {
        statusBadge.text('On Time').removeClass().addClass('badge bg-success');
    }
    
    // Part Information
    $('#detail_part_name').text(data.product_name || '-');
    $('#detail_quantity').text(data.quantity || '-');
	$('#detail_desc').text(data.manufacture_description || '-');
    $('#detail_setup_hours').text(data.setup_hours || '-');
    $('#detail_total_hours').text(data.total_hours || '-');
    $('#detail_due_date').text(data.end_date || '-');

    $('#detail_route_desc').text(data.route_desc || '-');

    if (data.is_breakdown_affected && data.breakdown_hours > 0) {
        $('#breakdown_info').show();
        $('#detail_breakdown_hours').text(data.breakdown_hours);
    } else {
        $('#breakdown_info').hide();
    }
    
    // Schedule Information
    $('#detail_start_date').text(data.start_date || '-');
    $('#detail_start_time').text(data.start_time || '-');
    $('#detail_end_date').text(data.end_date || '-');
    $('#detail_shift').text(data.shift_name || '-');
}

$('#editWorkOrderBtn').on('click', function() {
    if (!currentTaskDetails) return;
    
    $('#workOrderDetailModal').modal('hide');

    $('#edit_task_id').val(currentTaskDetails.task_id);
    $('#edit_priority').val(currentTaskDetails.priority);
    $('#edit_machine').val(currentTaskDetails.machine_id);
    $('#edit_setup_hours').val(currentTaskDetails.setup_hours);
    $('#edit_total_hours').val(currentTaskDetails.total_hours);
    $('#edit_start_date').val(currentTaskDetails.start_date);
    $('#edit_quantity').val(currentTaskDetails.quantity);

    const editModal = new bootstrap.Modal(document.getElementById('editWorkOrderModal'));
    editModal.show();
});

$('#saveEditBtn').on('click', function() {
    const formData = {
        task_id: $('#edit_task_id').val(),
        priority: $('#edit_priority').val(),
        machine_id: $('#edit_machine').val(),
        setup_hours: $('#edit_setup_hours').val(),
        total_hours: $('#edit_total_hours').val(),
        start_date: $('#edit_start_date').val(),
        quantity: $('#edit_quantity').val()
    };

    const $btn = $(this);
    $btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-2"></span>Saving...');
    
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=update_assypu_task",
        method: "POST",
        data: formData,
        dataType: "json",
        success: function(response) {
            if (response.success) {
                alert('Work order updated successfully!');
                $('#editWorkOrderModal').modal('hide');
                location.reload();
            } else {
                alert('Error: ' + (response.message || 'Failed to update work order'));
                $btn.prop('disabled', false).html('<i class="fas fa-save me-2"></i>Save Changes');
            }
        },
        error: function(xhr, status, error) {
            console.error("AJAX Error:", error);
            alert('Error updating work order: ' + error);
            $btn.prop('disabled', false).html('<i class="fas fa-save me-2"></i>Save Changes');
        }
    });
});

$('#deleteWorkOrderBtn').on('click', function() {
    if (!currentTaskDetails) return;
    
    if (!confirm('Are you sure you want to delete this work order? This action cannot be undone.')) {
        return;
    }
    
    const $btn = $(this);
    $btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-2"></span>Deleting...');
    
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=delete_assypu_task",
        method: "POST",
        data: {
            task_id: currentTaskDetails.task_id,
            work_order_id: currentTaskDetails.work_order_id,
            part_id: currentTaskDetails.part_id
        },
        dataType: "json",
        success: function(response) {
            if (response.success) {
                alert('Work order deleted successfully!');
                $('#workOrderDetailModal').modal('hide');
                location.reload();
            } else {
                alert('Error: ' + (response.message || 'Failed to delete work order'));
                $btn.prop('disabled', false).html('<i class="fas fa-trash me-2"></i>Delete');
            }
        },
        error: function(xhr, status, error) {
            console.error("AJAX Error:", error);
            alert('Error deleting work order: ' + error);
            $btn.prop('disabled', false).html('<i class="fas fa-trash me-2"></i>Delete');
        }
    });
});
</script>
<!-- Start Breakdown Modal -->
<div class="modal fade" id="startBreakdownModal" tabindex="-1" aria-labelledby="startBreakdownModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="startBreakdownModalLabel">Start Machine Breakdown</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <form id="startBreakdownForm">
                    <div class="mb-3">
                        <label for="startBreakdownMachine" class="form-label">Machine</label>
                        <select class="form-select" id="startBreakdownMachine" required>
                            <option value="">Select Machine</option>
                            <?php foreach ($taskNames as $machineId => $taskName): ?>
                                <option value="<?php echo $machineId; ?>">
                                    <?php echo $taskName; ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div class="mb-3">
                        <label for="breakdownReason" class="form-label">Breakdown Reason</label>
                        <?php 
                        // Call Keycode function to generate dropdown
                        echo Keycode::getKeycodeListValue(
                            "breakdown_reason",
                            "", // Default empty value
                            "100%",
                            "Please Select",
                            "id",
                            "code",
                            "breakdown_reason", // ID for the select element
                            "",
                            "form-select", // Using form-select for Bootstrap 5 styling
                            false,
                            "required"
                        );
                        ?>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-danger" id="confirmStartBreakdownBtn">Start Breakdown</button>
            </div>
        </div>
    </div>
</div>

<!-- Stop Breakdown Modal -->
<div class="modal fade" id="stopBreakdownModal" tabindex="-1" aria-labelledby="stopBreakdownModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="stopBreakdownModalLabel">Stop Machine Breakdown</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <form id="stopBreakdownForm">
                    <div class="mb-3">
                        <label for="stopBreakdownMachine" class="form-label">Machine</label>
                        <select class="form-select" id="stopBreakdownMachine" required>
                            <option value="">Select Machine</option>
                            <?php 
                            // Only show machines that currently have active breakdowns
                            $activeBreakdownMachines = [];
                            $breakdownQuery = "SELECT DISTINCT mb.machine_id, sd.resource_code 
                                             FROM machine_breakdown mb 
                                             JOIN station_detail_table sd ON mb.machine_id = sd.id 
                                             WHERE mb.is_active = 1";
                            $breakdownResult = mysqli_query($conn, $breakdownQuery);
                            while ($row = mysqli_fetch_assoc($breakdownResult)) {
                                $activeBreakdownMachines[$row['machine_id']] = $row['resource_code'];
                            }
                            
                            foreach ($activeBreakdownMachines as $machineId => $machineName): 
                            ?>
                                <option value="<?php echo $machineId; ?>">
                                    <?php echo $machineName; ?> (Active Breakdown)
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div class="alert alert-warning">
                        <i class="fas fa-exclamation-triangle"></i>
                        This will stop the breakdown and recalculate affected work orders.
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-success" id="confirmStopBreakdownBtn">Stop Breakdown</button>
            </div>
        </div>
    </div>
</div>
<script>
// Breakdown Start/Stop functionality
document.getElementById('startBreakdownBtn').addEventListener('click', function() {
    var startBreakdownModal = new bootstrap.Modal(document.getElementById('startBreakdownModal'));
    startBreakdownModal.show();
});

document.getElementById('stopBreakdownBtn').addEventListener('click', function() {
    var stopBreakdownModal = new bootstrap.Modal(document.getElementById('stopBreakdownModal'));
    stopBreakdownModal.show();
});

// Start Breakdown

document.getElementById('confirmStartBreakdownBtn').addEventListener('click', function() {
    const machineId = document.getElementById('startBreakdownMachine').value;
    const reason = document.getElementById('breakdown_reason').value; 
    alert(reason);
    if (!machineId || !reason) {
        alert('Please select a machine and breakdown reason');
        return;
    }
    
    const breakdownData = {
        machine_id: machineId,
        breakdown_reason: reason,
    };
    
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=start_machine_breakdown",
        method: 'POST',
        data: breakdownData,
        dataType: 'json',
        success: function(response) {
            if (response.status === 'success') {
                alert('Breakdown started successfully');
                $('#startBreakdownModal').modal('hide');
                // Reset form
                document.getElementById('startBreakdownForm').reset();
                window.location.reload();
            } else {
                alert('Error starting breakdown: ' + response.message);
            }
        },
        error: function(xhr, status, error) {
            alert('Error starting breakdown: ' + error);
        }
    });
});
//  reset functionality when modal is shown
$('#startBreakdownModal').on('show.bs.modal', function () {
    document.getElementById('startBreakdownForm').reset();
});
// Stop Breakdown
document.getElementById('confirmStopBreakdownBtn').addEventListener('click', function() {
    const machineId = document.getElementById('stopBreakdownMachine').value;
    
    if (!machineId) {
        alert('Please select a machine with active breakdown');
        return;
    }
    
    const breakdownData = {
        machine_id: machineId
    };
    
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=stop_machine_breakdown",
        method: 'POST',
        data: breakdownData,
        dataType: 'json',
        success: function(response) {
            if (response.status === 'success') {
                alert('Breakdown stopped successfully');
                $('#stopBreakdownModal').modal('hide');
                window.location.reload();
            } else {
                alert('Error stopping breakdown: ' + response.message);
            }
        },
        error: function(xhr, status, error) {
            alert('Error stopping breakdown: ' + error);
        }
    });
});

// Helper function to refresh breakdown status (optional)
function refreshBreakdownStatus() {
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=get_breakdown_status",
        method: 'GET',
        dataType: 'json',
        success: function(response) {
            // Update UI based on breakdown status if needed
            console.log('Breakdown status updated', response);
        }
    });
}

// Auto-refresh breakdown status every 2 minutes
setInterval(refreshBreakdownStatus, 120000);
</script>
	
	<script>
    let draggedTask = null;
    let highlightedNeighbor = null;

    document.querySelectorAll('.gantt-task').forEach(task => {
        task.addEventListener('dragstart', (e) => {
            draggedTask = task;
            task.classList.add('dragging');
            console.log('Dragging task with priority:', task.dataset.priority);
        });

        task.addEventListener('dragend', (e) => {
            task.classList.remove('dragging');
            if (highlightedNeighbor) {
                highlightedNeighbor.classList.remove('highlight-border');
                highlightedNeighbor = null;
            }
        });
    });

    document.querySelectorAll('.gantt-row').forEach(row => {
        row.addEventListener('dragover', (e) => {
            e.preventDefault();
            row.classList.add('drop-target');
            
            if (!draggedTask) return;
            
            const dropX = e.clientX - row.getBoundingClientRect().left;
            const tasks = [...row.querySelectorAll('.gantt-task')];
            const otherTasks = tasks.filter(t => t !== draggedTask);
            
            otherTasks.sort((a, b) => parseFloat(a.style.left) - parseFloat(b.style.left));
            
            if (highlightedNeighbor) {
                highlightedNeighbor.classList.remove('highlight-border');
                highlightedNeighbor = null;
            }
            
            for (let i = 0; i < otherTasks.length; i++) {
                const task = otherTasks[i];
                const taskLeft = parseFloat(task.style.left);
                const taskRight = taskLeft + parseFloat(task.style.width);
                
                if (taskRight < dropX) {
                    highlightedNeighbor = task;
                } else {
                    break;
                }
            }
            
            if (highlightedNeighbor) {
                highlightedNeighbor.classList.add('highlight-border');
            }
        });

        row.addEventListener('dragleave', (e) => {
            row.classList.remove('drop-target');
            if (highlightedNeighbor) {
                highlightedNeighbor.classList.remove('highlight-border');
                highlightedNeighbor = null;
            }
        });

        row.addEventListener('drop', (e) => {
            e.preventDefault();
            row.classList.remove('drop-target');

            if (!draggedTask) return;

            const dropX = e.clientX - row.getBoundingClientRect().left;
            const tasks = [...row.querySelectorAll('.gantt-task')];
            const otherTasks = tasks.filter(t => t !== draggedTask);
            
            otherTasks.sort((a, b) => parseFloat(a.style.left) - parseFloat(b.style.left));

            let leftNeighbor = null;
            for (let i = 0; i < otherTasks.length; i++) {
                const task = otherTasks[i];
                const taskLeft = parseFloat(task.style.left);
                const taskRight = taskLeft + parseFloat(task.style.width);
                
                if (taskRight < dropX) {
                    leftNeighbor = task;
                } else {
                    break;
                }
            }

            if (highlightedNeighbor) {
                highlightedNeighbor.classList.remove('highlight-border');
                highlightedNeighbor = null;
            }

            const taskId = draggedTask.dataset.taskId;
            const newMachineId = row.dataset.machineId;
            const partId = draggedTask.dataset.partId;
            const workOrderId = draggedTask.dataset.workOrderId;
            const leftNeighborPriority = leftNeighbor ? leftNeighbor.dataset.priority : null;
            const leftNeighborTaskId = leftNeighbor ? leftNeighbor.dataset.taskId : null;
            const newPosition = dropX;
            
                $.ajax({
                    url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=update_assypu_task_priority",
                    method: 'POST',
                    data: { 
                        task_id: taskId,
                        new_machine_id: newMachineId,
                        part_id: partId, 
                        work_order_id: workOrderId, 
                        left_neighbor_priority: leftNeighborPriority,
                        left_neighbor_task_id: leftNeighborTaskId,
                        new_position: newPosition
                    }, 
                    dataType: 'json',
                    success: function(response) {
                        if (response.status === 'success') {
                            window.location.reload();
                        } else {
                            alert("Error updating task: " + response.message);
                        }
                    },
                    error: function(xhr, status, error) {
                        alert("Error updating task: " + error);
                    }
                });
            
        });
    });

    let scrollInterval = null;
    const ganttScrollable = document.querySelector('.gantt-scrollable-content');
    const scrollSpeed = 20;
    const scrollMargin = 50;

    function startAutoScroll(direction) {
        if (scrollInterval) clearInterval(scrollInterval);
        
        scrollInterval = setInterval(() => {
            if (direction === 'left') {
                ganttScrollable.scrollLeft -= scrollSpeed;
            } else {
                ganttScrollable.scrollLeft += scrollSpeed;
            }
        }, 20);
    }

    function stopAutoScroll() {
        if (scrollInterval) {
            clearInterval(scrollInterval);
            scrollInterval = null;
        }
    }

    document.addEventListener('dragover', (e) => {
        if (!draggedTask) return;
        
        const scrollRect = ganttScrollable.getBoundingClientRect();
        const xPos = e.clientX - scrollRect.left;
        
        if (xPos < scrollMargin) {
            startAutoScroll('left');
        } else if (xPos > (scrollRect.width - scrollMargin)) {
            startAutoScroll('right');
        } else {
            stopAutoScroll();
        }
    });

    document.addEventListener('dragend', () => {
        stopAutoScroll();
    });

    document.addEventListener('drop', () => {
        stopAutoScroll();
    });

    // Add Break functionality
    document.getElementById('addBreakBtn').addEventListener('click', function() {
        var breakModal = new bootstrap.Modal(document.getElementById('breakModal'));
        breakModal.show();
    });

    document.getElementById('saveBreakBtn').addEventListener('click', function() {
        const machineId = document.getElementById('breakMachine').value;
        const duration = parseFloat(document.getElementById('breakDuration').value);
        const reason = document.getElementById('breakReason').value;
        
        if (!machineId || isNaN(duration) || duration < 0.5 || duration > 10) {
            alert('Please fill all fields with valid values');
            return;
        }
        
        // Find the highest priority task for this machine
        const tasks = [...document.querySelectorAll('.gantt-task')];
        const machineTasks = tasks.filter(task => 
            task.dataset.currentMachine === machineId
        );
        
        let highestPriorityTask = null;
        if (machineTasks.length > 0) {
            machineTasks.sort((a, b) => a.dataset.priority - b.dataset.priority);
            highestPriorityTask = machineTasks[0];
        }
        
        // Prepare data for AJAX
        const breakData = {
            machine_id: machineId,
            duration: duration,
            reason: reason,
            highest_priority_task_id: highestPriorityTask ? highestPriorityTask.dataset.taskId : null,
            highest_priority: highestPriorityTask ? highestPriorityTask.dataset.priority : null
        };
        
        // Send AJAX request
        $.ajax({
            url: site_url + "/modules/machines_management/index.php?page=ajax_for_assypu&action=add_assypu_break",
            method: 'POST',
            data: breakData,
            dataType: 'json',
            success: function(response) {
                if (response.status === 'success') {
                    alert('Break added successfully');
                    window.location.reload();
                } else {
                    alert('Error adding break: ' + response.message);
                }
            },
            error: function(xhr, status, error) {
                alert('Error adding break: ' + error);
            }
        });
    });
    </script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$('body').addClass('sidebar-collapse');
</script>
    </div>
  </div>
</div>

<style>
  .split-container {
    display: flex;
    height: calc(100vh - 60px); /* Adjust based on your header height */
    width: 100%;
  }
  
  .split-panel {
    flex: 1;
    overflow: auto;
    padding: 10px;
    background-color: #f0f0f0;
    border: 1px solid #ccc;
  }
  
  #left-panel {
    background-color: #e6f7ff;
  }
  
  #right-panel {
    background-color: #fff2e6;
  }
  
  .split-divider {
    width: 10px;
    background-color: #ccc;
    cursor: col-resize;
  }
  #container {
    display: flex;
    width: 100%;
    height: 100vh;
  }

  #left-panel {
    flex: 20;
  }

  #divider {
    width: 5px;
    cursor: col-resize;
    background-color: #aaa;
  }

  #right-panel {
    flex: 70;
  }
</style>
<script>
  document.addEventListener('DOMContentLoaded', function() {
    const leftPanel = document.getElementById('left-panel');
    const rightPanel = document.getElementById('right-panel');
    const divider = document.getElementById('divider');

    let isDragging = false;

    divider.addEventListener('mousedown', function(e) {
      isDragging = true;
      document.body.style.cursor = 'col-resize';
      document.addEventListener('mousemove', onMouseMove);
      document.addEventListener('mouseup', onMouseUp);
    });

    function onMouseMove(e) {
      if (!isDragging) return;

      const container = divider.parentNode;
      const containerWidth = container.offsetWidth;
      const offsetX = e.clientX - container.getBoundingClientRect().left;

      // Minimum and maximum limits (optional)
      const minLeft = 10;  // in %
      const maxLeft = 90;

      let leftFlex = (offsetX / containerWidth) * 100;
      leftFlex = Math.max(minLeft, Math.min(maxLeft, leftFlex));
      let rightFlex = 100 - leftFlex;

      leftPanel.style.flex = leftFlex;
      rightPanel.style.flex = rightFlex;
    }

    function onMouseUp() {
      isDragging = false;
      document.body.style.cursor = '';
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
    }
  });
</script>
