<?php
session_start();
include "config.php";
require_once __DIR__ . '/cnc_scheduler_lib.php';

if (!isset($_SESSION['engineer_id']) || !isset($_SESSION['machine_id'])) {
    die("Unauthorized access!");
}
$machine_id      = intval($_SESSION['machine_id']);
$engineer_id     = intval($_SESSION['engineer_id']);

$resource_code = '';
$rcSql = "SELECT resource_code FROM station_detail_table WHERE id = $machine_id LIMIT 1";
$rcRes = $conn->query($rcSql);
if ($rcRes && $rcRes->num_rows > 0) {
    $resource_code = $rcRes->fetch_assoc()['resource_code'];
}

$serverTime      = date('Y-m-d H:i:s');
$serverTimestamp = time() * 1000;

$today           = date('Y-m-d');
$cncMachineTableId = isset($_GET['cnc_id'])    ? intval($_GET['cnc_id'])    : null;
$table_id          = isset($_GET['table_id'])  ? intval($_GET['table_id']) : 1;
$no_of_table       = 2;
$ordersByTable = [];
$sql = "SELECT 
        v.id AS row_id,
        v.manuf_id AS id,
        v.part_id,
        v.table_id,
        v.machine_id,
        v.work_order_id,
        v.product_name,
        v.start_date,
        v.quantity,
        v.is_dual_table,
        v.total_hours,
        v.set_id,
        v.priority,
        v.end_date,
        v.is_break,
        v.finished,
        v.changeover_pending,
        c.start_time AS changeover_start,
        c.end_time   AS changeover_end,
        c.duration_seconds
        FROM cnc_machine_table v
        LEFT JOIN cnc_machine_changeover c
            ON c.work_order_table_id = v.manuf_id
           AND c.machine_id = v.machine_id
        WHERE v.machine_id = $machine_id
          AND v.is_break   = 0
          AND (v.finished = 0 OR (v.finished = 1 AND v.changeover_pending = 1))
        ORDER BY v.table_id, v.priority ASC, v.start_date ASC";

$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($result)) {

    $partDisplay = $row['product_name'];
    $partNumbers = [];

    if (!empty($row['set_id']) && $row['set_id'] != 0) {

        $mapSql = "SELECT part_id, ratio
                   FROM set_mangmnt_mapping
                   WHERE set_id = " . intval($row['set_id']);
        $mapRes = $conn->query($mapSql);

        $parts        = [];
        $partRatioMap = [];

        while ($mapRow = $mapRes->fetch_assoc()) {
            $partId             = intval($mapRow['part_id']);
            $ratio              = intval($mapRow['ratio']) ?: 1;
            $parts[]            = $partId;
            $partRatioMap[$partId] = $ratio;
        }

        if (!empty($parts)) {
            $partIds = implode(",", $parts);
            $itemSql = "SELECT id, part_number
                        FROM item_management
                        WHERE id IN ($partIds)";
            $itemRes      = $conn->query($itemSql);
            $partNumbers  = [];
            $displayParts = [];

            while ($itemRow = $itemRes->fetch_assoc()) {
                $ratio       = $partRatioMap[$itemRow['id']] ?? 1;
                $partNumbers[] = [
                    'id'          => $itemRow['id'],
                    'part_number' => $itemRow['part_number'],
                    'ratio'       => $ratio
                ];
                for ($i = 0; $i < $ratio; $i++) {
                    $displayParts[] = $itemRow['part_number'];
                }
            }
            $partDisplay = implode(", ", $displayParts);
        }
    }

    $document_upload = "";
    $document_dir    = "../admin/route_documents/";

    if (!empty($row['set_id']) && $row['set_id'] != 0) {
        $docSql       = "SELECT document_upload FROM set_route_details WHERE set_id = '" . $row['set_id'] . "'";
        $document_dir = "../admin/set_route_documents/";
    } else {
        $docSql = "SELECT document_upload FROM route_details WHERE item_id = '" . $row['part_id'] . "'";
    }

    $docResult = mysqli_query($conn, $docSql);
    if ($docResult && mysqli_num_rows($docResult) > 0) {
        $docRow          = mysqli_fetch_assoc($docResult);
        $document_upload = $docRow['document_upload'];
    }

    $row['document_upload'] = $document_upload;
    $row['document_dir']    = $document_dir;
    $row['product_name']    = $partDisplay;
    $row['part_numbers']    = $partNumbers;

    $ordersByTable[$row['table_id']][] = $row;
}

function getTotalCounts($conn, $workOrderId, $partId, $cncMachineTableId, $type, $isSet = false) {
    $workOrderId = intval($workOrderId);
    $partId      = intval($partId);
    $type        = $conn->real_escape_string($type);

    // NOTE: $cncMachineTableId here is manuf_id (see fetch query above,
    // which aliases v.manuf_id AS id) — matches cnc_part_count_log rows,
    // which are now written using manuf_id as cnc_machine_table_id.
    $sql = "SELECT SUM(quantity) AS total
            FROM cnc_part_count_log
            WHERE work_order_id        = $workOrderId
              AND cnc_machine_table_id = $cncMachineTableId
              AND part_id              = $partId
              AND type                 = '$type'";

    $result = $conn->query($sql);
    if (!$result) return "SQL ERROR: " . $conn->error;
    $row = $result->fetch_assoc();
    return $row['total'] ? $row['total'] : 0;
}

function getRemainingCncRequiredQty($conn, $currentManufId)
{
    $currentManufId = intval($currentManufId);

    $sql = "
    SELECT
        c.manuf_id,
        c.work_order_id,
        c.part_id,

        /* VAC driven target */
        ROUND(
            mt_c.quantity * COALESCE(vac.ok_qty,0) / NULLIF(mt_v.quantity,0),
            2
        ) AS vac_target_qty,

        /* Already produced by OTHER CNC rows */
        (
            SELECT COALESCE(SUM(l.quantity),0)
            FROM cnc_part_count_log l
            INNER JOIN cnc_machine_table c2
                    ON c2.manuf_id = l.cnc_machine_table_id
            WHERE c2.work_order_id = c.work_order_id
              AND c2.part_id       = c.part_id
              AND l.type           = 'ok'
              AND c2.manuf_id <> c.manuf_id
        ) AS already_done

    FROM cnc_machine_table c

    INNER JOIN manufacture_machine_table mt_c
            ON mt_c.id = c.manuf_id

    INNER JOIN manufacture_machine_table mt_v
            ON mt_v.parent_ids     = mt_c.part_id
           AND mt_v.work_order_id  = mt_c.work_order_id

    INNER JOIN vac_machine_table v
            ON v.manuf_id = mt_v.id

    LEFT JOIN (
        SELECT
            vac_machine_table_id,
            SUM(quantity) AS ok_qty
        FROM vac_part_count_log
        WHERE type='ok'
        GROUP BY vac_machine_table_id
    ) vac
        ON vac.vac_machine_table_id = v.manuf_id

    WHERE c.manuf_id = $currentManufId
    LIMIT 1";

    $res = mysqli_query($conn,$sql);

    if(!$res || mysqli_num_rows($res)==0){
        return null;
    }

    $row = mysqli_fetch_assoc($res);

    $target    = floatval($row['vac_target_qty']);
    $produced  = floatval($row['already_done']);

    $remaining = max(0, $target - $produced);

    return round($remaining,2);
}

function getMachineStatus($conn, $tableId, $machineId, $workOrderId, $partId, $cncMachineTableId) {

    $sql = "SELECT action_type
            FROM cnc_machine_activity_log
            WHERE work_order_id        = $workOrderId
              AND part_id              = $partId
              AND machine_id           = $machineId
              AND table_id             = $tableId
              AND cnc_machine_table_id = $cncMachineTableId
            ORDER BY created_at DESC
            LIMIT 1";

    $result = mysqli_query($conn, $sql);
    if ($result && mysqli_num_rows($result) > 0) {
        $row = mysqli_fetch_assoc($result);
        if (!empty($row['action_type'])) {
            return $row['action_type'];
        }
    }
    return 'pause';
}

function calculateAndStoreActualUPH($conn, $workOrderId, $partId, $machine_id, $cncMachineTableId, $isSet = false) {
    // NOTE: $cncMachineTableId here is manuf_id throughout this function.
    $countSql = "SELECT SUM(quantity) AS total
                 FROM cnc_part_count_log
                 WHERE work_order_id        = $workOrderId
                   AND cnc_machine_table_id = $cncMachineTableId
                   AND part_id              = $partId
                   AND type                 = 'ok'";
    $countResult = $conn->query($countSql);
    $countRow    = $countResult->fetch_assoc();
    $okCount     = $countRow['total'] ?? 0;
    $totalMade   = $okCount;

    $activitySql = "SELECT
                    MIN(CASE WHEN action_type = 'start'  THEN created_at END) AS first_start,
                    MAX(CASE WHEN action_type = 'finish' THEN created_at END) AS last_finish
                    FROM cnc_machine_activity_log
                    WHERE work_order_id        = $workOrderId
                      AND cnc_machine_table_id = $cncMachineTableId
                      AND part_id              = '$partId'";
    $activityRes = $conn->query($activitySql);
    $actualUph   = 0;

    if ($activityRes && $activityRes->num_rows > 0) {
        $activityRow = $activityRes->fetch_assoc();
        $firstStart  = $activityRow['first_start'];
        $lastFinish  = $activityRow['last_finish'];

        if ($firstStart) {
            if ($lastFinish) {
                $startTime    = strtotime($firstStart);
                $finishTime   = strtotime($lastFinish);
                $totalSeconds = $finishTime - $startTime;
            } else {
                $startTime    = strtotime($firstStart);
                $totalSeconds = time() - $startTime;
            }

            $nonProductiveSql = "SELECT action_type, created_at
                                 FROM cnc_machine_activity_log
                                 WHERE work_order_id        = $workOrderId
                                   AND cnc_machine_table_id = $cncMachineTableId
                                   AND part_id              = '$partId'
                                   AND action_type IN ('start','pause','break','breakdown')
                                 ORDER BY created_at ASC";
            $nonProdRes          = $conn->query($nonProductiveSql);
            $nonProductiveSeconds = 0;
            $lastPauseStart      = null;

            if ($nonProdRes && $nonProdRes->num_rows > 0) {
                while ($row = $nonProdRes->fetch_assoc()) {
                    $actionType = $row['action_type'];
                    $timestamp  = strtotime($row['created_at']);

                    if (in_array($actionType, ['pause','break','breakdown'])) {
                        $lastPauseStart = $timestamp;
                    } elseif ($actionType === 'start' && $lastPauseStart !== null) {
                        $nonProductiveSeconds += $timestamp - $lastPauseStart;
                        $lastPauseStart = null;
                    }
                }
                if ($lastPauseStart !== null) {
                    $endPoint              = $lastFinish ? strtotime($lastFinish) : time();
                    $nonProductiveSeconds += $endPoint - $lastPauseStart;
                }
            }

            $productiveSeconds = $totalSeconds - $nonProductiveSeconds;
            $totalHours        = max(0, $productiveSeconds) / 3600;
            $actualUph         = ($totalHours > 0) ? round($totalMade / $totalHours, 2) : 0;
        }
    }

    $checkSql    = "SELECT id FROM cnc_part_count_log
                    WHERE work_order_id        = $workOrderId
                      AND cnc_machine_table_id = $cncMachineTableId
                      AND part_id              = '$partId'
                    LIMIT 1";
    $checkResult = $conn->query($checkSql);
    if ($checkResult->num_rows > 0) {
        $updateUphSql = "UPDATE cnc_part_count_log
                         SET uph = $actualUph
                         WHERE work_order_id        = $workOrderId
                           AND cnc_machine_table_id = $cncMachineTableId
                           AND part_id              = '$partId'";
        if (!mysqli_query($conn, $updateUphSql)) {
            error_log("Failed to update UPH: " . mysqli_error($conn));
        }
    }
    return $actualUph;
}

function getPartNumbersFromSet($conn, $setId, $partId) {
    $partNumbers = [];
    if (!empty($setId) && $setId != 0) {
        $mapSql  = "SELECT smm.part_id, smm.ratio
                    FROM set_mangmnt_mapping smm
                    WHERE smm.set_id = " . intval($setId);
        $mapRes  = $conn->query($mapSql);
        $partMap = [];
        while ($mapRow = $mapRes->fetch_assoc()) {
            $partMap[$mapRow['part_id']] = intval($mapRow['ratio']) ?: 1;
        }
        if (!empty($partMap)) {
            $partIds = implode(",", array_keys($partMap));
            $itemSql = "SELECT id, part_number FROM item_management WHERE id IN ($partIds)";
            $itemRes = $conn->query($itemSql);
            while ($itemRow = $itemRes->fetch_assoc()) {
                $partNumbers[] = [
                    'id'          => $itemRow['id'],
                    'part_number' => $itemRow['part_number'],
                    'ratio'       => $partMap[$itemRow['id']] ?? 1,
                ];
            }
        }
    } else {
        $partNumbers[] = [
            'id'          => $partId,
            'part_number' => '',
            'ratio'       => 1,
        ];
    }
    return $partNumbers;
}

