<?php
session_start();
$_SESSION['debug'] = "approve_shipment.php accessed, POST data: " . print_r($_POST, true);
require_once __DIR__ . '/../../classes/Database.php';
require_once __DIR__ . '/../../classes/Logger.php';
require_once __DIR__ . '/../../classes/Shipment.php';


if (!isset($_SESSION['role']) || !in_array($_SESSION['role'], ['admin', 'super_admin'])) {
    header('Location: /unauthorized.php');
    exit();
}


if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    $_SESSION['error'] = 'Invalid request method.';
    header('Location: ../../views/shipments/pending_approvals.php');
    exit();
}


if (!isset($_POST['shipment_id']) || !is_numeric($_POST['shipment_id'])) {
    $_SESSION['error'] = 'Invalid shipment ID provided.';
    header('Location: ../../views/shipments/pending_approvals.php');
    exit();
}

$shipmentId = (int)$_POST['shipment_id'];
$approverId = $_SESSION['user_id'];


$database = new Database();
$conn = $database->getConnection();


$logger = new Logger($conn, $_SESSION['user_id'], $_SESSION['username'], $_SESSION['role']);

$shipment = new Shipment($conn, $logger);

try {

    $shipmentDetails = $shipment->getShipmentById($shipmentId);

    if (!$shipmentDetails) {
        throw new Exception('Shipment not found.');
    }


    if ($shipmentDetails['status'] !== 'pending') {
        throw new Exception('Shipment is no longer pending approval. Current status: ' . $shipmentDetails['status']);
    }


    if ($shipmentDetails['created_by'] == $approverId) {
        throw new Exception('You cannot approve a shipment you created.');
    }

    $conn->beginTransaction();

    if (isset($_POST['approve'])) {

        $updateSql = "UPDATE shipments SET
                        status = 'shipped',
                        approved_by = :approved_by,
                        approval_date = NOW()
                      WHERE shipment_id = :shipment_id";

        $stmt = $conn->prepare($updateSql);
        $stmt->bindParam(':approved_by', $approverId, PDO::PARAM_INT);
        $stmt->bindParam(':shipment_id', $shipmentId, PDO::PARAM_INT);

        if (!$stmt->execute()) {
            throw new Exception('Failed to approve shipment.');
        }


        $logSql = "INSERT INTO shipment_logs (shipment_id, action, performed_by, notes, action_date)
                   VALUES (:shipment_id, 'approved', :performed_by, 'Shipment approved for dispatch', NOW())";
        $logStmt = $conn->prepare($logSql);
        $logStmt->bindParam(':shipment_id', $shipmentId, PDO::PARAM_INT);
        $logStmt->bindParam(':performed_by', $approverId, PDO::PARAM_INT);
        $logStmt->execute();

        $conn->commit();
        $_SESSION['success'] = 'Shipment #' . $shipmentId . ' has been approved successfully. It is now ready for dispatch to ' . htmlspecialchars($shipmentDetails['to_branch_name']) . '.';

    } elseif (isset($_POST['reject'])) {

        $rejectionNotes = trim($_POST['rejection_notes'] ?? '');

        if (empty($rejectionNotes)) {
            throw new Exception('Rejection reason is required.');
        }


        $updateSql = "UPDATE shipments SET
                        status = 'rejected',
                        approved_by = :approved_by,
                        approval_date = NOW(),
                        rejection_notes = :rejection_notes
                      WHERE shipment_id = :shipment_id";

        $stmt = $conn->prepare($updateSql);
        $stmt->bindParam(':approved_by', $approverId, PDO::PARAM_INT);
        $stmt->bindParam(':rejection_notes', $rejectionNotes, PDO::PARAM_STR);
        $stmt->bindParam(':shipment_id', $shipmentId, PDO::PARAM_INT);

        if (!$stmt->execute()) {
            throw new Exception('Failed to reject shipment.');
        }


        $itemsSql = "SELECT si.item_id FROM shipment_items si WHERE si.shipment_id = :shipment_id";
        $itemsStmt = $conn->prepare($itemsSql);
        $itemsStmt->bindParam(':shipment_id', $shipmentId, PDO::PARAM_INT);
        $itemsStmt->execute();
        $items = $itemsStmt->fetchAll(PDO::FETCH_ASSOC);


        if (!empty($items)) {
            foreach ($items as $item) {
                $returnItemSql = "UPDATE items SET current_location_id = :from_branch_id WHERE item_id = :item_id";
                $returnStmt = $conn->prepare($returnItemSql);
                $returnStmt->bindParam(':from_branch_id', $shipmentDetails['from_branch_id'], PDO::PARAM_INT);
                $returnStmt->bindParam(':item_id', $item['item_id'], PDO::PARAM_INT);
                $returnStmt->execute();
            }
        }


        $logSql = "INSERT INTO shipment_logs (shipment_id, action, performed_by, notes, action_date)
                   VALUES (:shipment_id, 'rejected', :performed_by, :notes, NOW())";
        $logStmt = $conn->prepare($logSql);
        $logStmt->bindParam(':shipment_id', $shipmentId, PDO::PARAM_INT);
        $logStmt->bindParam(':performed_by', $approverId, PDO::PARAM_INT);
        $logStmt->bindParam(':notes', $rejectionNotes, PDO::PARAM_STR);
        $logStmt->execute();

        $conn->commit();
        $_SESSION['success'] = 'Shipment #' . $shipmentId . ' has been rejected. Items have been returned to ' . htmlspecialchars($shipmentDetails['from_branch_name']) . '. Reason: ' . htmlspecialchars($rejectionNotes);

    } else {
        throw new Exception('Invalid action specified.');
    }


    $redirectUrl = '../../views/shipments/pending_approvals.php';
    if (isset($_POST['approve'])) {
        $redirectUrl .= '?filter=approved';
    }

} catch (Exception $e) {
    if ($conn->inTransaction()) {
        $conn->rollback();
    }

    error_log("Error in approve_shipment.php: " . $e->getMessage());
    $_SESSION['error'] = 'Error: ' . $e->getMessage();


    header('Location: ../../views/shipments/view_for_approval.php?id=' . $shipmentId);
    exit();
}


header('Location: ' . $redirectUrl);
exit();
?>