<?php
/* ============================================================================
   REPLICA WOOD — AJAX ACTIONS (routed through machine_tab/index.php)
   Included by the shell via page=ajax_actions_replica_wood. The shell
   already did session_start() and included startup.php — do NOT repeat
   either here.
   ========================================================================= */

if (isset($_REQUEST['action'])) {
    while (ob_get_level()) { ob_end_clean(); }
    header('Content-Type: application/json');
    header('Cache-Control: no-cache, must-revalidate');
}

if (function_exists('mysqli_report')) {
    mysqli_report(MYSQLI_REPORT_OFF);
}
set_exception_handler(function ($e) {
    while (ob_get_level()) { ob_end_clean(); }
    header('Content-Type: application/json');
    echo json_encode(["success" => false, "message" => "Server error: " . $e->getMessage()]);
    exit;
});

// How many recent taps undo can reach back through.
define('RW_UNDO_STACK_LIMIT', 10);

function rw_update_inventory_stock($conn, $item_id, $qty_change) {
    $item_id    = intval($item_id);
    $qty_change = floatval($qty_change);

    $result = mysqli_query($conn, "SELECT quantity_in_stock FROM inventory WHERE item_id = $item_id");

    if ($result && mysqli_num_rows($result) > 0) {
        mysqli_query($conn, "UPDATE inventory 
                              SET quantity_in_stock = quantity_in_stock + ($qty_change) 
                              WHERE item_id = $item_id");
    } else {
        if ($qty_change < 0) return false;
        mysqli_query($conn, "INSERT INTO inventory (item_id, quantity_in_stock) VALUES ($item_id, $qty_change)");
    }
    return true;
}

function rw_reduce_bom_materials($conn, $main_product_id, $count_qty) {
    $main_product_id = intval($main_product_id);
    $bom_res = mysqli_query($conn, "SELECT sub_part_id, quantity_required, type 
                                     FROM bom WHERE main_product_id = $main_product_id");
    if (!$bom_res) return;

    while ($bom_row = mysqli_fetch_assoc($bom_res)) {
        $sub_part_id  = intval($bom_row['sub_part_id']);
        $qty_required = floatval($bom_row['quantity_required']);
        $deduct_qty   = -1 * $qty_required * $count_qty;

        rw_update_inventory_stock($conn, $sub_part_id, $deduct_qty);

        if (($bom_row['type'] ?? '') == 'Manufactured') {
            rw_reduce_bom_materials($conn, $sub_part_id, $count_qty);
        }
    }
}

function rw_get_active_breakdown($conn, $req_date) {
    $req_date = mysqli_real_escape_string($conn, $req_date);
    $sql = "SELECT id FROM replica_wood_breakdown_log
            WHERE req_date = '$req_date' AND status = 'active'
            ORDER BY id DESC LIMIT 1";
    $res = mysqli_query($conn, $sql);
    return ($res && mysqli_num_rows($res) > 0) ? mysqli_fetch_assoc($res) : null;
}

function rw_get_shift_status($conn, $req_date) {
    $req_date = mysqli_real_escape_string($conn, $req_date);
    $res = mysqli_query($conn, "SELECT status FROM replica_wood_shift_status WHERE req_date = '$req_date' LIMIT 1");
    return ($res && mysqli_num_rows($res) > 0) ? mysqli_fetch_assoc($res)['status'] : 'not_started';
}

// Push one action onto the capped undo stack for this session.
function rw_push_undo_action($part_id, $type, $req_date) {
    if (!isset($_SESSION['rw_undo_stack']) || !is_array($_SESSION['rw_undo_stack'])) {
        $_SESSION['rw_undo_stack'] = [];
    }
    $_SESSION['rw_undo_stack'][] = [
        'part_id'  => $part_id,
        'type'     => $type,
        'req_date' => $req_date,
    ];
    if (count($_SESSION['rw_undo_stack']) > RW_UNDO_STACK_LIMIT) {
        array_shift($_SESSION['rw_undo_stack']);
    }
}

if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'log_count_wood') {

    $part_id     = intval($_REQUEST['part_id']);
    $req_date    = mysqli_real_escape_string($conn, $_REQUEST['req_date']);
    $type        = $_REQUEST['type'] === 'green' ? 'green' : 'red';
    $engineer_id = intval($_SESSION['engineer_id'] ?? 0);
    $now         = date('Y-m-d H:i:s');

    if ($part_id <= 0 || !$req_date) {
        echo json_encode(["success" => false, "message" => "Missing parameters"]);
        exit;
    }

    // Server-side mirror of every client-side gate — a disabled button is
    // a UI hint, not a security boundary.
    if (rw_get_active_breakdown($conn, $req_date)) {
        echo json_encode(["success" => false, "message" => "There's an active breakdown — all lines are paused"]);
        exit;
    }
    if (rw_get_shift_status($conn, $req_date) !== 'started') {
        echo json_encode(["success" => false, "message" => "Shift hasn't been started for this date"]);
        exit;
    }
    $plan_check = mysqli_query($conn, "SELECT req_qty FROM replica_wood_planning
                                        WHERE part_id = $part_id AND req_date = '$req_date' LIMIT 1");
    $req_qty = ($plan_check && mysqli_num_rows($plan_check) > 0) ? (int) mysqli_fetch_assoc($plan_check)['req_qty'] : 0;
    if ($req_qty <= 0) {
        echo json_encode(["success" => false, "message" => "No requirement set for this item today"]);
        exit;
    }

    mysqli_autocommit($conn, false);
    $error = false;
    $error_message = '';

    // Upsert +1 into the appropriate log — GREEN into replica_wood_count_log,
    // RED into its own replica_wood_scrap_log. One accumulated row per
    // (part, date), not one row per tap; replica_wood_planning is never
    // touched here any more (it only ever stores the requirement).
    if ($type === 'green') {
        $log_ok = mysqli_query($conn, "INSERT INTO replica_wood_count_log 
                (part_id, req_date, quantity, engineer_id, created_on, updated_on)
                VALUES ($part_id, '$req_date', 1, $engineer_id, '$now', '$now')
                ON DUPLICATE KEY UPDATE
                    quantity = quantity + 1,
                    engineer_id = $engineer_id,
                    updated_on = '$now'");
    } else {
        $log_ok = mysqli_query($conn, "INSERT INTO replica_wood_scrap_log 
                (part_id, req_date, quantity, engineer_id, created_on, updated_on)
                VALUES ($part_id, '$req_date', 1, $engineer_id, '$now', '$now')
                ON DUPLICATE KEY UPDATE
                    quantity = quantity + 1,
                    engineer_id = $engineer_id,
                    updated_on = '$now'");
    }
    if (!$log_ok) {
        $error = true;
        $error_message = mysqli_error($conn);
    }

    // GREEN ONLY — add 1 finished piece to stock.
    if (!$error && $type == 'green') {
        if (!rw_update_inventory_stock($conn, $part_id, 1)) {
            $error = true;
            $error_message = "Failed to update finished stock";
        }
    }

    // BOTH Green and Red — consume BOM raw materials for 1 piece.
    if (!$error) {
        rw_reduce_bom_materials($conn, $part_id, 1);
    }

    if ($error) {
        mysqli_rollback($conn);
        mysqli_autocommit($conn, true);
        echo json_encode(["success" => false, "message" => $error_message]);
    } else {
        mysqli_commit($conn);
        mysqli_autocommit($conn, true);

        // Push onto the undo stack so up to RW_UNDO_STACK_LIMIT recent
        // taps can be undone in order, most recent first.
        rw_push_undo_action($part_id, $type, $req_date);

        echo json_encode(["success" => true]);
    }
    exit;
}

if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'undo_last_wood') {

    $req_date = mysqli_real_escape_string($conn, $_REQUEST['req_date'] ?? '');

    if (rw_get_active_breakdown($conn, $req_date)) {
        echo json_encode(["success" => false, "message" => "There's an active breakdown — all lines are paused"]);
        exit;
    }

    $stack = $_SESSION['rw_undo_stack'] ?? [];
    $last  = end($stack);

    if (!$last || ($last['req_date'] ?? '') !== $req_date) {
        echo json_encode(["success" => false, "message" => "Nothing to undo"]);
        exit;
    }

    $part_id = intval($last['part_id']);
    $type    = $last['type'] === 'green' ? 'green' : 'red';
    $now     = date('Y-m-d H:i:s');
    $table   = $type === 'green' ? 'replica_wood_count_log' : 'replica_wood_scrap_log';

    mysqli_autocommit($conn, false);
    $error = false;
    $error_message = '';

    $dec_ok = mysqli_query($conn, "UPDATE $table
            SET quantity = GREATEST(quantity - 1, 0), updated_on = '$now'
            WHERE part_id = $part_id AND req_date = '$req_date'");
    if (!$dec_ok) {
        $error = true;
        $error_message = mysqli_error($conn);
    } else {
        // Drop the row at 0 so a future +1 tap re-inserts cleanly instead
        // of resuming from a stale zero row.
        mysqli_query($conn, "DELETE FROM $table WHERE part_id = $part_id AND req_date = '$req_date' AND quantity <= 0");
    }

    // GREEN ONLY — remove the finished piece we'd added to stock.
    if (!$error && $type === 'green') {
        if (!rw_update_inventory_stock($conn, $part_id, -1)) {
            $error = true;
            $error_message = "Failed to reverse finished stock";
        }
    }

    // BOTH green and red consumed BOM raw materials for 1 piece — give it back.
    if (!$error) {
        rw_reduce_bom_materials($conn, $part_id, -1);
    }

    if ($error) {
        mysqli_rollback($conn);
        mysqli_autocommit($conn, true);
        echo json_encode(["success" => false, "message" => $error_message]);
    } else {
        mysqli_commit($conn);
        mysqli_autocommit($conn, true);

        // Pop only after a successful reversal — if anything failed above,
        // the stack still has this entry so the operator can retry.
        array_pop($_SESSION['rw_undo_stack']);

        echo json_encode([
            "success"    => true,
            "undo_count" => count($_SESSION['rw_undo_stack']),
        ]);
    }
    exit;
}

if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'start_shift') {

    $req_date = mysqli_real_escape_string($conn, $_REQUEST['req_date'] ?? '');
    $user_id  = intval($_SESSION['engineer_id'] ?? 0);
    $now      = date('Y-m-d H:i:s');

    if (!$req_date) {
        echo json_encode(["success" => false, "message" => "Missing date"]);
        exit;
    }

    $sql = "INSERT INTO replica_wood_shift_status (req_date, status, updated_by, updated_on)
            VALUES ('$req_date', 'started', $user_id, '$now')
            ON DUPLICATE KEY UPDATE status = 'started', updated_by = $user_id, updated_on = '$now'";

    if (mysqli_query($conn, $sql)) {
        // A new shift start is a clean boundary — don't let undo reach
        // back into whatever happened on a previous shift/session.
        unset($_SESSION['rw_undo_stack']);
        echo json_encode(["success" => true, "message" => "Shift started"]);
    } else {
        echo json_encode(["success" => false, "message" => mysqli_error($conn)]);
    }
    exit;
}

if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'pause_shift') {

    $req_date = mysqli_real_escape_string($conn, $_REQUEST['req_date'] ?? '');
    $user_id  = intval($_SESSION['engineer_id'] ?? 0);
    $now      = date('Y-m-d H:i:s');

    if (!$req_date) {
        echo json_encode(["success" => false, "message" => "Missing date"]);
        exit;
    }

    $sql = "INSERT INTO replica_wood_shift_status (req_date, status, updated_by, updated_on)
            VALUES ('$req_date', 'paused', $user_id, '$now')
            ON DUPLICATE KEY UPDATE status = 'paused', updated_by = $user_id, updated_on = '$now'";

    if (mysqli_query($conn, $sql)) {
        echo json_encode(["success" => true, "message" => "Shift paused"]);
    } else {
        echo json_encode(["success" => false, "message" => mysqli_error($conn)]);
    }
    exit;
}

if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'log_breakdown_wood') {

    $req_date    = mysqli_real_escape_string($conn, $_REQUEST['req_date']);
    $reason      = mysqli_real_escape_string($conn, trim($_REQUEST['reason'] ?? ''));
    $note        = mysqli_real_escape_string($conn, trim($_REQUEST['note'] ?? ''));
    $engineer_id = intval($_SESSION['engineer_id'] ?? 0);
    $now         = date('Y-m-d H:i:s');

    if (!$req_date || $reason === '') {
        echo json_encode(["success" => false, "message" => "Missing parameters"]);
        exit;
    }

    if (rw_get_active_breakdown($conn, $req_date)) {
        echo json_encode(["success" => false, "message" => "There's already an active breakdown for this date"]);
        exit;
    }

    $sql = "INSERT INTO replica_wood_breakdown_log
                (req_date, engineer_id, reason, note, status, started_at)
            VALUES
                ('$req_date', $engineer_id, '$reason', " .
                ($note !== '' ? "'$note'" : "NULL") . ", 'active', '$now')";

    if (mysqli_query($conn, $sql)) {
        // A breakdown is also a natural boundary for what "undo" should
        // be able to reach back through.
        unset($_SESSION['rw_undo_stack']);
        echo json_encode(["success" => true, "message" => "Breakdown logged"]);
    } else {
        echo json_encode(["success" => false, "message" => mysqli_error($conn)]);
    }
    exit;
}

if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'end_breakdown_wood') {

    $req_date = mysqli_real_escape_string($conn, $_REQUEST['req_date']);
    $now      = date('Y-m-d H:i:s');

    $active = rw_get_active_breakdown($conn, $req_date);
    if (!$active) {
        echo json_encode(["success" => false, "message" => "No active breakdown found for this date"]);
        exit;
    }

    $sql = "UPDATE replica_wood_breakdown_log
            SET status = 'completed', ended_at = '$now'
            WHERE id = " . intval($active['id']);

    if (mysqli_query($conn, $sql)) {
        echo json_encode(["success" => true, "message" => "Breakdown ended"]);
    } else {
        echo json_encode(["success" => false, "message" => mysqli_error($conn)]);
    }
    exit;
}

echo json_encode(["success" => false, "message" => "Unknown action"]);
exit;
?>