function getShiftForDatetime($shiftsByDay, $datetime) {
    $dayOfWeek = (int)date('N', strtotime($datetime));
    $timeOfDay = date('H:i:s', strtotime($datetime));
    if (!isset($shiftsByDay[$dayOfWeek])) return null;
    foreach ($shiftsByDay[$dayOfWeek] as $shift) {
        $shiftStart = $shift['start_time'];
        $shiftEnd   = $shift['end_time'];
        if ($shiftStart <= $shiftEnd) {
            if ($timeOfDay >= $shiftStart && $timeOfDay < $shiftEnd) return $shift['id'];
        } else {
            if ($timeOfDay >= $shiftStart || $timeOfDay < $shiftEnd) return $shift['id'];
        }
    }
    return null;
}

function getShiftStartDate($shiftsByDay, $datetime) {
    $dayOfWeek = (int)date('N', strtotime($datetime));
    $timeOfDay = date('H:i:s', strtotime($datetime));
    $date      = date('Y-m-d', strtotime($datetime));
    if (!isset($shiftsByDay[$dayOfWeek])) return $date;
    foreach ($shiftsByDay[$dayOfWeek] as $shift) {
        $shiftStart = $shift['start_time'];
        $shiftEnd   = $shift['end_time'];
        if ($shiftStart > $shiftEnd && $timeOfDay < $shiftEnd) {
            return date('Y-m-d', strtotime($date . ' -1 day'));
        }
    }
    return $date;
}

function isMachineInBreakdown($conn, $machineId) {
    $sql = "SELECT status
            FROM cnc_machine_breakdown_log
            WHERE machine_id = $machineId
            ORDER BY created_at DESC
            LIMIT 1";
    $res = mysqli_query($conn, $sql);
    if ($res && mysqli_num_rows($res) > 0) {
        $row = mysqli_fetch_assoc($res);
        return $row['status'] === 'active';
    }
    return false;
}

$tableOrdersJS        = [];
$tableBorders         = [];
$firstOffSignedByTable = [];

foreach ($ordersByTable as $tableId => $orders) {
    $tableOrdersJS[$tableId] = [];

    foreach ($orders as $order) {

        // $order['id'] is manuf_id (aliased in the fetch query above).
        $currentStatus = getMachineStatus(
            $conn,
            $tableId,
            $order['machine_id'],
            $order['work_order_id'],
            $order['part_id'],
            $order['id']
        );

        $order['machine_status'] = $currentStatus;
        $setId = isset($order['set_id']) ? intval($order['set_id']) : 0;
        $isSet = (!empty($setId) && $setId != 0);

        $okCount        = getTotalCounts($conn, $order['work_order_id'], $order['part_id'], $order['id'], 'ok',        $isSet);
        $nokCount       = getTotalCounts($conn, $order['work_order_id'], $order['part_id'], $order['id'], 'nok',       $isSet);
        $quarantineCount= getTotalCounts($conn, $order['work_order_id'], $order['part_id'], $order['id'], 'quarantine',$isSet);

        $actualUph = calculateAndStoreActualUPH(
            $conn,
            $order['work_order_id'],
            $order['part_id'],
            $order['machine_id'],
            $order['id'],
            $isSet
        );

// Dynamic required qty based on upstream VAC OK count
        $dynamicReqQty = getRemainingCncRequiredQty($conn, $order['manuf_id']);
        $qtyReqDisplay = ($dynamicReqQty !== null)
            ? (int)round($dynamicReqQty)   // round off to a whole unit for display
            : (int)$order['quantity'];

        // NEW: original_uph snapshot is a cnc_machine_table column, so this
        // must be looked up by manuf_id, not by the real row id.
        $snapshotSql = "SELECT original_uph
                        FROM cnc_machine_table
                        WHERE manuf_id = {$order['id']}
                          AND original_uph > 0
                        LIMIT 1";
        $snapshotRes = mysqli_query($conn, $snapshotSql);
        if ($snapshotRes && mysqli_num_rows($snapshotRes) > 0) {
            $snapshotRow = mysqli_fetch_assoc($snapshotRes);
            $originalUph = floatval($snapshotRow['original_uph']);
        } else {
            $productionHours = max(0, floatval($order['total_hours']) - floatval($order['setup_hours']));
            $originalUph     = ($productionHours > 0)
                ? round($order['quantity'] / $productionHours, 2)
                : 0;
        }

        $borderColor = "green";
        if ($originalUph > 0 && $actualUph > 0) {
            $borderColor = ($actualUph >= $originalUph) ? "green" : "red";
        }
        $tableBorders[$tableId] = $borderColor;

        // First-Off sign-off check — cnc_machine_table_id here is manuf_id,
        // matching first_off_signoff_cnc which stores manuf_id.
        $checkFirstOff = "SELECT id, signed_at
                          FROM cnc_first_off_signoff
                          WHERE work_order_id        = {$order['work_order_id']}
                            AND part_id              = {$order['part_id']}
                            AND cnc_machine_table_id = {$order['id']}
                          LIMIT 1";
        $firstOffRes    = mysqli_query($conn, $checkFirstOff);
        $firstOffSigned = false;

        if ($firstOffRes && mysqli_num_rows($firstOffRes) > 0) {
            $firstOffRow = mysqli_fetch_assoc($firstOffRes);
            $signedAt    = $firstOffRow['signed_at'];

            $shiftsByDay = [];
            $shiftResult = mysqli_query($conn, "SELECT * FROM working_hours");
            while ($shiftRow = mysqli_fetch_assoc($shiftResult)) {
                $day = (int)$shiftRow['day_shifts'];
                $shiftsByDay[$day][] = $shiftRow;
            }

            $shiftAtSignOff          = getShiftForDatetime($shiftsByDay, $signedAt);
            $shiftNow                = getShiftForDatetime($shiftsByDay, date('Y-m-d H:i:s'));
            $shiftStartDateAtSignOff = getShiftStartDate($shiftsByDay, $signedAt);
            $shiftStartDateNow       = getShiftStartDate($shiftsByDay, date('Y-m-d H:i:s'));

            if (
                $shiftAtSignOff !== null &&
                $shiftNow       !== null &&
                $shiftAtSignOff === $shiftNow &&
                $shiftStartDateAtSignOff === $shiftStartDateNow
            ) {
                $firstOffSigned = true;
            }
        }
        $firstOffSignedByTable[$tableId] = $firstOffSigned;

        $tableOrdersJS[$tableId][] = [
            "id"                 => $order['id'], // manuf_id — used as the identifier for all ajax actions
            "row_id"             => $order['row_id'], // real cnc_machine_table.id, kept for reference only
            "part_id"            => $order['part_id'],
            "set_id"             => $order['set_id'],
            "machine_id"         => $order['machine_id'],
            "document_upload"    => $order['document_upload'],
            "document_dir"       => $order['document_dir'],
            "product_name"       => $order['product_name'],
            "qty_req"            => $qtyReqDisplay,
            "original_uph"       => $originalUph,
            "ok"                 => $okCount,
            "nok"                => $nokCount,
            "quar"               => $quarantineCount,
            "work_order_id"      => $order['work_order_id'],
            "actual_uph"         => $actualUph,
            "border"             => $borderColor,
            "is_dual_table"      => $order['is_dual_table'],
            "part_numbers"       => $order['part_numbers'],
            "start_date"         => $order['start_date'],
            "end_date"           => $order['end_date'],
            "machine_status"     => $currentStatus,
            "first_off_signed"   => $firstOffSigned,
            "changeover_pending" => intval($order['changeover_pending']),
        ];
    }
}

$machineStatuses = [];
foreach ($tableOrdersJS as $tableId => $orders) {
    $machineStatuses[$tableId] = !empty($orders)
        ? $orders[0]['machine_status']
        : 'pause';
}

$table1Status = strtolower($machineStatuses[1] ?? 'pause');
$table2Status = strtolower($machineStatuses[2] ?? 'pause');

$productiveStatuses = ['start'];

$table1Running = in_array($table1Status, $productiveStatuses);
$table2Running = in_array($table2Status, $productiveStatuses);

$shouldRunClock = ($table1Running || $table2Running);

$prodDate = ((int)date('H') < 6)
    ? date('Y-m-d', strtotime('-1 day'))
    : date('Y-m-d');

$clockSql = "SELECT * FROM cnc_machine_clock_daily
             WHERE machine_id = $machine_id
               AND production_date = '$prodDate'
             LIMIT 1";
$clockRes = mysqli_query($conn, $clockSql);

