<?php
/**
 * gantt_chart_assbly.php  (Assembly admin Gantt include + daily batch script)
 * =====================================================================
 * CHANGES FROM ORIGINAL:
 *   - recalculateMachineDatesforassbly() and handleMachineBreakdowns()
 *     removed — now the shared assbly_fullReschedule() and
 *     assbly_handleMachineBreakdowns() from assbly_scheduler_lib.php.
 *   - FIX: PASS 3's OK-quantity lookup had no task-instance scoping at
 *     all (the same bug found and fixed in CNC's and PU's equivalent
 *     batch scripts, and in Assypu's) — it summed production across
 *     every instance of a work_order+part combination ever scheduled
 *     (`WHERE work_order_id=... AND part_id=... AND partIds=...`),
 *     not just this specific task instance. If the same part had been
 *     split by a prior breakdown, or simply re-scheduled after a
 *     previous completed run, the "remaining quantity" this pass
 *     computed would be wrong — it would treat historical production
 *     from an unrelated task row as if it applied to the current one.
 *     Added `assbly_machine_table_id` (manuf_id) scoping, consistent
 *     with the fixed CNC/PU/Assypu batch scripts.
 *   - Machine-type filter for the breakdown-processing loop was already
 *     correct here (`machine_type = 2`, matching every other assembly
 *     machine query in this file) — unlike Assypu, there was no
 *     copy-paste mismatch to fix in this particular query.
 * =====================================================================
 */

require_once __DIR__ . '/assbly_scheduler_lib.php';

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

/* ---------------------------------------------------------------------
 * PASS 1: mark completed break tasks whose end_date has passed
 * ------------------------------------------------------------------- */
mysqli_query($conn, "
    UPDATE assbly_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 assbly_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 assbly_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 assbly_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)) {

    $assblyId    = 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 assbly_machine_table_id (= manuf_id), matching
    // every other consumer of assbly_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 assbly_part_count_log
        WHERE assbly_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 assbly_machine_table
        SET
            total_hours_update = '$remainingHours',
            total_hours        = '$remainingHours',
            setup_hours        = 0,
            finished           = '$finishedVal'
        WHERE id = '$assblyId'
    ";
    mysqli_query($conn, $updateSql);

    $machinesToReschedule[$machineId] = true;
}

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

/* ---------------------------------------------------------------------
 * PASS 4: breakdown-hours accrual for active breakdowns
 * Machine-type filter here was already correct (machine_type = 2,
 * matching every other assembly-machine query in this file) — no
 * copy-paste mismatch to fix, unlike Assypu's equivalent script.
 * ------------------------------------------------------------------- */
$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 = 2 AND mb.is_active = 1
";
$result = mysqli_query($conn, $query);

if ($result && mysqli_num_rows($result) > 0) {
    // assbly_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.
    assbly_handleMachineBreakdowns($conn);
    while ($machineRow = mysqli_fetch_assoc($result)) {
        assbly_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;">Assembly 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;">Assembly 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 loadAssemblyWorkOrders() {
    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_get_workorders&action=get_assembly_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);
            renderAssemblyReadyOrdersFromPHP();
            renderAssemblyNotReadyOrdersFromPHP();
        }
    });
}

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>Machine</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>
</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>${getAssemblyMachineSelectHtml(order.id, order.machine_id)}</td>
    <td>${escapeHtml(order.product_description)}</td>
    <td>${escapeHtml(order.end_date)}</td>
    <td>${escapeHtml(order.quantity)}</td>
    <td>${escapeHtml(order.total_hours)}</td>
</tr>`;
    });
    html += `</tbody></table>`;
    $('#assembly-ready-container').html(html);
       if (typeof $().select2 !== 'undefined') {
        $('.machine-select').select2({
            dropdownAutoWidth: true,
            width: 'resolve',
            dropdownParent: $(document.body)
        });
    }
    initTableSort('assemblyReadyTable');
}

function renderAssemblyNotReadyOrders(orders) {
    if (orders.length === 0) {
        $('#assembly-not-ready-container').html('<p class="p-3">No assembly not ready orders found.</p>');
        return;
    }
    let html = `
        <table class="table table-bordered table-sm mb-0" id="assemblyNotReadyTable">
            <thead class="table-light">
                <tr>
                    <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>Machine</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>
</tr>
                </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>${getAssemblyMachineSelectHtml(order.id, order.machine_id)}</td>
    <td>${escapeHtml(order.product_description)}</td>
    <td>${escapeHtml(order.end_date)}</td>
    <td>${escapeHtml(order.quantity)}</td>
    <td>${escapeHtml(order.total_hours)}</td>
