<?php
ob_start();
require("dbconnect.php");
require("config.php");
require("function.php");

header('Content-Type: application/json');

// See dispatchalert_update.php for why we turn this off — keeps errors as
// JSON instead of a fatal mysqli_sql_exception dumping HTML into the response.
if (function_exists('mysqli_report')) { mysqli_report(MYSQLI_REPORT_OFF); }

if (!isset($_SESSION["username_".$dbname])) {
    echo json_encode(['success'=>false,'message'=>'Session expired. Please re-login.']);
    exit;
}

$zdb = $_SESSION["zdbyear_".$dbname];
mysqli_select_db($conn, $zdb);

try {

$vouchno = isset($_POST['vouchno']) ? (int)$_POST['vouchno'] : 0;
if ($vouchno <= 0) {
    echo json_encode(['success'=>false,'message'=>'Invalid sale order.']);
    exit;
}

$hdrRes = mysqli_query($conn, "SELECT `vouchno`,`invoiceno`,`salesman` FROM `saleorder` WHERE `vouchno`='$vouchno'");
$hdr    = $hdrRes ? mysqli_fetch_assoc($hdrRes) : null;
if (!$hdr) {
    echo json_encode(['success'=>false,'message'=>'Sale order not found.']);
    exit;
}

// Can't revert an order that's already been invoiced — it must stay in the
// Invoiced tab. Only Dispatched-but-not-yet-invoiced orders can move back.
if ((int)($hdr['invoiceno'] ?? 0) > 0) {
    echo json_encode(['success'=>false,'message'=>'This order is already invoiced and cannot be moved back to Pending.']);
    exit;
}

$audituser = audituser();

// ── Clear dispatch/LR/transporter details, putting the order back into
// "Pending Dispatch" (dispatchdate IS NULL is what the Pending tab filters on).
$ok = mysqli_query($conn, "UPDATE `saleorder` SET
    `dispatchdate`=NULL,
    `dispatchby`='',
    `transportmode`='',
    `lrno`='',
    `lrdate`=NULL,
    `transporter`='',
    `edituser`='$audituser', `editdate`=CURDATE(), `edittime`=CURTIME()
    WHERE `vouchno`='$vouchno'");

if (!$ok) {
    echo json_encode(['success'=>false,'message'=>mysqli_error($conn)]);
    exit;
}

// ── Undo the stock-OUT and accounting entries that were posted on dispatch
// (see dispatchalert_update.php) — both were keyed source='DSP', vouchno=this
// sale order, so removing those rows fully reverses the dispatch.
mysqli_query($conn, "DELETE FROM `transacn` WHERE `source`='DSP' AND `vouchno`='$vouchno'");
mysqli_query($conn, "DELETE FROM `actran`   WHERE `source`='DSP' AND `vouchno`='$vouchno'");

// ── Notify: Sale Order moved back to Pending Dispatch ──────────────────────
$custRes  = mysqli_query($conn, "SELECT a.name AS custname FROM `saleorder` s LEFT JOIN `accmast` a ON a.accode = s.customer WHERE s.vouchno='$vouchno'");
$custRow  = $custRes ? mysqli_fetch_assoc($custRes) : null;
$custName = $custRow['custname'] ?? '';
$salesman = (int)($hdr['salesman'] ?? 0);
$msgRevert = mysqli_real_escape_string($conn,
    "Sale Order #$vouchno" . ($custName ? " ($custName)" : '') . " was moved back to Pending Dispatch by $audituser.");

mysqli_query($conn, "CREATE TABLE IF NOT EXISTS `notifications` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `vouchno` INT(11) NOT NULL DEFAULT 0,
    `reftype` VARCHAR(20) NOT NULL DEFAULT '',
    `audience` VARCHAR(30) NOT NULL DEFAULT '',
    `action` VARCHAR(20) NOT NULL DEFAULT '',
    `message` VARCHAR(255) NOT NULL DEFAULT '',
    `readflag` VARCHAR(1) NOT NULL DEFAULT '',
    `createduser` VARCHAR(50) NOT NULL DEFAULT '',
    `createddate` DATE NULL,
    `createdtime` TIME NULL,
    PRIMARY KEY (`id`),
    KEY `audience` (`audience`),
    KEY `vouchno` (`vouchno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

mysqli_query($conn, "INSERT INTO `notifications`
    (`vouchno`,`reftype`,`audience`,`action`,`message`,`createduser`,`createddate`,`createdtime`)
    VALUES ('$vouchno','saleorder','admin','info','$msgRevert','$audituser',CURDATE(),CURTIME())");

if ($salesman > 0) {
    mysqli_query($conn, "INSERT INTO `notifications`
        (`vouchno`,`reftype`,`audience`,`action`,`message`,`createduser`,`createddate`,`createdtime`)
        VALUES ('$vouchno','saleorder','salesman_$salesman','info','$msgRevert','$audituser',CURDATE(),CURTIME())");
}

if (ob_get_level() > 0) { ob_clean(); }
echo json_encode(['success'=>true]);

} catch (\Throwable $e) {
    if (ob_get_level() > 0) { ob_clean(); }
    echo json_encode(['success'=>false, 'message'=>$e->getMessage()]);
}