if ($clockRes && mysqli_num_rows($clockRes) > 0) {
    $clockRow = mysqli_fetch_assoc($clockRes);
} else {
    mysqli_query($conn, "INSERT INTO cnc_machine_clock_daily
        (machine_id, production_date, production_seconds, last_start_time, is_running)
        VALUES ($machine_id, '$prodDate', 0, NULL, 0)");
    $clockRow = [
        'production_seconds' => 0,
        'last_start_time'    => null,
        'is_running'         => 0,
    ];
}

if ($shouldRunClock && !$clockRow['is_running']) {
    mysqli_query($conn, "UPDATE cnc_machine_clock_daily
        SET is_running = 1, last_start_time = NOW()
        WHERE machine_id = $machine_id
          AND production_date = '$prodDate'");
    $clockRow['is_running']      = 1;
    $clockRow['last_start_time'] = date('Y-m-d H:i:s');
} elseif (!$shouldRunClock && $clockRow['is_running']) {
    $elapsed = time() - strtotime($clockRow['last_start_time']);
    mysqli_query($conn, "UPDATE cnc_machine_clock_daily
        SET production_seconds = production_seconds + $elapsed,
            is_running = 0,
            last_start_time = NULL
        WHERE machine_id = $machine_id
          AND production_date = '$prodDate'");
    $clockRow['production_seconds'] += $elapsed;
    $clockRow['is_running']          = 0;
    $clockRow['last_start_time']     = null;
}

$storedSeconds = (int)$clockRow['production_seconds'];
if ($clockRow['is_running'] && $clockRow['last_start_time']) {
    $elapsed        = time() - strtotime($clockRow['last_start_time']);
    $storedSeconds += max(0, $elapsed);
}

$document_upload = "";
$document_dir    = "../admin/route_documents/";
$ext             = "";
$partNumbers     = [];
$workOrderId     = 0;
$partId          = 0;
$setId           = 0;
$detail          = null;

if ($cncMachineTableId) {
    $detailSql = "SELECT * FROM cnc_machine_table
                  WHERE manuf_id   = $cncMachineTableId
                    AND machine_id = $machine_id
                    AND table_id   = $table_id";
    $detailRes = $conn->query($detailSql);
    if ($detailRes && $detailRes->num_rows > 0) {
        $detail      = $detailRes->fetch_assoc();
        $partId      = $detail['part_id'];
        $workOrderId = $detail['work_order_id'];
        $setId       = isset($detail['set_id']) ? intval($detail['set_id']) : 0;
        $partNumbers = getPartNumbersFromSet($conn, $setId, $partId);

        if (!empty($setId) && $setId != 0) {
            $docSql       = "SELECT document_upload FROM set_route_details WHERE set_id = '$setId'";
            $document_dir = "../admin/set_route_documents/";
        } else {
            $docSql = "SELECT document_upload FROM route_details WHERE item_id = '$partId'";
        }

        $result_edit = mysqli_query($conn, $docSql);
        if ($result_edit && mysqli_num_rows($result_edit) > 0) {
            $row_edit        = mysqli_fetch_assoc($result_edit);
            $document_upload = $row_edit['document_upload'];
        }
        $ext = strtolower(pathinfo($document_upload, PATHINFO_EXTENSION));
    }
}

$isBreakdown = isMachineInBreakdown($conn, $machine_id);

$dualTableBlocked = [];
for ($t = 1; $t <= $no_of_table; $t++) {
    if (!empty($tableOrdersJS[$t])) {
        $firstOrder = $tableOrdersJS[$t][0];
        if ($firstOrder['is_dual_table'] == 1) {
            $oppositeTable          = ($t == 1) ? 2 : 1;
            $oppositeHasActiveOrder = !empty($tableOrdersJS[$oppositeTable]);
            if ($oppositeHasActiveOrder) {
                $dualTableBlocked[$t] = $oppositeTable;
            } else {
                $dualTableBlocked[$oppositeTable] = $t;
            }
        }
    }
}
?>

<style>
.bg-purple {
    background-color: #9c4893 !important;
}
.count-controls {
    display: flex;
    align-items: center;
    width: 100%;
}
.count-btn {
    flex: 0 0 auto;
    min-width: 80px;
}
.count-display {
    flex: 1;
    max-width: 100px;
    text-align: center;
}
.partinfoBox {
    border: 1px solid #9c4893;
    background: #D9D9D9;
    padding: 0.2rem 0.6rem;
}
.br-0 {
    border-radius: 0 !important;
}
.f-w-b {
    font-weight: bold !important;
}
.undoBtn {
    background: #EFB200;
    color: #fff;
    border: 1px solid #333;
}
.status-table {
    border-collapse: collapse;
    font-size: 16px;
    text-align: center;
    width: 100%;
}
.status-table td {
    border: 1px solid purple;
    padding: 7px 12px;
    width: 50%;
}
.status-table td:first-child {
    font-weight: bold;
    text-align: left;
}
.green {
    color: green;
    font-weight: bold;
}
.status-btn {
    padding: 15px 20px;
    font-size: 16px;
    font-weight: bold;
    color: white;
    background: #888;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    min-width: 160px;
    text-align: center;
}
.status-btn.break {
    background: gray;
}
.status-btn.breakdown {
    background: gray;
    border: 3px solid red;
}
.part-checkbox {
    margin: 8px 0;
    padding: 12px 15px;
    border: 2px solid #ddd;
    border-radius: 6px;
    transition: all 0.3s ease;
    cursor: pointer;
}
.part-checkbox:hover {
    background-color: #f8f9fa;
    border-color: #007bff;
}
.part-checkbox .form-check-input {
    width: 24px;
    height: 24px;
    margin-top: 0;
    margin-right: 12px;
    cursor: pointer;
    flex-shrink: 0;
}
.part-checkbox .form-check-label {
    font-size: 16px;
    font-weight: 500;
    cursor: pointer;
    margin-bottom: 0;
    line-height: 24px;
}
.part-checkbox:has(input:checked) { 
    background-color: #ffe5e5;
    border-color: #dc3545;
}
.part-checkbox input:checked ~ label { 
    color: #dc3545; 
    font-weight: 600; 
}
.part-checkbox:not(:has(input:checked)) {
    background-color: #e8fbe8;
    border-color: #28a745;
}
.part-checkbox:not(:has(input:checked)) .form-check-label {
    color: #28a745;
    font-weight: 600;
}
.part-checkbox .form-check {
    display: flex;
    align-items: center;
    margin-bottom: 0;
}
.part-checkbox * {
    transition: all 0.2s ease;
}
#reasonSelection .form-check {
    margin: 12px 0;
    padding: 18px 20px;
    border: 2px solid #ddd;
    border-radius: 6px;
    transition: all 0.3s ease;
    cursor: pointer;
    min-height: 60px;
}
#reasonSelection .form-check:hover {
    background-color: #f8f9fa;
    border-color: #dc3545;
}
#reasonSelection .form-check-input {
    width: 30px;
    height: 30px;
    margin-top: 0;
    margin-right: 12px;
    cursor: pointer;
}
#reasonSelection .form-check-label {
    font-size: 16px;
    font-weight: 500;
    cursor: pointer;
    line-height: 24px;
}
#reasonSelection .form-check:has(input:checked) {
    background-color: #ffe6e6;
    border-color: #dc3545;
}
#reasonSelection .form-check input:checked ~ label {
    color: #dc3545;
    font-weight: 600;
}
#partSelection,
#reasonSelection {
    max-height: 400px !important;
    overflow-y: auto;
}
.reason-item .form-check-label {
    margin-left: 28px;
}
#partSelectionModal .form-check {
    display: flex;
    align-items: center;
    gap: 12px;
    position: static;
}
#partSelectionModal .form-check-input {
    position: static;
    margin: 0;
    flex-shrink: 0;
}
#partSelectionModal .form-check-label {
    margin: 0;
    cursor: pointer;
}
.machine-table {
    border: 8px solid green;
    margin: 10px 0;
    padding: 0;
    border-radius: 2px;
    position: relative;
}
.table-header {
    background: #f8f9fa;
    padding: 10px;
    border-bottom: 1px solid #dee2e6;
}
.table-body {
    padding: 15px;
}
.machine-table.border-success {
    border-color: green !important;
}
.machine-table.border-danger {
    border-color: red !important;
}
.table-controls {
    position: absolute;
    top: 10px;
    right: 10px;
}
.btn-group .btn {
    height: 100px;
    font-size: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.table-changeover-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.95);
    z-index: 100;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(8px);
}
.table-changeover-content {
    text-align: center;
    padding: 20px;
    color: white;
    width: 100%;
    max-width: 500px;
}
.table-changeover-content h4 {
    color: #ffc107;
    margin-bottom: 15px;
    font-size: 20px;
}
.table-changeover-timer {
    font-size: 48px;
    font-weight: bold;
    font-family: monospace;
    background: rgba(0,0,0,0.5);
    padding: 15px;
    border-radius: 10px;
    margin: 15px 0;
    letter-spacing: 2px;
}
.table-changeover-progress {
    width: 100%;
    height: 8px;
    background: rgba(255,255,255,0.2);
    border-radius: 4px;
    overflow: hidden;
    margin: 15px 0;
}
.table-changeover-progress-bar {
    height: 100%;
    background: linear-gradient(90deg, #28a745, #ffc107, #dc3545);
    transition: width 0.1s linear;
    border-radius: 4px;
}
.table-changeover-stop-btn {
    background: #dc3545;
    color: white;
    border: none;
    padding: 8px 20px;
    font-size: 14px;
    font-weight: bold;
    border-radius: 5px;
    cursor: pointer;
    margin-top: 10px;
    transition: all 0.3s ease;
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 101;
}
.table-changeover-stop-btn:hover {
    background: #c82333;
    transform: scale(1.05);
}
.table-changeover-info {
    font-size: 14px;
    color: #ccc;
    margin: 10px 0;
}
.machine-table {
    position: relative;
    overflow: hidden;
}
.changeover-active {
    position: relative;
}
.changeover-badge {
    display: inline-block;
    background: #dc3545;
    color: white;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 12px;
    margin-left: 10px;
    animation: pulse 1s infinite;
}
@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.6; }
    100% { opacity: 1; }
}
.changeoverBtn {
    font-size: 16px !important;
    padding: 8px 20px !important;
    font-weight: bold !important;
}
@keyframes pulse-green {
    0% {
        background-color: #ffc107;
        box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.7);
    }
    70% {
        background-color: #ff9800;
        box-shadow: 0 0 0 10px rgba(255, 193, 7, 0);
    }
    100% {
        background-color: #ffc107;
        box-shadow: 0 0 0 0 rgba(255, 193, 7, 0);
    }
}
@keyframes flash-ok {
    0%   { background-color: #28a745; transform: scale(1); }
    25%  { background-color: #fff; transform: scale(0.93); box-shadow: 0 0 0 5px #28a74555; }
    100% { background-color: #28a745; transform: scale(1); box-shadow: none; }
}
@keyframes flash-nok {
    0%   { background-color: #dc3545; transform: scale(1); }
    25%  { background-color: #fff; transform: scale(0.93); box-shadow: 0 0 0 5px #dc354555; }
    100% { background-color: #dc3545; transform: scale(1); box-shadow: none; }
}
@keyframes flash-quarantine {
    0%   { background-color: #ffc107; transform: scale(1); }
    25%  { background-color: #fff; transform: scale(0.93); box-shadow: 0 0 0 5px #ffc10755; }
    100% { background-color: #ffc107; transform: scale(1); box-shadow: none; }
}
@keyframes flash-undo {
    0%   { background-color: #6c757d; transform: scale(1); }
    35%  { background-color: #dee2e6; transform: scale(0.91); }
    100% { background-color: #6c757d; transform: scale(1); }
}
.do-flash-ok        { animation: flash-ok        0.38s ease forwards; }
.do-flash-nok       { animation: flash-nok       0.38s ease forwards; }
.do-flash-quarantine{ animation: flash-quarantine 0.38s ease forwards; }
.do-flash-undo      { animation: flash-undo       0.28s ease forwards; }
.table-label {
    font-weight: bold;
    font-size: 30px;
}
.uph-live-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 500;
    padding: 2px 7px;
    border-radius: 20px;
    vertical-align: middle;
    margin-left: 4px;
}
.uph-live-badge.green  { background: #d4edda; color: #155724; }
.uph-live-badge.red    { background: #f8d7da; color: #721c24; }
.uph-live-badge.loading { background: #e9ecef; color: #6c757d; }
.uph-live-badge .dot {
    width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
}
.uph-live-badge.green .dot  { background: #28a745; animation: uph-pulse 1.4s ease-in-out infinite; }
.uph-live-badge.red   .dot  { background: #dc3545; animation: uph-pulse 1.4s ease-in-out infinite; }
.uph-live-badge.loading .dot { background: #adb5bd; }
@keyframes uph-pulse { 0%,100%{opacity:1} 50%{opacity:.3} }
.dual-table-badge {
    display: inline-block;
    background: #17a2b8;
    color: #fff;
    font-size: 13px;
    font-weight: bold;
    padding: 3px 10px;
    border-radius: 4px;
    margin: 0 6px;
    letter-spacing: 1px;
    vertical-align: middle;
    border: 2px solid #117a8b;
    animation: dual-pulse 2s infinite;
}
@keyframes dual-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(23,162,184,0.5); }
    50%       { box-shadow: 0 0 0 6px rgba(23,162,184,0); }
}
.dual-waiting-badge {
    display: inline-block;
    background: #ffc107;
    color: #333;
    font-size: 13px;
    font-weight: bold;
    padding: 3px 10px;
    border-radius: 4px;
    margin: 0 6px;
    letter-spacing: 1px;
    vertical-align: middle;
    border: 2px solid #d39e00;
    animation: waiting-pulse 1.5s infinite;
}
@keyframes waiting-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255,193,7,0.6); }
    50%       { box-shadow: 0 0 0 8px rgba(255,193,7,0); }
}
/* ── Finished-pending-changeover banner ── */
.finished-banner {
    font-size: 16px;
    font-weight: bold;
    border-radius: 4px;
}
</style>

<section class="content" style="margin-top:5vh;">
    <div class="container-fluid">

<div class="header" style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
    <div style="display:flex; align-items:center; gap:15px;">
        <button id="logoutBtn"
        data-code="<?= htmlspecialchars($resource_code, ENT_QUOTES) ?>"
        style="
            background: #dc3545;
            color: #fff;
            border: none;
            padding: 10px 22px;
            font-size: 16px;
            font-weight: bold;
            border-radius: 6px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            min-width: 130px;
            justify-content: center;
        ">
            <i class="fas fa-sign-out-alt"></i> Log Out
        </button>
        <h2 style="margin:0;">CNC Dashboard - <?= htmlspecialchars($resource_code) ?></h2>
    </div>
    <div style="display:flex; align-items:center; gap:20px;">
        <div id="clock" style="
            font-family: monospace;
            font-size: 18px;
            color: #2575fc;
            padding: 4px 10px;
            border-radius: 6px;
            background-color: #f0f0f0;
            text-align: center;
            min-width: 100px;
        ">00:00:00</div>
        <div style="text-align:center; min-width:180px;">
            <div style="font-size:11px; font-weight:500; letter-spacing:1px; color:var(--color-text-secondary); text-transform:uppercase; margin-bottom:2px;">
                Production Clock
            </div>
            <div id="productionClock" style="font-family:monospace; font-size:28px; font-weight:bold; color:#28a745; line-height:1;">00:00:00</div>
            <div id="clockStatusBadge" style="display:inline-block; font-size:11px; font-weight:bold; letter-spacing:1px; padding:2px 8px; border-radius:4px; margin-top:3px; background:#dc3545; color:#fff;">
                PAUSED
            </div>
        </div>
    </div>
</div>

<?php if ($isBreakdown): ?>
    <div class="machine-table text-center" style="border:10px solid red; padding:50px;">
        <h1 style="color:red;">⚠ MACHINE UNDER BREAKDOWN</h1>
        <p>Please resolve the issue before continuing production</p>
        <button id="breakdownOverBtn"
                class="btn btn-success btn-lg mt-3"
                data-machine="<?= $machine_id ?>">
            Breakdown Over
        </button>
    </div>

<?php else: ?>
        <?php for ($t = 1; $t <= $no_of_table; $t++): ?>
            <?php
            $isBlockedByDual = isset($dualTableBlocked[$t]);
            $blockedByTable  = $isBlockedByDual ? $dualTableBlocked[$t] : null;
            ?>

            <?php if ($isBlockedByDual):
                $dualOrderIsWaiting = isset($tableOrdersJS[$t])
                                   && !empty($tableOrdersJS[$t])
                                   && $tableOrdersJS[$t][0]['is_dual_table'] == 1;
            ?>

            <div class="machine-table"
                 id="table-<?= $t ?>"
                 style="border: 10px solid <?= $dualOrderIsWaiting ? '#ffc107' : '#17a2b8' ?>;
                        margin-bottom: 20px;
                        min-height: 160px;
                        display: flex;
                        align-items: center;
                        justify-content: center;">
                <div class="text-center py-4">
                    <?php if ($dualOrderIsWaiting): ?>
                        <div style="font-size: 48px; color: #ffc107;">
                            <i class="fas fa-hourglass-half"></i>
                        </div>
                        <h3 style="color: #ffc107; font-weight: bold; margin: 10px 0 6px;">
                            DUAL TABLE — WAITING
                        </h3>
                        <p class="text-muted mb-1">
                            This dual-table work order is waiting for
                            <strong>Table <?= $blockedByTable ?></strong>
                            to finish its current job before it can start.
                        </p>
                        <?php
                            $waitingOrderName = $tableOrdersJS[$t][0]['product_name'] ?? '';
                            if ($waitingOrderName):
                        ?>
                        <p class="text-muted mb-2" style="font-size:13px;">
                            Queued part: <strong><?= htmlspecialchars($waitingOrderName) ?></strong>
                        </p>
                        <?php endif; ?>
                        <span class="dual-waiting-badge mt-2" style="font-size: 15px; padding: 6px 16px;">
                            <i class="fas fa-hourglass-half"></i>
                            Waiting for Table <?= $blockedByTable ?> to finish
                        </span>
                    <?php else: ?>
                        <div style="font-size: 48px; color: #17a2b8;">
                            <i class="fas fa-clone"></i>
                        </div>
                        <h3 style="color: #17a2b8; font-weight: bold; margin: 10px 0 6px;">
                            DUAL TABLE WORK ORDER
                        </h3>
                        <p class="text-muted mb-0">
                            Table <?= $t ?> is running as part of the dual-table job on
                            <strong>Table <?= $blockedByTable ?></strong>
                        </p>
                        <span class="dual-table-badge mt-2" style="font-size: 15px; padding: 6px 16px;">
                            <i class="fas fa-link"></i> Linked to Table <?= $blockedByTable ?>
                        </span>
                    <?php endif; ?>
                </div>
            </div>

            <?php elseif (!empty($tableOrdersJS[$t])):
                $first             = $tableOrdersJS[$t][0];
                $machineStatus     = $first['machine_status'];
                $borderColor       = isset($tableBorders[$t]) ? $tableBorders[$t] : 'green';
                $firstOffSigned    = $first['first_off_signed'] ?? false;
                $changeoverPending = intval($first['changeover_pending'] ?? 0);
            ?>

            <div class="machine-table <?= $borderColor == 'green' ? 'border-success' : 'border-danger' ?>"
                 id="table-<?= $t ?>"
                 style="border:10px solid <?= $borderColor ?>; margin-bottom:20px;">
                <div class="table-header">
                    <div class="row">
                        <div class="col-md-8">
                            <strong>
                                <span class="table-label">Table <?= $t ?> |</span>
                                <?php if ($first['is_dual_table'] == 1): ?>
                                    <span class="dual-table-badge">
                                        <i class="fas fa-clone"></i> DUAL
                                    </span>
                                <?php endif; ?>
                                <span class="table-label"> |</span>
                                Part No : <span class="part_name"><?= $first["product_name"] ?></span> | 
                                UPH: <span class="planned_uph"><?= round($first["original_uph"], 2) ?></span> |
                                Actual UPH: <span class="actual_uph" id="actual-uph-t<?= $t ?>"><?= $first["actual_uph"] ?></span>
                                <span class="uph-live-badge loading" id="uph-badge-t<?= $t ?>">
                                    <span class="dot"></span>
                                    <span class="uph-badge-label">…</span>
                                </span> |
                                <span class="qty_req hide" style="font-size: 25px; font-weight: bold;">QTY Req :</span>
                                <span class="qty_req hide" style="font-size: 25px; font-weight: bold;"><?= $first["qty_req"] ?></span>
                               QTY Good : <span class="qty_good"><?= $first["ok"] ?></span> |
                               QTY Req : <span class="qty_req"><?= $first["qty_req"] ?></span>
                            </strong>
                        </div>
                        <div class="col-md-4 text-right">
                            <?php if (!$firstOffSigned && !$changeoverPending): ?>
                                <button class="btn btn-dark btn-lg firstOffBtn mr-2"
                                        data-table="<?= $t ?>"
                                        data-cnc-id="<?= $first['id'] ?>">
                                    <i class="fas fa-stamp"></i> First-Off
                                </button>
                            <?php elseif ($firstOffSigned && !$changeoverPending): ?>
                                <span class="badge bg-success mr-2">
                                    <i class="fas fa-check"></i> Approved
                                </span>
                            <?php endif; ?>

                            <button class="btn btn-warning btn-lg changeoverBtn"
                                    data-table="<?= $t ?>"
                                    data-cnc-id="<?= $first['id'] ?>">
                                <i class="fas fa-exchange-alt"></i> Changeover
                            </button>
                        </div>
                    </div>
                </div>

                <div class="table-body">
                    <?php if ($changeoverPending): ?>
                    <!-- ── Finished banner — shown when changeover_pending = 1 ── -->
                    <div class="finished-banner alert alert-success text-center py-2 mb-3">
                        <i class="fas fa-check-circle"></i>
                        Order Finished — Complete changeover to remove from dashboard
                    </div>
                    <?php endif; ?>

                    <div class="row text-center">
                        <div class="col-md-3">
                            <button type="button" class="btn btn-success w-100 increment-btn mb-2 py-3"
                                    data-type="ok"
                                    data-table="<?= $t ?>"
                                    data-cnc-id="<?= $first['id'] ?>"
                                    <?= ($changeoverPending || in_array($machineStatus, ['pause', 'break', 'breakdown'])) ? 'disabled' : '' ?>>
                                OK
                            </button>
                            <div class="input-group">
                                <input type="number" class="form-control text-center ok-count" value="<?= $first['ok'] ?>" readonly style="font-size: 30px; font-weight: bold;">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary decrement-btn"
                                            type="button"
                                            data-type="ok"
                                            data-table="<?= $t ?>"
                                            data-cnc-id="<?= $first['id'] ?>"
                                            <?= $changeoverPending ? 'disabled' : '' ?>>
                                        Undo
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="col-md-3">
                            <button type="button" class="btn btn-danger w-100 increment-btn mb-2 py-3"
                                    data-type="nok"
                                    data-table="<?= $t ?>"
                                    data-cnc-id="<?= $first['id'] ?>"
                                    <?= ($changeoverPending || in_array($machineStatus, ['pause', 'break', 'breakdown'])) ? 'disabled' : '' ?>>
                                NOK
                            </button>
                            <div class="input-group">
                                <input type="number"
                                       class="form-control text-center nok-count"
                                       value="<?= $first['nok'] ?>"
                                       readonly
                                       style="font-size: 30px; font-weight: bold;">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary decrement-btn"
                                            type="button"
                                            data-type="nok"
                                            data-table="<?= $t ?>"
                                            data-cnc-id="<?= $first['id'] ?>"
                                            <?= $changeoverPending ? 'disabled' : '' ?>>
                                        Undo
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="col-md-3">
                            <button type="button" class="btn btn-warning w-100 increment-btn mb-2 py-3"
                                    data-type="quarantine"
                                    data-table="<?= $t ?>"
                                    data-cnc-id="<?= $first['id'] ?>"
                                    <?= ($changeoverPending || in_array($machineStatus, ['pause', 'break', 'breakdown'])) ? 'disabled' : '' ?>>
                                QUAR
                            </button>
                            <div class="input-group">
                                <input type="number" class="form-control text-center quar-count" value="<?= $first['quar'] ?>" readonly style="font-size: 30px; font-weight: bold;">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary decrement-btn"
                                            type="button"
                                            data-type="quarantine"
                                            data-table="<?= $t ?>"
                                            data-cnc-id="<?= $first['id'] ?>"
                                            <?= $changeoverPending ? 'disabled' : '' ?>>
                                        Undo
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="col-md-3">
                            <?php if (!$changeoverPending): ?>
                            <div class="btn-group w-100">
                                <button class="btn <?= $machineStatus === 'pause' ? 'btn-success' : 'btn-dark' ?> machine-action"
                                        data-table="<?= $t ?>"
                                        data-action="<?= $machineStatus === 'pause' ? 'pause' : 'start' ?>"
                                        data-cnc-id="<?= $first['id'] ?>">
                                    <?= $machineStatus === 'pause' ? 'Start' : 'Pause' ?>
                                </button>
                                <button class="btn btn-primary finish-btn"
                                        data-table="<?= $t ?>"
                                        data-cnc-id="<?= $first['id'] ?>">
                                    Finished
                                </button>
                                <button class="btn btn-info details-btn"
                                        data-table="<?= $t ?>"
                                        data-order='<?= json_encode($first) ?>'>
                                    Details
                                </button>
                            </div>
                            <?php else: ?>
                            <button class="btn btn-info details-btn w-100"
                                    data-table="<?= $t ?>"
                                    data-order='<?= json_encode($first) ?>'>
                                <i class="fas fa-info-circle"></i> Details
                            </button>
                            <?php endif; ?>
                        </div>
                    </div>
                </div>
            </div>

            <?php else: ?>
            <div class="machine-table" style="border:1px solid #ccc; margin-bottom:20px;">
                <div class="table-header">
                    <strong>Table <?= $t ?> - No orders scheduled</strong>
                </div>
            </div>
            <?php endif; ?>
        <?php endfor; ?>

        <div class="footer row mt-4">
            <div class="col-md-4">
                <button id="toggleAllBtn" class="btn btn-warning w-100 py-4">
                    <i class="fas fa-pause mr-2"></i> Pause/Start All Tables
                </button>
            </div>
            <div class="col-md-4">
                <button id="scheduleBreakAll" class="btn btn-info w-100 py-4">
                    <i class="fas fa-clock mr-2"></i> Schedule Break All Tables
                </button>
            </div>
            <div class="col-md-4">
                <button id="breakdownAllBtn" class="btn btn-danger w-100 py-4">
                    <i class="fas fa-exclamation-triangle mr-2"></i> Machine Breakdown
                </button>
            </div>
        </div>
<?php endif; ?>
    </div>
</section>

<!-- Changeover Overlay -->
<div id="changeoverOverlay" class="changeover-overlay" style="display: none;">
    <div class="changeover-container">
        <div class="changeover-spinner"></div>
        <h2>🔄 CHANGEOVER IN PROGRESS</h2>
        <div class="changeover-info">
            <strong>Table: <span id="changeoverTableDisplay"></span></strong>
        </div>
        <div class="changeover-timer" id="changeoverTimer">00:00:00</div>
        <div class="changeover-progress">
            <div class="changeover-progress-bar" id="changeoverProgress"></div>
        </div>
        <div class="changeover-info" id="changeoverStartedAt"></div>
        <button class="changeover-stop-btn" onclick="stopChangeover()">
            <i class="fas fa-stop"></i> Stop Changeover
        </button>
    </div>
</div>

<!-- First-Off Modal -->
<div class="modal fade" id="firstOffModal" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header bg-dark text-white">
                <h5 class="modal-title">
                    <i class="fas fa-stamp mr-2"></i>
                    First-Off Quality Approval
                </h5>
                <button type="button" class="close" data-dismiss="modal">&times;</button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label><strong>Enter QC Clock Number</strong></label>
                    <input type="text" id="qc_clock_no" class="form-control" placeholder="Enter Clock Number" required>
                </div>
                <div class="form-group mt-3">
                    <label><strong>QC Comment</strong></label>
                    <textarea id="qc_comment" class="form-control" rows="3" placeholder="Enter approval comment (optional)"></textarea>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button class="btn btn-dark" id="submitFirstOff">Approve</button>
            </div>
        </div>
    </div>
</div>

<!-- Changeover Modal -->
<div class="modal fade" id="changeoverModal" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header bg-warning text-white">
                <h5 class="modal-title">
                    <i class="fas fa-exchange-alt mr-2"></i>
                    Start Changeover - Table <span id="changeoverTableId"></span>
                </h5>
                <button type="button" class="close" data-dismiss="modal">&times;</button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label><strong>Enter Employee Clock Number</strong></label>
                    <input type="text" id="changeover_clock_no" class="form-control" placeholder="Enter Clock Number" required>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button class="btn btn-warning" id="submitChangeover">Start</button>
            </div>
        </div>
    </div>
</div>

<!-- Part Selection Modal -->
<div class="modal fade" id="partSelectionModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header bg-warning text-white">
                <h5 class="modal-title"><i class="fas fa-cogs mr-2"></i>Select Part Number</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <h6 class="mb-3">Please select the part number(s):</h6>
                <div id="partSelection" style="max-height: 200px; overflow-y: auto;"></div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-warning" id="proceedToReason">Next</button>
            </div>
        </div>
    </div>
</div>

<!-- Reason Selection Modal -->
<div class="modal fade" id="reasonModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header bg-danger text-white">
                <h5 class="modal-title"><i class="fas fa-exclamation-circle mr-2"></i>Select Reason</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <h6 class="mb-3">Select Reason</h6>
                <div id="reasonSelection" style="max-height: 400px; overflow-y: auto;">
                    <?php
                    $reasonSql = "SELECT * FROM reason_codes";
                    $reasonRes = $conn->query($reasonSql);
                    while ($r = $reasonRes->fetch_assoc()): ?>
                        <div class="form-check mb-2 reason-item">
                            <input class="form-check-input reason-radio" type="radio" name="reason_id" value="<?= $r['id'] ?>" id="reason<?= $r['id'] ?>">
                            <label class="form-check-label" for="reason<?= $r['id'] ?>">
                                <?= htmlspecialchars($r['reason_name']); ?>
                            </label>
                        </div>
                    <?php endwhile; ?>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-secondary" id="backToParts">Back</button>
                <button class="btn btn-danger" id="submitNok">Submit</button>
            </div>
        </div>
    </div>
</div>

<!-- Breakdown Modal -->
<div class="modal fade" id="breakdownModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header bg-danger text-white">
                <h5 class="modal-title"><i class="fas fa-tools mr-2"></i>Machine Breakdown</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="form-group hide">
                    <label for="breakdown_duration"><strong>Breakdown Duration (hours)</strong></label>
                    <input type="number" class="form-control" id="breakdown_duration" min="0.5" max="24" step="0.5" value="0.5" required>
                    <small class="form-text text-muted">Enter duration between 0.5 and 24 hours</small>
                </div>
                <div class="form-group">
                    <label for="breakdown_reason"><strong>Breakdown Reason</strong></label>
                    <?php
                    echo Keycode::getKeycodeListValue(
                        "cnc_machine_breakdown_reason", $cnc_machine_breakdown_reason, "100%", "Please Select",
                        "id", "code", "cnc_machine_breakdown_reason", "", "form-control", false, "required"
                    );
                    ?>
                </div>
                <input type="hidden" id="breakdown_table_id" value="">
                <input type="hidden" id="breakdown_cnc_id" value="">
            </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="submitBreakdown">Submit</button>
            </div>
        </div>
    </div>
</div>

<!-- Schedule Break Modal -->
<div class="modal fade" id="scheduleBreakModal" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header bg-warning">
                <h5 class="modal-title"><i class="fas fa-coffee mr-2"></i> Start Break</h5>
                <button type="button" class="close" data-dismiss="modal">&times;</button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label><b>Break Type</b></label>
                    <select id="breakType" class="form-control">
                        <option value="">-- Select Break --</option>
                        <option value="20">EARLY BREAK (20 mins)</option>
                        <option value="30">LUNCH BREAK (30 mins)</option>
                        <option value="custom">OTHER</option>
                    </select>
                </div>
                <div class="form-group mt-3">
                    <label><b>Duration (Minutes)</b></label>
                    <input type="text" id="breakDuration" class="form-control" placeholder="Auto-filled" readonly>
                </div>
                <div class="form-group mt-3">
                    <label><b>Remarks (Optional)</b></label>
                    <textarea id="breakRemarks" class="form-control" rows="2" placeholder="Enter remarks..."></textarea>
                </div>
                <input type="hidden" id="break_table_id" value="">
                <input type="hidden" id="break_cnc_id" value="">
            </div>
            <div class="modal-footer justify-content-center" style="gap:15px;">
                <button class="btn btn-secondary btn-lg" data-dismiss="modal">
                    <i class="fas fa-times mr-1"></i> Cancel
                </button>
                <button class="btn btn-warning btn-lg" id="submitScheduleBreak">
                    <i class="fas fa-play mr-1"></i> Start Break
                </button>
            </div>
        </div>
    </div>
</div>

<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header bg-primary text-white">
                <h5 class="modal-title"><i class="fas fa-info-circle mr-2"></i>Order Details - Table <span id="detailsTableId"></span></h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="row mb-2"><div class="col-6"><strong>Part Number:</strong></div><div class="col-6" id="detailsPartNumber"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Description:</strong></div><div class="col-6" id="detailsDescription"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Work Order:</strong></div><div class="col-6" id="detailsWorkOrder"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Start Date:</strong></div><div class="col-6" id="detailsStartDate"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>End Date:</strong></div><div class="col-6" id="detailsEndDate"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Quantity Required:</strong></div><div class="col-6" id="detailsQtyReq"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>OK Count:</strong></div><div class="col-6" id="detailsOkCount"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>NOK Count:</strong></div><div class="col-6" id="detailsNokCount"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Quarantine Count:</strong></div><div class="col-6" id="detailsQuarCount"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Target UPH:</strong></div><div class="col-6" id="detailsTargetUph"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Actual UPH:</strong></div><div class="col-6" id="detailsActualUph"></div></div>
                <div class="row mb-2"><div class="col-6"><strong>Status:</strong></div><div class="col-6" id="detailsStatus"></div></div>
                <div class="row mb-2">
                    <div class="col-6"><strong>Document:</strong></div>
                    <div class="col-6">
                        <a href="#" id="detailsPdfLink" target="_blank" style="display:none;">
                            <i class="fas fa-file-pdf text-danger mr-1"></i> View PDF
                        </a>
                        <span id="detailsNoPdf" style="display:none;">No PDF available</span>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script>
const logoutRedirectUrl = "<?= htmlspecialchars($logoutRedirectUrl, ENT_QUOTES) ?>";
console.log("JavaScript loaded - Multi-table version");
const frontEndURL = "<?= $frontEndURL; ?>";
const machine_id = <?= $machine_id ?>;
const cncMachineTableId = <?= (int)$cncMachineTableId ?>;
const tableOrdersByTable = <?php echo json_encode($tableOrdersJS); ?>;

console.log("frontEndURL:", frontEndURL);
console.log("machine_id:", machine_id);
console.log("cncMachineTableId:", cncMachineTableId);
console.log("tableOrdersByTable:", tableOrdersByTable);

let currentIndex = {};
for (let t in tableOrdersByTable) {
    currentIndex[t] = 0;
}

let currentTableId   = null;
let currentCncId     = null;
let currentCountType = null;
let selectedParts    = [];

function updateClock() {
    const now = new Date();
    const hours   = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    document.getElementById('clock').textContent = `${hours}:${minutes}:${seconds}`;
}
updateClock();
setInterval(updateClock, 1000);

$('#backBtn').on('click', function() {
    window.location.href = "index?page=dashboard_cnc&machine_id=" + machine_id;
});

// First-Off
$(document).on('click', '.firstOffBtn', function() {
    currentTableId = $(this).data('table');
    currentCncId   = $(this).data('cnc-id');
    $('#firstOffModal').modal('show');
});

$('#submitFirstOff').click(function() {
    let qcClockNo = $("#qc_clock_no").val().trim();
    let qcComment = $("#qc_comment").val().trim();
    if (!qcClockNo) { alert("Please enter QC clock number"); return; }

    let workOrderId, partId;
    if (cncMachineTableId) {
        workOrderId = <?= isset($workOrderId) ? $workOrderId : 0 ?>;
        partId      = <?= isset($partId) ? $partId : 0 ?>;
    } else {
        const orders = tableOrdersByTable[currentTableId];
        if (!orders || orders.length === 0) { alert("No order found for this table"); return; }
        const currentOrder = orders[currentIndex[currentTableId] || 0];
        workOrderId = currentOrder.work_order_id;
        partId      = currentOrder.part_id;
    }

    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=first_off_signoff_cnc",
        method: "POST",
        data: { work_order_id: workOrderId, part_id: partId, cnc_machine_table_id: currentCncId, table_id: currentTableId, machine_id: machine_id, qc_clock_no: qcClockNo, qc_comment: qcComment },
        dataType: "json",
        success: function(response) {
            if (response.success) { $("#firstOffModal").modal("hide"); alert("✅ First-Off Approved Successfully"); location.reload(); }
            else { alert("❌ " + response.message); }
        },
        error: function(xhr, status, error) { alert("AJAX Error: " + error); }
    });
});

// Changeover
$(document).on('click', '.changeoverBtn', function() {
    currentTableId = $(this).data('table');
    $('#changeoverTableId').text(currentTableId);
    $('#changeoverModal').modal('show');
});

$('#submitChangeover').click(function() {
    let clockNo = $("#changeover_clock_no").val().trim();
    if (!clockNo) { alert("Please enter employee clock number"); return; }
    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=start_changeover_cnc",
        method: "POST",
        data: { machine_id: machine_id, table_id: currentTableId, clock_no: clockNo },
        dataType: "json",
        success: function(response) {
            if (response.success) { $("#changeoverModal").modal("hide"); alert("✅ Changeover started for Table " + currentTableId); location.reload(); }
            else { alert("❌ " + response.message); }
        },
        error: function(xhr, status, error) { alert("AJAX Error: " + error); }
    });
});

// Increment buttons
$(document).on('click', ".increment-btn", function() {
    const type    = $(this).data("type");
    const tableId = $(this).data("table");
    const cncId   = $(this).data("cnc-id");
    const flashMap = { ok: 'do-flash-ok', nok: 'do-flash-nok', quarantine: 'do-flash-quarantine' };
    const $btn = $(this);
    $btn.removeClass('do-flash-ok do-flash-nok do-flash-quarantine');
    void $btn[0].offsetWidth;
    $btn.addClass(flashMap[type]);

    if (!tableId || !cncId) return;

    currentTableId   = tableId;
    currentCncId     = cncId;
    currentCountType = type;

    let workOrderId, partId, setId;
    if (cncMachineTableId) {
        workOrderId = <?= isset($workOrderId) ? $workOrderId : 0 ?>;
        partId      = <?= isset($partId) ? $partId : 0 ?>;
        setId       = <?= isset($setId) ? $setId : 0 ?>;
    } else {
        const orders = tableOrdersByTable[tableId];
        if (!orders || orders.length === 0) return;
        const currentOrder = orders[currentIndex[tableId] || 0];
        workOrderId = currentOrder.work_order_id;
        partId      = currentOrder.part_id;
        setId       = currentOrder.set_id || 0;
    }

    if (type === "ok") {
        $.ajax({
            url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_count_cnc",
            method: "POST",
            data: { work_order_id: workOrderId, part_id: partId, table_id: tableId, cnc_machine_table_id: cncId, type: type, setId: setId, quantity: 1 },
            dataType: "json",
            success: function(response) { if (response.success) { location.reload(); } else { alert("Error: " + response.message); } },
            error: function(xhr, status, error) { alert("AJAX Error: " + error); }
        });
    } else {
        populatePartSelection(tableId);
        $("#partSelectionModal").modal("show");
    }
});

// Decrement buttons
$(document).on('click', ".decrement-btn", function() {
    const type    = $(this).data("type");
    const tableId = $(this).data("table");
    const cncId   = $(this).data("cnc-id");
    if (!tableId || !cncId) return;

    let currentCount = 0;
    let workOrderId, partId, setId;
    if (cncMachineTableId) {
        currentCount = parseInt($(`#${type}_count`).val() || 0);
        workOrderId  = <?= isset($workOrderId) ? $workOrderId : 0 ?>;
        partId       = <?= isset($partId) ? $partId : 0 ?>;
        setId        = <?= isset($setId) ? $setId : 0 ?>;
    } else {
        const orders = tableOrdersByTable[tableId];
        if (!orders || orders.length === 0) return;
        const currentOrder = orders[currentIndex[tableId] || 0];
        workOrderId  = currentOrder.work_order_id;
        partId       = currentOrder.part_id;
        setId        = currentOrder.set_id || 0;
        currentCount = parseInt($(`#table-${tableId} .${type}-count`).val() || 0);
    }

    if (currentCount <= 0) { alert("⚠ Count is already 0. Nothing to undo."); return; }

    if (confirm("Are you sure you want to undo the last " + type.toUpperCase() + " entry?")) {
        $.ajax({
            url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_count_cnc",
            method: "POST",
            data: { work_order_id: workOrderId, part_id: partId, table_id: tableId, cnc_machine_table_id: cncId, type: type, setId: setId, quantity: -1 },
            dataType: "json",
            success: function(response) { if (response.success) { location.reload(); } else { alert("❌ Error: " + response.message); } },
            error: function(xhr, status, error) { alert("AJAX Error: " + error); }
        });
    }
});

let selectedNokPartIds   = '';
let unselectedNokPartIds = '';

function buildExpandedParts(partNumbers) {
    let expanded = [];
    partNumbers.forEach(function(part) {
        let ratio = parseInt(part.ratio) || 1;
        for (let i = 0; i < ratio; i++) {
            expanded.push({ id: part.id, part_number: part.part_number, unit_index: i + 1, uid: part.id + '_' + i });
        }
    });
    return expanded;
}

function populatePartSelection(tableId) {
    let partNumbers = [];
    if (cncMachineTableId) {
        partNumbers = <?php echo json_encode(isset($partNumbers) ? $partNumbers : []); ?>;
    } else {
        const orders = tableOrdersByTable[tableId];
        if (!orders || orders.length === 0) return false;
        const currentOrder = orders[currentIndex[tableId] || 0];
        partNumbers = currentOrder.part_numbers || [];
    }

    const partSelection = document.getElementById("partSelection");
    partSelection.innerHTML = '';
    let expanded = buildExpandedParts(partNumbers);

    if (expanded.length <= 1) {
        if (cncMachineTableId) {
            selectedNokPartIds   = expanded.length ? String(expanded[0].id) : String(<?= isset($partId) ? $partId : 0 ?>);
            unselectedNokPartIds = '';
        } else {
            const orders       = tableOrdersByTable[tableId];
            const currentOrder = orders[currentIndex[tableId] || 0];
            selectedNokPartIds   = String(currentOrder.part_id);
            unselectedNokPartIds = '';
        }
        $("#reasonModal").modal("show");
        return false;
    }

    expanded.forEach(function(item) {
        const label = expanded.filter(function(e) { return e.id === item.id; }).length > 1
            ? item.part_number + ' — unit ' + item.unit_index
            : item.part_number;
        const partDiv = document.createElement('div');
        partDiv.className = 'part-checkbox';
        partDiv.innerHTML = `<div class="form-check"><input class="form-check-input part-check" type="checkbox" value="${item.id}" data-uid="${item.uid}" id="part_${item.uid}" checked><label class="form-check-label" for="part_${item.uid}">${label}</label></div>`;
        partDiv.addEventListener('click', function(e) {
            if (e.target.tagName !== 'INPUT') {
                const cb = this.querySelector('input[type="checkbox"]');
                cb.checked = !cb.checked;
            }
        });
        partSelection.appendChild(partDiv);
    });
    return true;
}

$("#proceedToReason").click(function() {
    let checked = [], unchecked = [];
    document.querySelectorAll('.part-check').forEach(function(cb) {
        (cb.checked ? checked : unchecked).push(cb.value);
    });
    if (checked.length === 0) { alert("⚠ Please select at least one part unit."); return; }
    selectedNokPartIds   = checked.join(',');
    unselectedNokPartIds = unchecked.join(',');
    $("#partSelectionModal").modal("hide");
    $("#reasonModal").modal("show");
});

$("#backToParts").click(function() {
    $("#reasonModal").modal("hide");
    $("#partSelectionModal").modal("show");
});

$("#submitNok").click(function() {
    let reason = $(".reason-radio:checked").val();
    if (!reason) { alert("⚠ Please select a reason."); return; }

    let workOrderId, partId, setId;
    if (cncMachineTableId) {
        workOrderId = <?= isset($workOrderId) ? $workOrderId : 0 ?>;
        partId      = <?= isset($partId) ? $partId : 0 ?>;
        setId       = <?= isset($setId) ? $setId : 0 ?>;
    } else {
        const orders = tableOrdersByTable[currentTableId];
        if (!orders || orders.length === 0) { alert("No order found for this table"); return; }
        const currentOrder = orders[currentIndex[currentTableId] || 0];
        workOrderId = currentOrder.work_order_id;
        partId      = currentOrder.part_id;
        setId       = currentOrder.set_id || 0;
    }

    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_count_cnc",
        method: "POST",
        data: { work_order_id: workOrderId, part_id: partId, table_id: currentTableId, cnc_machine_table_id: currentCncId, reason_id: reason, part_ids: selectedNokPartIds, nok_q_scrap_part_ids_part_ids: selectedNokPartIds, nok_q_ok_part_ids: unselectedNokPartIds, type: currentCountType, setId: setId, quantity: 1 },
        dataType: "json",
        success: function(response) {
            if (response.success) {
                $("#reasonModal").modal("hide");
                location.reload();
                $(".reason-radio").prop("checked", false);
                $(".part-check").prop("checked", false);
                selectedNokPartIds = ''; unselectedNokPartIds = '';
            } else { alert("Error: " + response.message); }
        },
        error: function(xhr, status, error) { alert("AJAX Error: " + error); }
    });
});

$(document).on('click', ".action-btn", function() {
    let action = $(this).data("action");
    if (action === "pdf") {
        <?php if (!empty($document_upload) && $ext === 'pdf'): ?>
            window.location.href = "<?= $document_dir . $document_upload ?>";
        <?php else: ?>
            alert("No PDF file available!");
        <?php endif; ?>
        return;
    }
    if (action === "break") {
        $('#break_table_id').val(<?= isset($table_id) ? $table_id : 0 ?>);
        $('#break_cnc_id').val(<?= isset($cncMachineTableId) ? $cncMachineTableId : 0 ?>);
        $('#scheduleBreakModal').modal('show');
        return;
    }

    let workOrderId, partId;
    if (cncMachineTableId) {
        workOrderId = <?= isset($workOrderId) ? $workOrderId : 0 ?>;
        partId      = <?= isset($partId) ? $partId : 0 ?>;
    } else {
        const tableId = <?= isset($table_id) ? $table_id : 0 ?>;
        const orders  = tableOrdersByTable[tableId];
        if (!orders || orders.length === 0) return;
        const currentOrder = orders[0];
        workOrderId = currentOrder.work_order_id;
        partId      = currentOrder.part_id;
    }

    if (action === "finish") {
        const okCount    = parseInt($("#ok_count").val());
        const requiredQty = <?= isset($detail['quantity']) ? $detail['quantity'] : 0 ?>;
        if (okCount < requiredQty) {
            if (!confirm(`OK Count: ${okCount}\nRequired: ${requiredQty}\n\nAre you sure you want to finish this order?`)) return;
        }
        if (!confirm("Are you sure you want to finish this work order?")) return;
    } else if (action !== 'pdf' && !confirm("Are you sure you want to set this work order to " + action + "?")) {
        return;
    }

    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_action_cnc",
        method: "POST",
        data: { work_order_id: workOrderId, part_id: partId, table_id: <?= isset($table_id) ? $table_id : 0 ?>, cnc_machine_table_id: <?= isset($cncMachineTableId) ? $cncMachineTableId : 0 ?>, machine_id: machine_id, action_type: action },
        dataType: "json",
        success: function(response) { if (response.success) { location.reload(); } else { alert("❌ Error: " + response.message); } },
        error: function(xhr, status, error) { alert("AJAX Error: " + error); }
    });
});

// Machine action (multi-table)
$(document).on('click', ".machine-action", function() {
    const tableId     = $(this).data("table");
    const currentAction = $(this).data("action");
    const cncId       = $(this).data("cnc-id");
    const newAction   = currentAction === 'start' ? 'pause' : 'start';
    const orders      = tableOrdersByTable[tableId];
    if (!orders || orders.length === 0) return;
    const currentOrder = orders[currentIndex[tableId] || 0];

    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_action_cnc",
        method: "POST",
        data: { machine_id: machine_id, work_order_id: currentOrder.work_order_id, table_id: tableId, cnc_machine_table_id: cncId, part_id: currentOrder.part_id, action_type: newAction },
        dataType: "json",
        success: function(response) { if (response.success) { location.reload(); } else { alert("Error: " + response.message); } },
        error: function(xhr, status, error) { alert("AJAX Error: " + error); }
    });
});

$(document).on('click', ".finish-btn", function() {
    const tableId = $(this).data("table");
    const cncId   = $(this).data("cnc-id");
    const orders  = tableOrdersByTable[tableId];
    if (!orders || orders.length === 0) return;
    const currentOrder = orders[currentIndex[tableId] || 0];

    if (!confirm("Are you sure you want to mark this order as finished?")) return;

    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_action_cnc",
        method: "POST",
        data: {
            work_order_id:        currentOrder.work_order_id,
            part_id:              currentOrder.part_id,
            table_id:             tableId,
            cnc_machine_table_id: cncId,
            machine_id:           machine_id,
            action_type:          "finish"
        },
        dataType: "json",
        success: function(response) {
            if (response.success) {
                disableTableAfterFinish(tableId); // ← disable immediately, no reload needed
            } else {
                alert("Error: " + response.message);
            }
        },
        error: function(xhr, status, error) { alert("AJAX Error: " + error); }
    });
});