</tr>`;
    });
    html += `</tbody></table>`;
    $('#assembly-not-ready-container').html(html);
        if (typeof $().select2 !== 'undefined') {
        $('.machine-select').select2({
            dropdownAutoWidth: true,
            width: 'resolve',
            dropdownParent: $(document.body)
        });
    }
    initTableSort('assemblyNotReadyTable');
}

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

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 type  = this.dataset.type;
            const tbody = table.querySelector('tbody');
            const rows  = Array.from(tbody.querySelectorAll('tr'));
            let direction = this.classList.contains('asc') ? 'desc' : 'asc';
            headers.forEach(h => h.classList.remove('asc', 'desc'));
            this.classList.add(direction);
            const columnIndex = Array.from(this.parentElement.children).indexOf(this);
            rows.sort((a, b) => {
                let aVal = a.children[columnIndex].textContent.trim();
                let bVal = b.children[columnIndex].textContent.trim();
                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;
            });
            rows.forEach(row => tbody.appendChild(row));
            if (typeof $().select2 !== 'undefined') {
                $('.machine-select').select2('destroy');
$('.machine-select').select2({
    dropdownAutoWidth: true,
    width: 'resolve',
    dropdownParent: $(document.body)
});
            }
        });
    });
}

function renderAssemblyReadyOrdersFromPHP() {
    <?php
    if (!empty($workOrderss_assm_ready)) {
        echo "renderAssemblyReadyOrders(" . json_encode($workOrderss_assm_ready) . ");";
    } else {
        echo "$('#assembly-ready-container').html('<p class=\"p-3\">No assembly ready orders found.</p>');";
    }
    ?>
}

function renderAssemblyNotReadyOrdersFromPHP() {
    <?php
    if (!empty($workOrderss_pending)) {
        echo "renderAssemblyNotReadyOrders(" . json_encode($workOrderss_pending) . ");";
    } else {
        echo "$('#assembly-not-ready-container').html('<p class=\"p-3\">No assembly not ready orders found.</p>');";
    }
    ?>
}

function escapeHtml(text) {
    if (text === null || text === undefined) return '';
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}
</script>
<script>
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');
        const machineSelectId = "machine_id_" + dbId;
        const machineId      = $("#" + machineSelectId).val();
        workOrders.push({ id: dbId, work_order_id: workOrderId, part_id: partId, machine_id: machineId });
    });
    if (workOrders.length === 0) { alert("Please select at least one work order."); return; }

    const $button  = $(button);
    const $spinner = $button.find('.btn-spinner');
    $button.prop('disabled', true).addClass('btn-loading');
    $spinner.removeClass('d-none');

    $.ajax({
        url: site_url + "/modules/machines_management/index.php?page=ajax_for_assmbly&action=select_order_for_assmbly",
        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 {
                console.error("Server response:", response);
            }
        },
        error: function (xhr, status, error) {
            console.error("AJAX Error:", error, xhr.responseText);
            location.reload();
        },
        complete: function() {
            $button.prop('disabled', false).removeClass('btn-loading');
            $spinner.addClass('d-none');
        }
    });
}

$(document).ready(function() {
    loadAssemblyWorkOrders();
    setInterval(loadAssemblyWorkOrders, 30000);
});
</script>
</div><!-- /.split-panel #left-panel -->

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

$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');

// Shifts
$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'];
        $shifts[]  = $shiftName;
        $shiftHours[$shiftName] = (float)$row['hours'];
        $shiftDays[$shiftName]  = $dayMap[(int)$row['day_shifts']];
        $shiftTimes[$shiftName] = ['start'=>$row['start_time'],'end'=>$row['end_time'],'hours'=>(float)$row['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;
}
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)) {

            // Collect this day's shifts first...
            $dayShifts = [];
            foreach ($shifts as $shift) {
                if ($shiftDays[$shift] === $dayOfWeek) {
                    $dayShifts[] = $shift;
                }
            }
            usort($dayShifts, function ($a, $b) use ($shiftTimes) {
                return strtotime($shiftTimes[$a]['start']) <=> strtotime($shiftTimes[$b]['start']);
            });

            foreach ($dayShifts as $shift) {
                $intervals=generateTimeIntervals($shiftTimes[$shift]['start'],$shiftTimes[$shift]['end']);
                $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"=>array_sum(array_column($intervals,'minutes'))
                ];
            }
        }
    }
    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;
}

// Active breakdowns (for label column styling only)
$activeBreakdowns=[];
$breakdownResult=mysqli_query($conn,"SELECT machine_id, breakdown_reason FROM machine_breakdown WHERE is_active=1");
while ($breakdown=mysqli_fetch_assoc($breakdownResult))
    $activeBreakdowns[$breakdown['machine_id']]=$breakdown['breakdown_reason'];

// Machine names (assembly = machine_type 2)
$taskNames=[];
$machineQuery=mysqli_query($conn,"SELECT id, resource_code FROM station_detail_table WHERE machine_type=2 AND hide=0");
while ($row=mysqli_fetch_assoc($machineQuery)) $taskNames[$row['id']]=$row['resource_code'];

// Colors
$colorPalette=['#e6f5f5','#f5e6f5','#e6ffe6','#fff2e6','#f0e6ff','#e6ffff','#ffe6f2','#f5f5e6','#e6f5f5','#f5e6ff','#e6ffec','#fff0e6','#e6f0ff','#ffe6ff','#e6ffe6','#f5e6e6','#e6e6f5','#f5f5e6','#e6f5f5','#f5e6f5'];
$machineColors=[]; $colorIndex=0;
foreach ($taskNames as $machineId=>$taskName) {
    $machineColors[$machineId]=$colorPalette[$colorIndex%count($colorPalette)];
    $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;border-right:3px solid rgba(255,255,255,0.5);}
    .gantt-task .task-content{padding:1px;font-size:10px;height:calc(100% - 20px);overflow:hidden;}
    .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;z-index:5;}
    .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;}
    .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);}
    .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;}
    .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;}
    /* Filter highlight */
    .gantt-task.filter-highlight{outline:3px solid yellow;box-shadow:0 0 15px yellow;z-index:10;}
    /* Status colours */
    .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;}
    /* Breakdown */
    .breakdown-task{background-color:var(--breakdown-color)!important;border-left:3px solid #cc0000!important;border-right:3px solid #cc0000!important;color:white!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}}
    /* Machine hide/show */
    .toggle-machine-visibility{transition:all 0.3s ease;}
    .toggle-machine-visibility:hover{color:#0056b3;transform:scale(1.2);}
    .hidden-machine-item{cursor:pointer;transition:background-color 0.3s ease;}
    .hidden-machine-item:hover{background-color:#e9ecef;}
    .hidden-machine-item:hover i{color:#28a745;}
    /* Bulk machine modal */
    #bulkMachineControlModal .form-check-input{position:relative!important;margin-left:8px!important;box-shadow:none!important;transition:none!important;}
    /* Split modal */
    .modal-dialog{max-width:800px;}
</style>

<div class="container-fluid">
    <div class="controls">
        <div class="row align-items-center mb-3">

            <!-- LEFT: title -->
            <div class="col-md-4">
                <h3 class="mb-0"><i class="fas fa-calendar-day me-2"></i>ASSEMBLY Gantt Chart</h3>
                <h5 class="text-muted"><?php echo date('l, F j, Y'); ?></h5>
            </div>

            <!-- RIGHT: filters + buttons -->
            <div class="col-md-8">
                <!-- Filter row -->
                <div class="row g-2 mb-2">
                    <div class="col-md-4">
                        <input type="text" id="filter_part" class="form-control" placeholder="Part Number">
                    </div>
                    <div class="col-md-4">
                        <input type="text" id="filter_wo" class="form-control" placeholder="Work Order">
                    </div>
                    <div class="col-md-4">
                        <button class="btn btn-success w-100" onclick="applyFilters()">
                            <i class="fas fa-filter me-1"></i>Apply Filter
                        </button>
                    </div>
                </div>
                <!-- Action buttons -->
                <div class="d-flex justify-content-end flex-wrap gap-2">
                    <button class="btn btn-info" id="showHiddenMachinesBtn">
                        <i class="fas fa-eye-slash me-1"></i>Show Hidden
                    </button>
                    <button class="btn btn-secondary" id="bulkMachineControlBtn">
                        <i class="fas fa-list-check me-1"></i>Bulk Hide/Show
                    </button>
                    <button class="btn btn-primary" onclick="loadAssemblyGanttRows()">
                        <i class="fas fa-sync-alt me-1"></i>Refresh
                    </button>
                    <button class="btn btn-warning" id="addBreakBtn">
                        <i class="fas fa-clock me-1"></i>Add Break
                    </button>
                    <button class="btn btn-danger hide" id="startBreakdownBtn">
                        <i class="fas fa-exclamation-triangle me-1"></i>Start Breakdown
                    </button>
                    <button class="btn btn-success hide" id="stopBreakdownBtn">
                        <i class="fas fa-check me-1"></i>Stop Breakdown
                    </button>
                </div>
            </div>
        </div>
    </div>

    <div class="gantt-container">
        <!-- Sticky machine labels -->
        <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;" data-machine-id="<?php echo $machineId; ?>">
                        <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; ?>
                                <i class="fas fa-eye toggle-machine-visibility"
                                   data-machine-id="<?php echo $machineId; ?>"
                                   style="position:absolute;top:5px;right:5px;cursor:pointer;color:#007bff;font-size:16px;z-index:100;"
                                   title="Hide this machine"></i>
                                <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>
                <?php 
                    endif;
                endforeach; ?>
            </div>
        </div>

        <!-- Scrollable Gantt content -->
        <div class="gantt-scrollable-content">
            <div class="gantt-grid">

                <!-- Time header — static PHP -->
                <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: loaded via AJAX -->
                <div id="assembly-gantt-rows-container">
                    <div style="padding:40px;text-align:center;color:#666;">
                        <div class="spinner-border text-primary" role="status"></div>
                        <p class="mt-2">Loading schedule...</p>
                    </div>
                </div>

            </div><!-- /.gantt-grid -->
        </div><!-- /.gantt-scrollable-content -->
    </div><!-- /.gantt-container -->
</div><!-- /.container-fluid -->


<!-- ══════════════════════════════════════════════════════════
     MODALS
     ══════════════════════════════════════════════════════════ -->

<!-- Work Order Detail Modal -->
<div class="modal fade" id="workOrderDetailModal" tabindex="-1" 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"><i class="fas fa-info-circle me-2"></i>Work Order Details</h5>
                <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body">
                <div id="detailLoadingSpinner" class="text-center py-5">
                    <div class="spinner-border text-primary" role="status"></div>
                    <p class="mt-2">Loading details...</p>
                </div>
                <div id="workOrderDetailContent" style="display:none;">
                    <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>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"></span></p>
                                    <p><strong>RefSalescode:</strong> <span id="detail_RefSalesCode"></span></p>
                                </div>
                            </div>
                        </div>
                    </div>
                    <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>
                    <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>
                    <!-- Notes -->
                    <div class="card mb-3 hide">
                        <div class="card-header bg-light"><h6 class="mb-0"><i class="fas fa-edit me-2"></i>Notes / Remarks</h6></div>
                        <div class="card-body">
                            <textarea id="task_note" class="form-control" rows="4" placeholder="Enter notes here..."></textarea>
                            <input type="hidden" id="note_task_id">
                            <input type="hidden" id="note_work_order_id">
                            <input type="hidden" id="note_part_id">
                            <button class="btn btn-success mt-2" onclick="saveTaskNote()">Save Note</button>
                        </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-info" id="splitWorkOrderBtn" style="display:none;"><i class="fas fa-cut me-2"></i>Split Work Order</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-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header bg-warning">
                <h5 class="modal-title"><i class="fas fa-edit me-2"></i>Edit Work Order</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></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 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 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 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 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 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 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>

<!-- Split Work Order Modal -->
<div class="modal fade" id="splitWorkOrderModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header bg-info text-white">
                <h5 class="modal-title"><i class="fas fa-cut me-2"></i>Split Work Order</h5>
                <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body">
                <div class="alert alert-info"><i class="fas fa-info-circle me-2"></i>Split this work order into two based on quantity.</div>
                <form id="splitWorkOrderForm">
                    <input type="hidden" id="split_task_id" name="task_id">
                    <div class="mb-3">
                        <label class="form-label"><strong>Current Quantity:</strong></label>
                        <p id="split_current_quantity" class="form-control-plaintext">-</p>
                    </div>
                    <div class="mb-3">
                        <label for="split_quantity" class="form-label">Split Quantity <span class="text-danger">*</span></label>
                        <input type="number" class="form-control" id="split_quantity" name="split_quantity" min="1" step="1" required>
                        <small class="form-text text-muted">Enter the quantity for the new work order</small>
                    </div>
                    <div id="split_preview" style="display:none;" class="mt-3">
                        <h6 class="border-bottom pb-2">Preview:</h6>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="card bg-light"><div class="card-body">
                                    <h6 class="card-title text-primary">Original WO</h6>
                                    <p class="mb-1"><strong>Quantity:</strong> <span id="preview_remaining_qty">-</span></p>
                                    <p class="mb-0"><strong>Hours:</strong> <span id="preview_remaining_hours">-</span></p>
                                </div></div>
                            </div>
                            <div class="col-md-6">
                                <div class="card bg-light"><div class="card-body">
                                    <h6 class="card-title text-success">New WO</h6>
                                    <p class="mb-1"><strong>Quantity:</strong> <span id="preview_split_qty">-</span></p>
                                    <p class="mb-0"><strong>Hours:</strong> <span id="preview_split_hours">-</span></p>
                                </div></div>
                            </div>
                        </div>
                    </div>
                    <div id="split_error" class="alert alert-danger mt-3" style="display:none;"></div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-info" id="confirmSplitBtn"><i class="fas fa-check me-2"></i>Confirm Split</button>
            </div>
        </div>
    </div>
</div>

<!-- Hidden Machines Modal -->
<div class="modal fade" id="hiddenMachinesModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header bg-info text-white">
                <h5 class="modal-title"><i class="fas fa-eye-slash me-2"></i>Hidden Machines</h5>
                <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body">
                <div id="hiddenMachinesLoadingSpinner" class="text-center py-5">
                    <div class="spinner-border text-primary" role="status"></div>
                    <p class="mt-2">Loading hidden machines...</p>
                </div>
                <div id="hiddenMachinesContent" style="display:none;">
                    <p class="text-muted">Click on a machine to unhide it</p>
                    <div class="list-group" id="hiddenMachinesList"></div>
                </div>
                <div id="hiddenMachinesEmpty" class="alert alert-info d-none">
                    <i class="fas fa-info-circle me-2"></i>No hidden machines found.
                </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>
            </div>
        </div>
    </div>
</div>

<!-- Bulk Machine Control Modal -->
<div class="modal fade" id="bulkMachineControlModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><i class="fas fa-list-check me-2"></i>Bulk Machine Control</h5>
                <button type="button" class="close" data-dismiss="modal">
    <span>&times;</span>
</button>
            </div>
            <div class="modal-body">
                <div class="mb-3">
                    <button type="button" class="btn btn-sm btn-outline-primary" id="selectAllMachinesBtn"><i class="fas fa-check-square me-1"></i>Select All</button>
                    <button type="button" class="btn btn-sm btn-outline-secondary ms-2" id="deselectAllMachinesBtn"><i class="fas fa-square me-1"></i>Deselect All</button>
                </div>
                <div class="alert alert-info"><i class="fas fa-info-circle me-2"></i>Select machines to hide or show, then click the appropriate button.</div>
                <div id="bulkMachineListContainer" style="max-height:400px;overflow-y:auto;border:1px solid #dee2e6;border-radius:5px;padding:15px;">
                    <div class="text-center p-3"><div class="spinner-border" role="status"></div><p>Loading machines...</p></div>
                </div>
            </div>
            <div class="modal-footer">
               <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-danger" id="bulkHideBtn"><i class="fas fa-eye-slash me-2"></i>Hide Selected</button>
                <button type="button" class="btn btn-success" id="bulkShowBtn"><i class="fas fa-eye me-2"></i>Show Selected</button>
            </div>
        </div>
    </div>
</div>

<!-- Start Breakdown Modal -->
<div class="modal fade" id="startBreakdownModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Start Machine Breakdown</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <form id="startBreakdownForm">
                    <div class="mb-3">
                        <label 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 class="form-label">Breakdown Reason</label>
                        <?php echo Keycode::getKeycodeListValue("breakdown_reason","","100%","Please Select","id","code","breakdown_reason","","form-select",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-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Stop Machine Breakdown</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <form id="stopBreakdownForm">
                    <div class="mb-3">
                        <label class="form-label">Machine</label>
                        <select class="form-select" id="stopBreakdownMachine" required>
                            <option value="">Select Machine</option>
                            <?php
                            $abResult=mysqli_query($conn,"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");
                            while ($row=mysqli_fetch_assoc($abResult)): ?>
                                <option value="<?php echo $row['machine_id']; ?>"><?php echo $row['resource_code']; ?> (Active Breakdown)</option>
                            <?php endwhile; ?>
                        </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>

<!-- Add Break Modal -->
<div class="modal fade" id="breakModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Add Machine Break</h5>
                <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
            </div>
            <div class="modal-body">
                <form id="breakForm">
                    <div class="mb-3">
                        <label class="form-label">Machine</label>
                        <select class="form-select" id="breakMachine" 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 class="form-label">Duration (hours)</label>
                        <input type="number" class="form-control" id="breakDuration" min="1" max="10" step="1" required>
                        <div class="form-text">Minimum 1 hour, Maximum 10 hours</div>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Reason</label>
                        <textarea class="form-control" id="breakReason" rows="2"></textarea>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-primary" id="saveBreakBtn">Save Break</button>
            </div>
        </div>
    </div>
</div>


<!-- ══════════════════════════════════════════════════════════
     SCRIPTS
     ══════════════════════════════════════════════════════════ -->
<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');

// ─────────────────────────────────────────────────────────────────────────────
// 1.  LOAD GANTT ROWS VIA AJAX
// ─────────────────────────────────────────────────────────────────────────────
function loadAssemblyGanttRows() {
    $('#assembly-gantt-rows-container').html(
        '<div style="padding:40px;text-align:center;color:#666;">' +
        '<div class="spinner-border text-primary" role="status"></div>' +
        '<p class="mt-2">Loading schedule...</p></div>'
    );
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=get_assembly_gantt_rows',
        method: 'GET',
        dataType: 'json',
        success: function(response) {
            if (response.success) {
                $('#assembly-gantt-rows-container').html(response.html);
                // Re-apply filters if any are active
                setTimeout(function() {
                    if ($('#filter_part').val() || $('#filter_wo').val()) {
                        applyFilters();
                    }
                }, 100);
            } else {
                $('#assembly-gantt-rows-container').html(
                    '<div class="alert alert-danger m-3">Failed to load rows: ' +
                    (response.message || 'Unknown error') + '</div>'
                );
            }
        },
        error: function(xhr, status, error) {
            console.error('AJAX error:', status, error);
            $('#assembly-gantt-rows-container').html(
                '<div class="alert alert-danger m-3">Error: ' + error +
                '<br><pre>' + xhr.responseText.substring(0,300) + '</pre></div>'
            );
        }
    });
}

$(document).ready(function() {
    loadAssemblyGanttRows();
});


// ─────────────────────────────────────────────────────────────────────────────
// 2.  FILTER SYSTEM (frontend-only, same as VAC)
// ─────────────────────────────────────────────────────────────────────────────
function applyFilters() {
    const partFilter = document.getElementById('filter_part').value.trim().toLowerCase();
    const woFilter   = document.getElementById('filter_wo').value.trim().toLowerCase();
 
    const tasks = document.querySelectorAll('.gantt-task');
 
    // ── No filters active → clear all highlights ──────────────────────────────
    if (!partFilter && !woFilter) {
        tasks.forEach(function(task) {
            task.classList.remove('filter-highlight');
        });
        document.querySelectorAll('.machine-section').forEach(function(section) {
            const card = section.querySelector('.card');
            if (!card) return;
            card.style.outline         = '';
            card.style.boxShadow       = '';
            card.style.backgroundColor = '';
        });
        return;
    }
 
    // ── Match tasks ───────────────────────────────────────────────────────────
    const matchedMachineIds = new Set();
 
    tasks.forEach(function(task) {
        // data-part  = product_name  (set in PHP by data-part="...")
        // data-wo    = work_order_name (set in PHP by data-wo="...")
        const part = (task.dataset.part || '').toLowerCase();
        const wo   = (task.dataset.wo   || '').toLowerCase();
 
        let match = true;
        if (partFilter && !part.includes(partFilter)) match = false;
        if (woFilter   && !wo.includes(woFilter))     match = false;
 
        if (match) {
            task.classList.add('filter-highlight');
 
            // Collect the machine ID this task belongs to
            const row = task.closest('.gantt-row');
            if (row && row.dataset.machineId) {
                // store as string — dataset always returns strings
                matchedMachineIds.add(row.dataset.machineId);
            }
        } else {
            task.classList.remove('filter-highlight');
        }
    });
 
    // ── Highlight / dim machine label cards ───────────────────────────────────
    // .machine-section elements live in .gantt-labels and each has
    // data-machine-id="123" set in the PHP label column loop.
    document.querySelectorAll('.machine-section').forEach(function(section) {
        const card = section.querySelector('.card');
        if (!card) return;
 
        // dataset.machineId is the camelCase version of data-machine-id
        const mid = section.dataset.machineId;
 
        if (matchedMachineIds.has(mid)) {
            // Gold highlight — machine has at least one matching task
            card.style.outline         = '3px solid #f5c518';
            card.style.boxShadow       = '0 0 12px rgba(245,197,24,0.8)';
            card.style.backgroundColor = '#fffbe6';
        } else {
            // Reset — no matching task on this machine
            card.style.outline         = '';
            card.style.boxShadow       = '';
            card.style.backgroundColor = '';
        }
    });
}
 
// Allow Enter key to trigger filter from either input
document.getElementById('filter_part').addEventListener('keypress', function(e) {
    if (e.key === 'Enter') applyFilters();
});
document.getElementById('filter_wo').addEventListener('keypress', function(e) {
    if (e.key === 'Enter') applyFilters();
});


// ─────────────────────────────────────────────────────────────────────────────
// 3.  WORK ORDER DETAIL MODAL — delegated click
// ─────────────────────────────────────────────────────────────────────────────
let currentTaskDetails = null;

$(document).on('click', '.gantt-task:not(.break-task):not(.dragging)', function() {
    loadWorkOrderDetails(
        this.dataset.taskId,
        this.dataset.workOrderId,
        this.dataset.partId,
        this.dataset.currentMachine
    );
});

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_assmbly&action=get_assmbly_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() {
            $('#detailLoadingSpinner').hide();
            $('#detailErrorMessage').removeClass('d-none');
        }
    });
}

function displayWorkOrderDetails(data) {
    $('#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 || '-');
    $('#task_note').val(data.task_note || '');
    $('#note_task_id').val(data.task_id);
    $('#note_work_order_id').val(data.work_order_id);
    $('#note_part_id').val(data.part_id);

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

    $('#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();
    }

    // Show/hide Split button — hide for breaks and qty <= 1
    if (data.is_break == 1 || data.quantity <= 1) {
        $('#splitWorkOrderBtn').hide();
    } else {
        $('#splitWorkOrderBtn').show();
    }
}

// Edit
$('#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);
    new bootstrap.Modal(document.getElementById('editWorkOrderModal')).show();
});

$('#saveEditBtn').on('click', function() {
    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_assmbly&action=update_assmbly_task',
        method: 'POST',
        data: {
            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()
        },
        dataType: 'json',
        success: function(response) {
            if (response.success) {
                alert('Work order updated successfully!');
                $('#editWorkOrderModal').modal('hide');
                loadAssemblyGanttRows();
            } else {
                alert('Error: ' + (response.message || 'Failed to update'));
                $btn.prop('disabled',false).html('<i class="fas fa-save me-2"></i>Save Changes');
            }
        },
        error: function() {
            alert('Error updating work order');
            $btn.prop('disabled',false).html('<i class="fas fa-save me-2"></i>Save Changes');
        }
    });
});

// Delete
$('#deleteWorkOrderBtn').on('click', function() {
    if (!currentTaskDetails) return;
    if (!confirm('Are you sure you want to delete this work order? This 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_assmbly&action=delete_assmbly_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!');
        window.location.reload();
              //  alert('Work order deleted successfully!');
              //  $('#workOrderDetailModal').modal('hide');
              //  loadAssemblyGanttRows();
              //  loadAssemblyWorkOrders();   
            } else {
                alert('Error: ' + (response.message || 'Failed to delete'));
                $btn.prop('disabled',false).html('<i class="fas fa-trash me-2"></i>Delete');
            }
        },
        error: function() {
            alert('Error deleting work order');
            $btn.prop('disabled',false).html('<i class="fas fa-trash me-2"></i>Delete');
        }
    });
});


// ─────────────────────────────────────────────────────────────────────────────
// 4.  SPLIT WORK ORDER
// ─────────────────────────────────────────────────────────────────────────────
$('#splitWorkOrderBtn').on('click', function() {
    if (!currentTaskDetails) return;
    $('#workOrderDetailModal').modal('hide');

    $('#split_task_id').val(currentTaskDetails.task_id);
    $('#split_current_quantity').text(currentTaskDetails.quantity);

    const maxSplitQty = currentTaskDetails.quantity - 1;
    if (maxSplitQty < 1) {
        $('#split_quantity').prop('disabled', true);
        $('#split_error').text('This work order cannot be split (quantity is 1)').show();
    } else {
        $('#split_quantity').prop('disabled', false).attr('max', maxSplitQty);
    }
    $('#split_quantity').val('');
    $('#split_preview').hide();
    $('#split_error').hide();
    $('#splitWorkOrderModal').modal('show');
});

// Live preview while typing split quantity
$('#split_quantity').on('input', function() {
    const splitQty   = parseFloat($(this).val());
    const currentQty = parseFloat(currentTaskDetails.quantity);
    const setupHours = parseFloat(currentTaskDetails.setup_hours);
    const totalHours = parseFloat(currentTaskDetails.total_hours);

    $('#split_error').hide();

    if (!splitQty || splitQty <= 0) { $('#split_preview').hide(); return; }
    if (splitQty >= currentQty) {
        $('#split_error').text('Split quantity must be less than current quantity (' + currentQty + ')').show();
        $('#split_preview').hide();
        return;
    }
    if (splitQty < 1) {
        $('#split_error').text('Split quantity must be at least 1').show();
        $('#split_preview').hide();
        return;
    }

    const hoursPerUnit    = (totalHours - setupHours) / currentQty;
    const remainingQty    = currentQty - splitQty;

    $('#preview_remaining_qty').text(remainingQty.toFixed(0));
    $('#preview_remaining_hours').text(((remainingQty * hoursPerUnit) + setupHours).toFixed(2) + 'h');
    $('#preview_split_qty').text(splitQty.toFixed(0));
    $('#preview_split_hours').text(((splitQty * hoursPerUnit) + setupHours).toFixed(2) + 'h');
    $('#split_preview').show();
});

$('#confirmSplitBtn').on('click', function() {
    const splitQty = parseFloat($('#split_quantity').val());
    if (!splitQty || splitQty <= 0) {
        $('#split_error').text('Please enter a valid split quantity').show();
        return;
    }
    const $btn = $(this);
    $btn.prop('disabled',true).html('<span class="spinner-border spinner-border-sm me-2"></span>Splitting...');
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=split_assmbly_work_order',
        method: 'POST',
        data: { task_id:$('#split_task_id').val(), split_quantity:splitQty },
        dataType: 'json',
        success: function(response) {
            if (response.success) {
                alert('Work order split successfully!\n\nOriginal WO: ' + response.original_quantity +
                      ' units (' + response.original_hours + 'h)\nNew WO: ' +
                      response.split_quantity + ' units (' + response.split_hours + 'h)');
                $('#splitWorkOrderModal').modal('hide');
                loadAssemblyGanttRows();
            } else {
                $('#split_error').text(response.message || 'Failed to split work order').show();
                $btn.prop('disabled',false).html('<i class="fas fa-check me-2"></i>Confirm Split');
            }
        },
        error: function() {
            $('#split_error').text('Error splitting work order').show();
            $btn.prop('disabled',false).html('<i class="fas fa-check me-2"></i>Confirm Split');
        }
    });
});


// ─────────────────────────────────────────────────────────────────────────────
// 5.  SAVE NOTE
// ─────────────────────────────────────────────────────────────────────────────
function saveTaskNote() {
    const $btn = $('button[onclick="saveTaskNote()"]');
    $btn.prop('disabled',true).html('<span class="spinner-border spinner-border-sm me-1"></span>Saving...');
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=save_assmbly_task_note',
        type: 'POST',
        data: {
            task_id:       $('#note_task_id').val(),
            work_order_id: $('#note_work_order_id').val(),
            part_id:       $('#note_part_id').val(),
            note:          $('#task_note').val()
        },
        success: function(res) {
            const data = (typeof res === 'string') ? JSON.parse(res) : res;
            if (data.status === 'success') {
                $btn.html('<i class="fas fa-check me-1"></i>Saved!');
                setTimeout(() => $btn.html('Save Note').prop('disabled',false), 2000);
            } else {
                $btn.html('Save Note').prop('disabled',false);
                alert('Failed to save note.');
            }
        },
        error: function() { $btn.html('Save Note').prop('disabled',false); alert('Error saving note.'); }
    });
}


// ─────────────────────────────────────────────────────────────────────────────
// 6.  DRAG & DROP — fully delegated, works on AJAX rows
// ─────────────────────────────────────────────────────────────────────────────
let draggedTask         = null;
let highlightedNeighbor = null;

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

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

document.addEventListener('dragstart', function(e) {
    const task = e.target.closest('.gantt-task');
    if (!task) return;
    draggedTask = task;
    task.classList.add('dragging');
});

document.addEventListener('dragend', function(e) {
    const task = e.target.closest('.gantt-task');
    if (!task) return;
    task.classList.remove('dragging');
    if (highlightedNeighbor) { highlightedNeighbor.classList.remove('highlight-border'); highlightedNeighbor = null; }
    draggedTask = null;
    stopAutoScroll();
});

document.addEventListener('dragover', function(e) {
    if (draggedTask && ganttScrollable) {
        const sr   = ganttScrollable.getBoundingClientRect();
        const xPos = e.clientX - sr.left;
        if (xPos < scrollMargin)                  startAutoScroll('left');
        else if (xPos > sr.width - scrollMargin)  startAutoScroll('right');
        else                                       stopAutoScroll();
    }
    const row = e.target.closest('.gantt-row');
    if (!row || !draggedTask) return;
    e.preventDefault();
    row.classList.add('drop-target');

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

    if (highlightedNeighbor) { highlightedNeighbor.classList.remove('highlight-border'); highlightedNeighbor = null; }
    for (let t of otherTasks) {
        if (parseFloat(t.style.left) + parseFloat(t.style.width) < dropX) highlightedNeighbor = t;
        else break;
    }
    if (highlightedNeighbor) highlightedNeighbor.classList.add('highlight-border');
});

document.addEventListener('dragleave', function(e) {
    const row = e.target.closest('.gantt-row');
    if (!row) return;
    if (!row.contains(e.relatedTarget)) {
        row.classList.remove('drop-target');
        if (highlightedNeighbor) { highlightedNeighbor.classList.remove('highlight-border'); highlightedNeighbor = null; }
    }
});

document.addEventListener('drop', function(e) {
    const row = e.target.closest('.gantt-row');
    if (!row || !draggedTask) return;
    e.preventDefault();
    row.classList.remove('drop-target');
    if (highlightedNeighbor) { highlightedNeighbor.classList.remove('highlight-border'); highlightedNeighbor = null; }
    stopAutoScroll();

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

    let leftNeighbor = null;
    for (let t of otherTasks) {
        if (parseFloat(t.style.left) + parseFloat(t.style.width) < dropX) leftNeighbor = t;
        else break;
    }

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


// ─────────────────────────────────────────────────────────────────────────────
// 7.  ADD BREAK
// ─────────────────────────────────────────────────────────────────────────────
document.getElementById('addBreakBtn').addEventListener('click', function() {
    new bootstrap.Modal(document.getElementById('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;
    }
    const tasks            = [...document.querySelectorAll('.gantt-task')];
    const machineTasks     = tasks.filter(t => t.dataset.currentMachine === machineId)
                                  .sort((a,b) => a.dataset.priority - b.dataset.priority);
    const highestPriorityTask = machineTasks[0] || null;

    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=add_assbly_break',
        method: 'POST',
        data: {
            machine_id:               machineId,
            duration:                 duration,
            reason:                   reason,
            highest_priority_task_id: highestPriorityTask ? highestPriorityTask.dataset.taskId  : null,
            highest_priority:         highestPriorityTask ? highestPriorityTask.dataset.priority : null
        },
        dataType: 'json',
        success: function(response) {
            if (response.status === 'success') {
                alert('Break added successfully');
                $('#breakModal').modal('hide');
                loadAssemblyGanttRows();
            } else { alert('Error adding break: ' + response.message); }
        },
        error: function(xhr,status,error) { alert('Error adding break: ' + error); }
    });
});


// ─────────────────────────────────────────────────────────────────────────────
// 8.  BREAKDOWN START / STOP
// ─────────────────────────────────────────────────────────────────────────────
document.getElementById('startBreakdownBtn').addEventListener('click', function() {
    new bootstrap.Modal(document.getElementById('startBreakdownModal')).show();
});
document.getElementById('stopBreakdownBtn').addEventListener('click', function() {
    new bootstrap.Modal(document.getElementById('stopBreakdownModal')).show();
});
$('#startBreakdownModal').on('show.bs.modal', function() {
    document.getElementById('startBreakdownForm').reset();
});
document.getElementById('confirmStartBreakdownBtn').addEventListener('click', function() {
    const machineId = document.getElementById('startBreakdownMachine').value;
    const reason    = document.getElementById('breakdown_reason').value;
    if (!machineId || !reason) { alert('Please select a machine and breakdown reason'); return; }
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=start_machine_breakdown',
        method: 'POST',
        data: { machine_id:machineId, breakdown_reason:reason },
        dataType: 'json',
        success: function(response) {
            if (response.status === 'success') {
                alert('Breakdown started successfully');
                $('#startBreakdownModal').modal('hide');
                document.getElementById('startBreakdownForm').reset();
                loadAssemblyGanttRows();
            } else { alert('Error: ' + response.message); }
        },
        error: function(xhr,status,error) { alert('Error: ' + error); }
    });
});
document.getElementById('confirmStopBreakdownBtn').addEventListener('click', function() {
    const machineId = document.getElementById('stopBreakdownMachine').value;
    if (!machineId) { alert('Please select a machine with active breakdown'); return; }
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=stop_machine_breakdown',
        method: 'POST',
        data: { machine_id:machineId },
        dataType: 'json',
        success: function(response) {
            if (response.status === 'success') {
                alert('Breakdown stopped successfully');
                $('#stopBreakdownModal').modal('hide');
                loadAssemblyGanttRows();
            } else { alert('Error: ' + response.message); }
        },
        error: function(xhr,status,error) { alert('Error: ' + error); }
    });
});
setInterval(function() {
    $.ajax({ url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=get_breakdown_status', method:'GET', dataType:'json',
        success: function(r) { console.log('Breakdown status updated', r); } });
}, 120000);


// ─────────────────────────────────────────────────────────────────────────────
// 9.  MACHINE HIDE / SHOW (full page reload — label column is PHP)
// ─────────────────────────────────────────────────────────────────────────────
$(document).on('click', '.toggle-machine-visibility', function(e) {
    e.stopPropagation();
    const machineId       = $(this).data('machine-id');
    const $icon           = $(this);
    const $machineSection = $(this).closest('.machine-section');
    const $ganttRow       = $(`.gantt-row[data-machine-id="${machineId}"]`);
    $icon.removeClass('fa-eye').addClass('fa-spinner fa-spin');
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=toggle_machine_visibility',
        method:'POST', data:{ machine_id:machineId, hide:1 }, dataType:'json',
        success: function(response) {
            if (response.status === 'success') {
                $machineSection.fadeOut(300, function() { $(this).remove(); });
                $ganttRow.fadeOut(300, function() { $(this).remove(); });
                showNotification('Machine hidden successfully', 'success');
				 loadAssemblyWorkOrders();
            } else {
                $icon.removeClass('fa-spinner fa-spin').addClass('fa-eye');
                showNotification('Error: ' + response.message, 'error');
            }
        },
        error: function(xhr,status,error) { $icon.removeClass('fa-spinner fa-spin').addClass('fa-eye'); showNotification('Error: ' + error, 'error'); }
    });
});

$('#showHiddenMachinesBtn').on('click', function() {
    new bootstrap.Modal(document.getElementById('hiddenMachinesModal')).show();
    loadHiddenMachines();
});

function loadHiddenMachines() {
    $('#hiddenMachinesLoadingSpinner').show();
    $('#hiddenMachinesContent').hide();
    $('#hiddenMachinesEmpty').addClass('d-none');
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=get_hidden_machines',
        method:'GET', dataType:'json',
        success: function(response) {
            $('#hiddenMachinesLoadingSpinner').hide();
            if (response.status === 'success' && response.data.length > 0) {
                let html = '';
                response.data.forEach(function(machine) {
                    html += `<div class="list-group-item list-group-item-action hidden-machine-item" data-machine-id="${machine.id}">
                        <div class="d-flex w-100 justify-content-between align-items-center">
                            <h6 class="mb-0"><i class="fas fa-server me-2"></i>${machine.resource_code}</h6>
                            <i class="fas fa-eye text-success" title="Click to unhide"></i>
                        </div></div>`;
                });
                $('#hiddenMachinesList').html(html);
                $('#hiddenMachinesContent').show();
            } else {
                $('#hiddenMachinesEmpty').removeClass('d-none');
            }
        },
        error: function(xhr,status,error) { $('#hiddenMachinesLoadingSpinner').hide(); showNotification('Error: ' + error, 'error'); }
    });
}

$(document).on('click', '.hidden-machine-item', function() {
    const machineId = $(this).data('machine-id');
    const $item     = $(this);
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=toggle_machine_visibility',
        method:'POST', data:{ machine_id:machineId, hide:0 }, dataType:'json',
        success: function(response) {
            if (response.status === 'success') {
                $item.fadeOut(300, function() {
                    $(this).remove();
                    if ($('#hiddenMachinesList .hidden-machine-item').length === 0) {
                        $('#hiddenMachinesContent').hide();
                        $('#hiddenMachinesEmpty').removeClass('d-none');
                    }
                });
                showNotification('Machine unhidden. Reloading...', 'success');
                setTimeout(function() { window.location.reload(); }, 1500);
            } else { showNotification('Error: ' + response.message, 'error'); }
        },
        error: function(xhr,status,error) { showNotification('Error: ' + error, 'error'); }
    });
});

function showNotification(message, type) {
    const notification = $(
        `<div class="alert alert-${type==='success'?'success':'danger'} alert-dismissible fade show"
              role="alert" style="position:fixed;top:20px;right:20px;z-index:9999;min-width:300px;">
            <i class="fas fa-${type==='success'?'check-circle':'exclamation-triangle'} me-2"></i>${message}
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
         </div>`);
    $('body').append(notification);
    setTimeout(function() { notification.alert('close'); }, 3000);
}


// ─────────────────────────────────────────────────────────────────────────────
// 10.  BULK MACHINE CONTROL
// ─────────────────────────────────────────────────────────────────────────────
document.getElementById('bulkMachineControlBtn').addEventListener('click', function() {
    new bootstrap.Modal(document.getElementById('bulkMachineControlModal')).show();
    loadAllMachinesForBulkControl();
});
function loadAllMachinesForBulkControl() {
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=get_all_assembly_machines',
        method:'GET', dataType:'json',
        success: function(response) {
            if (response.status==='success' && response.data) renderMachineCheckboxList(response.data);
            else $('#bulkMachineListContainer').html('<p class="text-danger p-3">Error loading machines</p>');
        },
        error: function(xhr,status,error) { $('#bulkMachineListContainer').html('<p class="text-danger p-3">Error: '+error+'</p>'); }
    });
}
function renderMachineCheckboxList(machines) {
    if (machines.length===0) { $('#bulkMachineListContainer').html('<p class="p-3">No machines found</p>'); return; }
    let html = '<div class="list-group">';
    machines.forEach(machine => {
        const statusBadge = machine.hide==1
            ? '<span class="badge bg-secondary ms-2">Hidden</span>'
            : '<span class="badge bg-success ms-2">Visible</span>';
        html += `<label class="list-group-item d-flex align-items-center" style="cursor:pointer;padding:12px 15px;">
            <input class="form-check-input me-3 bulk-machine-checkbox" type="checkbox"
                   value="${machine.id}" style="width:20px;height:20px;cursor:pointer;">
            <div class="flex-grow-1"><strong>${machine.resource_code}</strong>
            ${machine.resource_description?'<br><small class="text-muted">'+machine.resource_description+'</small>':''}</div>
            ${statusBadge}</label>`;
    });
    html += '</div>';
    $('#bulkMachineListContainer').html(html);
}
document.getElementById('selectAllMachinesBtn').addEventListener('click', function() { $('.bulk-machine-checkbox').prop('checked',true); });
document.getElementById('deselectAllMachinesBtn').addEventListener('click', function() { $('.bulk-machine-checkbox').prop('checked',false); });
document.getElementById('bulkHideBtn').addEventListener('click', function() { bulkToggleMachines(1); });
document.getElementById('bulkShowBtn').addEventListener('click', function() { bulkToggleMachines(0); });
function bulkToggleMachines(hideValue) {
    const selectedMachines = [];
    $('.bulk-machine-checkbox:checked').each(function() { selectedMachines.push(parseInt($(this).val())); });
    if (selectedMachines.length===0) { alert('Please select at least one machine'); return; }
    const $hideBtn=$('#bulkHideBtn'), $showBtn=$('#bulkShowBtn');
    const $clickedBtn = hideValue===1 ? $hideBtn : $showBtn;
    const originalText = $clickedBtn.html();
    $hideBtn.prop('disabled',true); $showBtn.prop('disabled',true);
    $clickedBtn.html('<span class="spinner-border spinner-border-sm me-2"></span>Processing...');
    $.ajax({
        url: site_url + '/modules/machines_management/index.php?page=ajax_for_assmbly&action=bulk_toggle_machine_visibility',
        method:'POST', data:{ machine_ids:JSON.stringify(selectedMachines), hide:hideValue }, dataType:'json',
        success: function(response) {
            if (response.status==='success') { $('#bulkMachineControlModal').modal('hide'); window.location.reload(); }
            else { alert('Error: '+(response.message||'Failed')); $clickedBtn.html(originalText); $hideBtn.prop('disabled',false); $showBtn.prop('disabled',false); }
        },
        error: function(xhr,status,error) { alert('Error: '+error); $clickedBtn.html(originalText); $hideBtn.prop('disabled',false); $showBtn.prop('disabled',false); }
    });
}
</script>
</div><!-- /.split-panel #right-panel -->
  </div><!-- /.split-container -->
</div><!-- /.container-fluid outer -->

<style>
  .split-container{display:flex;height:calc(100vh - 60px);width:100%;}
  .split-panel{flex:1;overflow:auto;padding:10px;background-color:#f0f0f0;border:1px solid #ccc;}
  #left-panel{background-color:#e6f7ff;flex:20;}
  #right-panel{background-color:#fff2e6;flex:70;}
  .split-divider{width:10px;background-color:#ccc;cursor:col-resize;}
  #divider{width:5px;cursor:col-resize;background-color:#aaa;}
</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 offsetX=e.clientX-container.getBoundingClientRect().left;
        let leftFlex=Math.max(10,Math.min(90,(offsetX/container.offsetWidth)*100));
        leftPanel.style.flex=leftFlex;
        rightPanel.style.flex=100-leftFlex;
    }
    function onMouseUp() {
        isDragging=false; document.body.style.cursor='';
        document.removeEventListener('mousemove',onMouseMove);
        document.removeEventListener('mouseup',onMouseUp);
    }
});
</script>