function disableTableAfterFinish(tableId) {
    const $table = $('#table-' + tableId);

    // Disable count and action buttons
    $table.find('.increment-btn, .decrement-btn, .machine-action, .finish-btn')
          .prop('disabled', true)
          .css('opacity', '0.4');

    // Hide First-Off button if present
    $table.find('.firstOffBtn').hide();

    // Show finished banner if not already there
    if ($table.find('.finished-banner').length === 0) {
        $table.find('.table-body').prepend(
            '<div class="finished-banner alert alert-success text-center py-2 mb-3">' +
            '<i class="fas fa-check-circle"></i> ' +
            'Order Finished — Complete changeover to remove from dashboard' +
            '</div>'
        );
    }

    // Keep Changeover and Details enabled
    $table.find('.changeoverBtn, .details-btn').prop('disabled', false).css('opacity', '1');
}

// Details button
$(document).on('click', ".details-btn", function() {
    const orderData = $(this).data('order');
    $("#detailsTableId").text($(this).data('table'));
    $("#detailsPartNumber").text(orderData.product_name || 'N/A');
    $("#detailsDescription").text(orderData.product_name || 'N/A');
    $("#detailsWorkOrder").text(orderData.work_order_id || 'N/A');
    $("#detailsStartDate").text(orderData.start_date ? new Date(orderData.start_date).toLocaleString() : 'Not set');
    $("#detailsEndDate").text(orderData.end_date ? new Date(orderData.end_date).toLocaleString() : 'Not set');
    $("#detailsQtyReq").text(orderData.qty_req || 0);
    $("#detailsOkCount").text(orderData.ok || 0);
    $("#detailsNokCount").text(orderData.nok || 0);
    $("#detailsQuarCount").text(orderData.quar || 0);
    $("#detailsTargetUph").text(orderData.original_uph || 0);
    $("#detailsActualUph").text(orderData.actual_uph || 0);
    $("#detailsStatus").text(orderData.machine_status || 'unknown');
    if (orderData.document_upload && orderData.document_upload !== "") {
        const ext = orderData.document_upload.split('.').pop().toLowerCase();
        if (ext === 'pdf') { $("#detailsPdfLink").attr('href', orderData.document_dir + orderData.document_upload).show(); $("#detailsNoPdf").hide(); }
        else { $("#detailsPdfLink").hide(); $("#detailsNoPdf").show(); }
    } else { $("#detailsPdfLink").hide(); $("#detailsNoPdf").show(); }
    $("#detailsModal").modal("show");
});

// Breakdown
$("#breakdownBtn, #breakdownAllBtn").click(function() {
    let allCncIds = [];
    for (let tableId in tableOrdersByTable) {
        const orders = tableOrdersByTable[tableId];
        if (orders && orders.length > 0) allCncIds.push(orders[currentIndex[tableId] || 0].id);
    }
    $('#breakdown_table_id').val(0);
    $('#breakdown_cnc_id').val(allCncIds.join(','));
    $("#breakdownModal").modal("show");
});

$("#submitBreakdown").click(function() {
    let duration = parseFloat($("#breakdown_duration").val());
    let reason   = $("#cnc_machine_breakdown_reason").val();
    let cncIds   = $('#breakdown_cnc_id').val();
    if (!duration || duration < 0.5 || duration > 24) { alert("⚠ Please enter a valid breakdown duration between 0.5 and 24 hours."); return; }
    if (!reason)  { alert("⚠ Please select a breakdown reason."); return; }
    if (!cncIds)  { alert("No active tables found."); return; }

    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_breakdown_cnc",
        method: "POST",
        data: { machine_id: machine_id, cnc_machine_table_id: cncIds, action_type: "breakdown", breakdown_reason: reason, breakdown_duration: duration },
        success: function(response) {
            if (typeof response === 'string') { try { response = JSON.parse(response); } catch(e) { alert("Server returned invalid JSON."); return; } }
            if (response.success) { $("#breakdownModal").modal("hide"); alert("✅ " + (response.message || "Breakdown logged successfully!")); location.reload(); }
            else { alert("❌ Error: " + response.message); }
        },
        error: function(xhr, status, error) { alert("Server response: " + xhr.responseText.substring(0, 500)); }
    });
});

// Schedule Break
$("#scheduleBreakAll").click(function() {
    $('#break_table_id').val(''); $('#break_cnc_id').val('');
    $('#breakType').val(''); $('#breakDuration').val('').prop('readonly', true); $('#breakRemarks').val('');
    $('#scheduleBreakModal').modal('show');
});

$('#scheduleBreakModal').on('hidden.bs.modal', function() {
    $('#breakType').val(''); $('#breakDuration').val('').prop('readonly', true); $('#breakRemarks').val('');
});

document.getElementById('breakType').addEventListener('change', function() {
    const type          = this.value;
    const durationInput = document.getElementById('breakDuration');
    if (type === '20' || type === '30') { durationInput.value = type; durationInput.readOnly = true; }
    else if (type === 'custom') { durationInput.value = ''; durationInput.readOnly = false; durationInput.focus(); }
    else { durationInput.value = ''; durationInput.readOnly = true; }
});

document.getElementById('submitScheduleBreak').addEventListener('click', function() {
    const type     = document.getElementById('breakType').value;
    const duration = document.getElementById('breakDuration').value;
    const remarks  = document.getElementById('breakRemarks').value.trim();
    const tableId  = document.getElementById('break_table_id').value;
    const cncId    = document.getElementById('break_cnc_id').value;
    if (!type) { alert('Please select break type'); return; }
    if (type === 'custom' && (!duration || parseFloat(duration) <= 0)) { alert('Enter valid duration'); return; }
    const durationHours = parseFloat(duration);
    const breakReason   = type === '20' ? 'EARLY BREAK' : type === '30' ? 'LUNCH BREAK' : (remarks || 'OTHER');
    if (!tableId) { scheduleBreakForAllTables(durationHours, breakReason); }
    else { scheduleBreakForSingleTable(tableId, cncId, durationHours, breakReason); }
});

function scheduleBreakForSingleTable(tableId, cncId, durationHours, reason) {
    const orders = tableOrdersByTable[tableId];
    if (!orders || orders.length === 0) { alert('No order found for this table'); return; }
    const currentOrder = orders[currentIndex[tableId] || 0];
    $.ajax({
        url: frontEndURL + '/machine_tab/index?page=ajax_actions_cnc&action=log_action_cnc',
        method: 'POST',
        data: { work_order_id: currentOrder.work_order_id, part_id: currentOrder.part_id, table_id: tableId, cnc_machine_table_id: cncId || currentOrder.id, machine_id: machine_id, action_type: 'break', break_duration: durationHours, break_reason: reason },
        dataType: 'json',
        success: function(response) {
            if (response.success) { $('#scheduleBreakModal').modal('hide'); alert('Break scheduled successfully!'); location.reload(); }
            else { alert('Error: ' + (response.message || 'Failed to schedule break')); }
        },
        error: function(xhr, status, error) { alert('AJAX Error: ' + error); }
    });
}

function scheduleBreakForAllTables(durationHours, reason) {
    let allTables = [], runningWOs = [];
    for (let tableId in tableOrdersByTable) {
        const orders = tableOrdersByTable[tableId];
        if (!orders || !orders.length) continue;
        const currentOrder = orders[currentIndex[tableId] || 0];
        allTables.push({ table_id: tableId, work_order_id: currentOrder.work_order_id, part_id: currentOrder.part_id, cnc_machine_table_id: currentOrder.id, machine_id: machine_id });
        if (currentOrder.machine_status === 'start') {
            runningWOs.push({ tableId: tableId, workOrderId: currentOrder.work_order_id, partId: currentOrder.part_id, cncMachineTableId: currentOrder.id, machineId: machine_id });
        }
    }
    if (!allTables.length) { alert('⚠ No active orders.'); return; }

    function doScheduleBreak() {
        $.ajax({
            url: frontEndURL + '/machine_tab/index?page=ajax_actions_cnc&action=schedule_break_all_tables_cnc',
            method: 'POST',
            data: { tables: JSON.stringify(allTables), duration: durationHours, reason: reason, machine_id: machine_id },
            dataType: 'json',
            success: function(response) {
                if (response.success) { $('#scheduleBreakModal').modal('hide'); alert('Break scheduled for all tables!'); location.reload(); }
                else { alert('Error: ' + (response.message || 'Failed to schedule break')); }
            },
            error: function(xhr, status, error) { alert('AJAX Error: ' + error); }
        });
    }

    if (runningWOs.length === 0) { doScheduleBreak(); return; }

    $.ajax({
        url: frontEndURL + '/machine_tab/index?page=ajax_actions_cnc&action=log_bulk_action_cnc',
        method: 'POST',
        data: { action_type: 'pause', work_orders: JSON.stringify(runningWOs) },
        dataType: 'json',
        success: function(response) {
            if (!response.success) { alert('❌ Could not pause tables before break: ' + (response.message || 'Unknown error')); return; }
            doScheduleBreak();
        },
        error: function(xhr, status, error) { alert('AJAX Error: ' + error); }
    });
}

// Toggle all
$("#toggleAllBtn").click(function() {
    let anyRunning = false;
    for (let tableId in tableOrdersByTable) {
        const orders = tableOrdersByTable[tableId];
        if (orders && orders.length > 0) {
            const status = orders[currentIndex[tableId] || 0].machine_status;
            if (status !== 'pause' && status !== 'finish') { anyRunning = true; break; }
        }
    }
    const actionType = anyRunning ? "pause" : "start";
    if (confirm(`Are you sure you want to ${actionType} all tables?`)) {
        let allWorkOrders = [];
        for (let tableId in tableOrdersByTable) {
            const orders = tableOrdersByTable[tableId];
            if (orders && orders.length > 0) {
                const currentOrder = orders[currentIndex[tableId] || 0];
                allWorkOrders.push({ tableId: tableId, workOrderId: currentOrder.work_order_id, partId: currentOrder.part_id, cncMachineTableId: currentOrder.id, machineId: machine_id });
            }
        }
        $.ajax({
            url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=log_bulk_action_cnc",
            method: "POST",
            data: { action_type: actionType, work_orders: JSON.stringify(allWorkOrders) },
            dataType: "json",
            success: function(response) {
                if (response.success) { alert(`All tables have been ${actionType}ed successfully!`); location.reload(); }
                else { alert("Error: " + response.message); }
            },
            error: function(xhr, status, error) { alert("AJAX Error: " + error); }
        });
    }
});

$('.fullscreen-toggle').click(function() {
    if (!document.fullscreenElement) {
        document.documentElement.requestFullscreen().catch(err => { console.error('Error:', err); });
        $(this).find('i').removeClass('fa-expand-arrows-alt').addClass('fa-compress-arrows-alt');
    } else {
        if (document.exitFullscreen) document.exitFullscreen();
        $(this).find('i').removeClass('fa-compress-arrows-alt').addClass('fa-expand-arrows-alt');
    }
});
$(document).on('fullscreenchange', function() {
    if (!document.fullscreenElement) $('.fullscreen-toggle i').removeClass('fa-compress-arrows-alt').addClass('fa-expand-arrows-alt');
});

$('#breakdownModal').on('hidden.bs.modal', function() { $('#breakdown_duration').val('1'); $('#breakdown_reason').val(''); });
$('#firstOffModal').on('hidden.bs.modal', function() { $('#qc_clock_no').val(''); $('#qc_comment').val(''); });

$(document).ready(function() {
    console.log("Document ready - Multi-table");
    for (let tableId in tableOrdersByTable) {
        if (tableOrdersByTable[tableId].length > 0) {
            console.log(`Table ${tableId} has ${tableOrdersByTable[tableId].length} orders`);
        }
    }
});
</script>

<script>
let changeoverInterval    = null;
let changeoverStartTime   = null;
let currentChangeoverTable = null;
let activeChangeoverData  = {};

function showChangeoverInTable(tableId, startTime) {
    const tableDiv = $(`#table-${tableId}`);
    if (tableDiv.find('.table-changeover-overlay').length > 0) return;

    const changeoverBtn = tableDiv.find('.changeoverBtn');
    changeoverBtn.css('animation', 'none').css('opacity', '0.6').prop('disabled', true);

    const overlayHtml = `
        <div class="table-changeover-overlay" id="changeover-overlay-${tableId}">
            <button class="table-changeover-stop-btn" onclick="stopTableChangeover(${tableId})">
                <i class="fas fa-stop"></i> Stop Changeover
            </button>
            <div class="table-changeover-content">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">
                    <h4 style="margin:0;"><i class="fas fa-exchange-alt"></i> CHANGEOVER IN PROGRESS</h4>
                    <span class="changeover-badge"><i class="fas fa-clock"></i> Active</span>
                </div>
                <div class="table-changeover-timer" id="changeover-timer-${tableId}">00:00:00</div>
                <div class="table-changeover-progress">
                    <div class="table-changeover-progress-bar" id="changeover-progress-${tableId}" style="width:0%"></div>
                </div>
                <div class="table-changeover-info" id="changeover-info-${tableId}"></div>
            </div>
        </div>`;

    tableDiv.css('position', 'relative').append(overlayHtml);
    changeoverStartTime = startTime ? new Date(startTime) : new Date();
    $(`#changeover-info-${tableId}`).html(`<i class="fas fa-user-clock"></i> Started at: ${changeoverStartTime.toLocaleTimeString()}`);
    startTableChangeoverTimer(tableId);
    disableTableButtons(tableId, true);
    activeChangeoverData[tableId] = { active: true, startTime: changeoverStartTime };
}

function startTableChangeoverTimer(tableId) {
    if (window[`changeoverInterval_${tableId}`]) clearInterval(window[`changeoverInterval_${tableId}`]);
    window[`changeoverInterval_${tableId}`] = setInterval(() => { updateTableChangeoverTimer(tableId); }, 1000);
    updateTableChangeoverTimer(tableId);
}

function updateTableChangeoverTimer(tableId) {
    const overlay = $(`#changeover-overlay-${tableId}`);
    if (overlay.length === 0) return;
    if (!activeChangeoverData[tableId] || !activeChangeoverData[tableId].startTime) return;
    const elapsed = Math.floor((new Date() - activeChangeoverData[tableId].startTime) / 1000);
    const h = Math.floor(elapsed / 3600), m = Math.floor((elapsed % 3600) / 60), s = elapsed % 60;
    $(`#changeover-timer-${tableId}`).text(`${String(h).padStart(2,'0')}:${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}`);
    const progressPercent = Math.min((elapsed / 7200) * 100, 100);
    $(`#changeover-progress-${tableId}`).css('width', progressPercent + '%');
    const progressBar = $(`#changeover-progress-${tableId}`);
    if (elapsed > 7200) progressBar.css('background', '#dc3545');
    else if (elapsed > 3600) progressBar.css('background', '#ffc107');
    else progressBar.css('background', '#28a745');
}

function stopTableChangeover(tableId) {
    if (!confirm('⚠️ Are you sure you want to STOP the changeover for Table ' + tableId + '?\n\nThis will resume normal production.')) return;
    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=end_changeover_cnc",
        method: "POST",
        data: { machine_id: machine_id, table_id: tableId },
        dataType: "json",
        success: function(response) {
            if (response.success) { removeChangeoverFromTable(tableId); alert("✅ Changeover stopped successfully for Table " + tableId); location.reload(); }
            else { alert("❌ Error stopping changeover: " + (response.message || "Unknown error")); }
        },
        error: function(xhr, status, error) { alert("AJAX Error: " + error); }
    });
}

function removeChangeoverFromTable(tableId) {
    const overlay = $(`#changeover-overlay-${tableId}`);
    if (overlay.length) overlay.remove();
    const tableDiv      = $(`#table-${tableId}`);
    const changeoverBtn = tableDiv.find('.changeoverBtn');
    changeoverBtn.css('animation', 'pulse-green 2s infinite').css('opacity', '1').prop('disabled', false);
    if (window[`changeoverInterval_${tableId}`]) { clearInterval(window[`changeoverInterval_${tableId}`]); delete window[`changeoverInterval_${tableId}`]; }
    disableTableButtons(tableId, false);
    delete activeChangeoverData[tableId];
}

function disableTableButtons(tableId, disabled) {
    const tableDiv = $(`#table-${tableId}`);
    tableDiv.find('.increment-btn').prop('disabled', disabled);
    tableDiv.find('.decrement-btn').prop('disabled', disabled);
    tableDiv.find('.machine-action').prop('disabled', disabled);
    tableDiv.find('.finish-btn').prop('disabled', disabled);
    tableDiv.find('.firstOffBtn').prop('disabled', disabled);
    tableDiv.css('opacity', disabled ? '0.7' : '1');
}

$(document).off('click', '.changeoverBtn').on('click', '.changeoverBtn', function() {
    if ($(this).prop('disabled')) return;
    const tableId = $(this).data('table');
    if (activeChangeoverData[tableId] && activeChangeoverData[tableId].active) { alert("⚠ Changeover is already in progress for this table!"); return; }

    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=check_active_changeover_cnc",
        method: "POST",
        data: { machine_id: machine_id, table_id: tableId },
        dataType: "json",
        success: function(response) {
            if (response.has_active_changeover) {
                if (response.changeover_data) showChangeoverInTable(tableId, response.changeover_data.start_time);
                alert("⚠ Changeover is already in progress for this table!");
                return;
            }
            currentChangeoverTable = tableId;
            const clockNo = prompt("🔧 ENTER EMPLOYEE CLOCK NUMBER\n\nPlease enter your clock number to start changeover:");
            if (clockNo && clockNo.trim()) startChangeover(tableId, clockNo.trim());
        },
        error: function(xhr, status, error) {
            const clockNo = prompt("🔧 ENTER EMPLOYEE CLOCK NUMBER\n\nPlease enter your clock number to start changeover:");
            if (clockNo && clockNo.trim()) startChangeover(tableId, clockNo.trim());
        }
    });
});

function startChangeover(tableId, clockNo) {
    const btn          = $(`#table-${tableId} .changeoverBtn`);
    const cncId        = btn.data('cnc-id');
    const originalText = btn.html();
    btn.html('<i class="fas fa-spinner fa-spin"></i> Starting...').prop('disabled', true);
    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=start_changeover_cnc",
        method: "POST",
        data: { machine_id: machine_id, table_id: tableId, cnc_machine_table_id: cncId, clock_no: clockNo },
        dataType: "json",
        success: function(response) {
            if (response.success) { showChangeoverInTable(tableId, null); alert("✅ Changeover started for Table " + tableId); }
            else { btn.html(originalText).prop('disabled', false); alert("❌ " + response.message); }
        },
        error: function(xhr, status, error) { btn.html(originalText).prop('disabled', false); alert("AJAX Error: " + error); }
    });
}

function checkActiveChangeovers() {
    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=check_active_changeover_cnc",
        method: "POST",
        data: { machine_id: machine_id, table_id: null },
        dataType: "json",
        success: function(response) {
            if (response.has_active_changeover && response.changeover_data) {
                if (Array.isArray(response.changeover_data)) {
                    response.changeover_data.forEach(function(co) {
                        if ($(`#changeover-overlay-${co.table_id}`).length === 0) showChangeoverInTable(co.table_id, co.start_time);
                    });
                } else {
                    const tableId = response.changeover_data.table_id;
                    if ($(`#changeover-overlay-${tableId}`).length === 0) showChangeoverInTable(tableId, response.changeover_data.start_time);
                }
            }
        },
        error: function(xhr, status, error) { console.error("Error checking active changeovers:", error); }
    });
}

$(document).ready(function() {
    console.log("Document ready - Enhanced Changeover");
    checkActiveChangeovers();

    for (let tableId in tableOrdersByTable) {
        const orders = tableOrdersByTable[tableId];
        if (orders && orders.length > 0 && orders[0].is_dual_table == 1) {
            const oppositeId = tableId == 1 ? 2 : 1;
            const oppositeHasActiveOrder = tableOrdersByTable[oppositeId] && tableOrdersByTable[oppositeId].length > 0;
            if (!oppositeHasActiveOrder) {
                const $opposite = $('#table-' + oppositeId);
                if ($opposite.length && !$opposite.find('.dual-table-badge').length) {
                    $opposite.find('.increment-btn, .decrement-btn, .machine-action, .finish-btn, .changeoverBtn, .firstOffBtn')
                             .prop('disabled', true).css('opacity', '0.4');
                }
            }
        }
    }
});
</script>

<script>
$(document).on("click", "#breakdownOverBtn", function() {
    let machineId = $(this).data("machine");
    $.ajax({
        url: frontEndURL + "/machine_tab/index?page=ajax_actions_cnc&action=end_breakdown_cnc",
        type: "POST",
        data: { machine_id: machineId },
        success: function(res) {
            if (res.success) { location.reload(); }
            else { alert("Failed to end breakdown"); }
        }
    });
});
</script>

<script>
(function () {
    const WINDOW_MINUTES   = 60;
    const POLL_INTERVAL_MS = 30000;
    const SKIP_STATUSES    = ['finish', 'pause', 'break', 'breakdown'];

    function renderUphForTable(tableId, liveUph, plannedUph) {
        const isGreen = plannedUph > 0 && liveUph >= plannedUph;
        const colour  = isGreen ? '#28a745' : '#dc3545';
        const numEl   = document.getElementById('actual-uph-t' + tableId);
        if (numEl) { numEl.textContent = liveUph; numEl.style.color = colour; }
        const badge = document.getElementById('uph-badge-t' + tableId);
        if (badge) {
            badge.className = 'uph-live-badge ' + (isGreen ? 'green' : 'red');
            badge.querySelector('.uph-badge-label').textContent = isGreen ? 'on target' : 'below target';
        }
        const tableDiv = document.getElementById('table-' + tableId);
        if (tableDiv) {
            tableDiv.style.borderColor = isGreen ? 'green' : 'red';
            tableDiv.classList.toggle('border-success', isGreen);
            tableDiv.classList.toggle('border-danger', !isGreen);
        }
    }

    function fetchLiveUphForTable(tableId) {
        const orders = tableOrdersByTable[tableId];
        if (!orders || orders.length === 0) return;
        const order = orders[0];
        if (SKIP_STATUSES.includes(order.machine_status)) {
            renderUphForTable(tableId, parseFloat(order.actual_uph) || 0, parseFloat(order.original_uph) || 0);
            return;
        }
        fetch(frontEndURL + '/machine_tab/index?page=ajax_actions_cnc&action=get_live_uph_cnc', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({ work_order_id: order.work_order_id, part_id: order.part_id, cnc_machine_table_id: order.id, table_id: tableId, window_minutes: WINDOW_MINUTES })
        })
        .then(r => r.json())
        .then(data => { if (!data.success) return; renderUphForTable(tableId, data.live_uph, data.planned_uph); })
        .catch(() => {});
    }

    function pollAllTables() {
        for (const tableId in tableOrdersByTable) fetchLiveUphForTable(tableId);
    }
    pollAllTables();
    setInterval(pollAllTables, POLL_INTERVAL_MS);
})();
</script>

<script>
function updateWallClock() {
    const now = new Date();
    const el  = document.getElementById('wallClock');
    if (el) el.textContent = String(now.getHours()).padStart(2,'0') + ':' + String(now.getMinutes()).padStart(2,'0') + ':' + String(now.getSeconds()).padStart(2,'0');
}
updateWallClock();
setInterval(updateWallClock, 1000);

let productionSeconds   = <?= $storedSeconds ?>;
const machineStatusesClock = <?= json_encode($machineStatuses) ?>;
let lastReportedRunning = null;

function isMachineRunning() {
    return Object.values(machineStatusesClock).some(s => s === 'start');
}

function renderProductionClock() {
    const running = isMachineRunning();
    const clockEl = document.getElementById('productionClock');
    const badgeEl = document.getElementById('clockStatusBadge');
    if (running) {
        productionSeconds++;
        if (clockEl) clockEl.style.color = '#28a745';
        if (badgeEl) { badgeEl.textContent = 'RUNNING'; badgeEl.style.background = '#28a745'; }
    } else {
        if (clockEl) clockEl.style.color = '#dc3545';
        if (badgeEl) { badgeEl.textContent = 'PAUSED'; badgeEl.style.background = '#dc3545'; }
    }
    const h = Math.floor(productionSeconds / 3600), m = Math.floor((productionSeconds % 3600) / 60), s = productionSeconds % 60;
    if (clockEl) clockEl.textContent = String(h).padStart(2,'0') + ':' + String(m).padStart(2,'0') + ':' + String(s).padStart(2,'0');
    if (lastReportedRunning !== running) { lastReportedRunning = running; persistClock(running); }
}
setInterval(renderProductionClock, 1000);
setInterval(function() { persistClock(isMachineRunning()); }, 30000);
window.addEventListener('beforeunload', function() { persistClock(isMachineRunning()); });

function persistClock(running) {
    fetch(frontEndURL + '/machine_tab/index?page=ajax_actions_cnc&action=update_clock_cnc', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({ machine_id: machine_id, production_seconds: productionSeconds, is_running: running ? 1 : 0, last_start_time: running ? new Date().toISOString() : '' }),
        keepalive: true
    }).catch(function() {});
}
</script>

<script>
document.getElementById('logoutBtn').addEventListener('click', function () {
    if (!confirm('Are you sure you want to log out?\n\nAll active tables will be paused automatically.')) return;

    const machineCode      = this.getAttribute('data-code');
    const baseUrl          = window.location.origin + '/thermotec/machine_tab/index.php';
    const logoutRedirectUrl = baseUrl + '?l=2&code=' + encodeURIComponent(machineCode);

    const btn = this;
    btn.disabled = true;
    btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Logging out...';

    let allWorkOrders = [];
    for (let tableId in tableOrdersByTable) {
        const orders = tableOrdersByTable[tableId];
        if (!orders || orders.length === 0) continue;
        const order = orders[currentIndex[tableId] || 0];
        if (order.machine_status === 'start') {
            allWorkOrders.push({ tableId: tableId, workOrderId: order.work_order_id, partId: order.part_id, cncMachineTableId: order.id, machineId: machine_id });
        }
    }

    persistClock(false);

    function doRedirect() { window.location.href = logoutRedirectUrl; }

    function destroySessionAndRedirect() {
        fetch(frontEndURL + '/machine_tab/index?page=ajax_actions_cnc&action=logout_cnc', { method: 'POST', keepalive: true })
        .catch(() => {}).finally(() => doRedirect());
    }

    if (allWorkOrders.length === 0) { destroySessionAndRedirect(); return; }

    fetch(frontEndURL + '/machine_tab/index?page=ajax_actions_cnc&action=log_bulk_action_cnc', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({ action_type: 'pause', work_orders: JSON.stringify(allWorkOrders) }),
        keepalive: true
    })
    .then(res => res.json())
    .then(response => { if (!response.success) console.warn('Bulk pause warning:', response.message); destroySessionAndRedirect(); })
    .catch(err => { console.error('Pause on logout failed:', err); destroySessionAndRedirect(); });
});

setInterval(function () { $.get('keep_alive.php'); }, 300000);
</script>

<script>
function checkQtyReqCrossed() {
    for (let tableId in tableOrdersByTable) {
        const orders = tableOrdersByTable[tableId];
        if (!orders || orders.length === 0) continue;

        const order   = orders[0];
        const okQty   = parseFloat(order.ok) || 0;
        const reqQty  = parseFloat(order.qty_req) || 0;

        if (reqQty <= 0) continue; // no valid required qty to compare against

        const $tableDiv  = $('#table-' + tableId);
        const $qtyGoodEl = $tableDiv.find('.qty_good');

        if (okQty >= reqQty) {
            // Visual highlight — turns the good-qty number red once crossed
            $qtyGoodEl.css({ color: '#dc3545', fontWeight: 'bold' });

            // One alert per table per crossing (guarded by sessionStorage so it
            // doesn't re-fire on every reload while the state stays the same)
            const alertKey = 'qtyReqAlerted_table_' + tableId + '_' + order.id;
            if (!sessionStorage.getItem(alertKey)) {
                sessionStorage.setItem(alertKey, '1');
                alert(
                    "⚠ Table " + tableId + ": Good quantity (" + okQty +
                    ") has reached/exceeded the required quantity (" + reqQty + ")."
                );
            }
        } else {
            $qtyGoodEl.css({ color: '', fontWeight: '' });
            // Clear the guard so a future crossing (e.g. after req qty changes) can re-alert
            sessionStorage.removeItem('qtyReqAlerted_table_' + tableId + '_' + order.id);
        }
    }
}

$(document).ready(function() {
    checkQtyReqCrossed();
});
</script>