<?php

declare(strict_types=1);

session_start();

require_once __DIR__ . "/config/database.php";

date_default_timezone_set("Africa/Kigali");


/*
|--------------------------------------------------------------------------
| DATABASE
|--------------------------------------------------------------------------
*/

$db = new Database();
$pdo = $db->connect();


/*
|--------------------------------------------------------------------------
| CHECK SESSION
|--------------------------------------------------------------------------
*/

if (
    !isset($_SESSION["print_job"]) ||
    !isset($_SESSION["print_job"]["order_id"])
) {

    header("Location: index.php");
    exit;

}


$orderId =
    (int)$_SESSION["print_job"]["order_id"];


$printerToken =
    $_SESSION["printer_qr"]["printer_token"]
    ?? "";


/*
|--------------------------------------------------------------------------
| AJAX JOB STATUS
|--------------------------------------------------------------------------
|
| success.php?job_status=1
|
|--------------------------------------------------------------------------
*/

if (
    isset($_GET["job_status"]) &&
    $_GET["job_status"] === "1"
) {

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


    $stmt = $pdo->prepare("
        SELECT

            id,
            status,
            created_at,
            started_at,
            completed_at,
            error_message

        FROM print_queue

        WHERE order_id = ?

        ORDER BY id DESC

        LIMIT 1
    ");


    $stmt->execute([
        $orderId
    ]);


    $job =
        $stmt->fetch(
            PDO::FETCH_ASSOC
        );


    if (!$job) {

        echo json_encode([

            "success" =>
                true,

            "found" =>
                false,

            "message" =>
                "Your print job is being prepared."

        ]);

        exit;

    }


    echo json_encode([

        "success" =>
            true,

        "found" =>
            true,

        "job" => [

            "id" =>
                (int)$job["id"],

            "status" =>
                strtoupper(
                    (string)(
                        $job["status"]
                    )
                ),

            "created_at" =>
                $job["created_at"],

            "started_at" =>
                $job["started_at"],

            "completed_at" =>
                $job["completed_at"],

            "error_message" =>
                $job["error_message"]

        ]

    ]);

    exit;

}


/*
|--------------------------------------------------------------------------
| LOAD ORDER
|--------------------------------------------------------------------------
*/

$stmt = $pdo->prepare("
    SELECT *

    FROM print_orders

    WHERE id = ?

    LIMIT 1
");


$stmt->execute([
    $orderId
]);


$order =
    $stmt->fetch(
        PDO::FETCH_ASSOC
    );


if (!$order) {

    die("Order not found.");

}


/*
|--------------------------------------------------------------------------
| LOAD PAYMENT
|--------------------------------------------------------------------------
*/

$stmt = $pdo->prepare("
    SELECT *

    FROM payments

    WHERE order_id = ?

    ORDER BY id DESC

    LIMIT 1
");


$stmt->execute([
    $orderId
]);


$payment =
    $stmt->fetch(
        PDO::FETCH_ASSOC
    );


if (!$payment) {

    die("Payment not found.");

}


/*
|--------------------------------------------------------------------------
| PAYMENT VALIDATION
|--------------------------------------------------------------------------
*/

if (
    $payment["status"] !== "SUCCESSFUL"
) {

    die(
        "Payment has not been completed."
    );

}


/*
|--------------------------------------------------------------------------
| UPDATE ORDER PAYMENT STATUS
|--------------------------------------------------------------------------
*/

$stmt = $pdo->prepare("
    UPDATE print_orders

    SET
        payment_status = 'paid'

    WHERE id = ?
");


$stmt->execute([
    $orderId
]);


/*
|--------------------------------------------------------------------------
| RECEIPT NUMBER
|--------------------------------------------------------------------------
*/

$receiptNumber =
    "SP-" .
    date("Ymd") .
    "-" .
    str_pad(
        (string)$orderId,
        6,
        "0",
        STR_PAD_LEFT
    );

?>
<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta
    name="viewport"
    content="width=device-width, initial-scale=1.0">

<title>
    Payment Successful - SmartPrint
</title>

<style>

*{
    box-sizing:border-box;
}

body{

    background:#0f1115;

    font-family:Arial, sans-serif;

    display:flex;

    justify-content:center;

    align-items:center;

    min-height:100vh;

    margin:0;

    color:white;

    padding:20px;

}

.card{

    width:500px;

    max-width:100%;

    background:#1b1d22;

    padding:35px;

    border-radius:15px;

    text-align:center;

    box-shadow:
        0 20px 50px rgba(0,0,0,.35);

}

.success{

    font-size:70px;

    color:#00c853;

    line-height:1;

}

h2{

    margin-top:15px;

}

.info{

    margin-top:25px;

    text-align:left;

    background:#252932;

    padding:20px;

    border-radius:10px;

}

.info p{

    margin:10px 0;

}

.status-box{

    margin-top:20px;

    padding:20px;

    border-radius:12px;

    background:#181a1f;

    border:1px solid #343842;

}

.status-icon{

    font-size:42px;

    margin-bottom:10px;

}

.status-title{

    font-size:22px;

    font-weight:bold;

}

.status-message{

    margin-top:8px;

    color:#bfc3cc;

    line-height:1.5;

}

.status-waiting{

    color:#ffc107;

}

.status-printing{

    color:#03a9f4;

}

.status-completed{

    color:#00c853;

}

.status-failed{

    color:#ff5252;

}

.status-dot{

    display:inline-block;

    width:12px;

    height:12px;

    border-radius:50%;

    margin-right:8px;

}

.dot-waiting{

    background:#ffc107;

}

.dot-printing{

    background:#03a9f4;

    animation:pulse 1s infinite;

}

.dot-completed{

    background:#00c853;

}

.dot-failed{

    background:#ff5252;

}

@keyframes pulse{

    0%{
        box-shadow:
            0 0 0 0
            rgba(3,169,244,.7);
    }

    70%{
        box-shadow:
            0 0 0 10px
            rgba(3,169,244,0);
    }

    100%{
        box-shadow:
            0 0 0 0
            rgba(3,169,244,0);
    }

}

.time-info{

    margin-top:15px;

    font-size:13px;

    color:#858b98;

}

button{

    margin-top:15px;

    padding:14px;

    width:100%;

    border:none;

    border-radius:8px;

    cursor:pointer;

    font-size:17px;

    background:#00c853;

    color:white;

}

button:hover{

    background:#00b248;

}

button.secondary{

    background:#343942;

}

button.secondary:hover{

    background:#414651;

}

.error-box{

    margin-top:15px;

    padding:12px;

    background:#35191c;

    color:#ff8a80;

    border-radius:8px;

    display:none;

}

@media(max-width:600px){

    body{

        padding:12px;

        align-items:flex-start;

    }

    .card{

        margin-top:15px;

        padding:22px 16px;

    }

    h2{

        font-size:23px;

    }

    .status-title{

        font-size:20px;

    }

}

</style>

</head>

<body>

<div class="card">


    <!-- PAYMENT SUCCESS -->

    <div class="success">

        ✓

    </div>


    <h2>

        Payment Successful

    </h2>


    <p>

        Your payment has been received successfully.

    </p>


    <!-- ORDER INFORMATION -->

    <div class="info">

        <p>

            <b>Receipt</b>

            <br>

            <?= htmlspecialchars(
                $receiptNumber
            ) ?>

        </p>


        <p>

            <b>Order</b>

            <br>

            <?= htmlspecialchars(
                (string)$order["order_number"]
            ) ?>

        </p>


        <p>

            <b>Amount</b>

            <br>

            <?= number_format(
                (float)$payment["amount"],
                2
            ) ?>

            <?= htmlspecialchars(
                (string)$payment["currency"]
            ) ?>

        </p>


        <p>

            <b>Transaction ID</b>

            <br>

            <?= htmlspecialchars(
                (string)$payment["transaction_id"]
            ) ?>

        </p>


        <p>

            <b>Payment Status</b>

            <br>

            <?= htmlspecialchars(
                (string)$payment["status"]
            ) ?>

        </p>

    </div>


    <!-- PRINT STATUS -->

    <div
        id="printStatusBox"
        class="status-box">

        <div
            id="statusIcon"
            class="status-icon">

            ⏳

        </div>


        <div
            id="statusTitle"
            class="status-title status-waiting">

            <span
                class="status-dot dot-waiting">
            </span>

            WAITING

        </div>


        <div
            id="statusMessage"
            class="status-message">

            Your print job is waiting in the printing queue.

        </div>


        <div
            id="statusTime"
            class="time-info">

            Checking print job status...

        </div>


        <div
            id="errorBox"
            class="error-box">

        </div>

    </div>


    <!-- RECEIPT -->

    <button
        type="button"
        onclick="window.location='receipt.php?order=<?= $orderId ?>'">

        Receipt

    </button>


    <!-- DONE -->

    <button
        type="button"
        class="secondary"
        onclick="window.location='upload.php?printer=<?= urlencode($printerToken) ?>'">

        Done

    </button>

</div>


<script>

const orderId =
    <?= $orderId ?>;


let currentStatus =
    null;


let pollingTimer =
    null;


/*
|--------------------------------------------------------------------------
| ELEMENTS
|--------------------------------------------------------------------------
*/

const statusIcon =
    document.getElementById(
        "statusIcon"
    );


const statusTitle =
    document.getElementById(
        "statusTitle"
    );


const statusMessage =
    document.getElementById(
        "statusMessage"
    );


const statusTime =
    document.getElementById(
        "statusTime"
    );


const errorBox =
    document.getElementById(
        "errorBox"
    );


/*
|--------------------------------------------------------------------------
| UPDATE UI
|--------------------------------------------------------------------------
*/

function updateStatus(job)
{

    const status =
        String(
            job.status || "WAITING"
        ).toUpperCase();


    /*
    |--------------------------------------------------------------------------
    | CLEAR OLD ERROR
    |--------------------------------------------------------------------------
    */

    errorBox.style.display =
        "none";

    errorBox.innerHTML =
        "";


    /*
    |--------------------------------------------------------------------------
    | WAITING
    |--------------------------------------------------------------------------
    */

    if (
        status === "WAITING"
    ) {

        statusIcon.innerHTML =
            "⏳";

        statusTitle.className =
            "status-title status-waiting";

        statusTitle.innerHTML =
            '<span class="status-dot dot-waiting"></span> WAITING';

        statusMessage.innerHTML =
            "Your document is waiting in the printing queue.";

        statusTime.innerHTML =
            "The Printing Agent will process your job automatically.";

        return;

    }


    /*
    |--------------------------------------------------------------------------
    | PRINTING
    |--------------------------------------------------------------------------
    */

    if (
        status === "PRINTING"
    ) {

        statusIcon.innerHTML =
            "🖨️";

        statusTitle.className =
            "status-title status-printing";

        statusTitle.innerHTML =
            '<span class="status-dot dot-printing"></span> PRINTING';

        statusMessage.innerHTML =
            "Your document is currently being printed.";

        statusTime.innerHTML =
            job.started_at
                ? "Printing started: "
                    + formatDate(
                        job.started_at
                    )
                : "Printing has started.";

        return;

    }


    /*
    |--------------------------------------------------------------------------
    | COMPLETED
    |--------------------------------------------------------------------------
    */

    if (
        status === "COMPLETED"
    ) {

        statusIcon.innerHTML =
            "✅";

        statusTitle.className =
            "status-title status-completed";

        statusTitle.innerHTML =
            '<span class="status-dot dot-completed"></span> COMPLETED';

        statusMessage.innerHTML =
            "Your document has been printed successfully.";

        statusTime.innerHTML =
            job.completed_at
                ? "Completed: "
                    + formatDate(
                        job.completed_at
                    )
                : "Printing completed successfully.";

        stopPolling();

        return;

    }


    /*
    |--------------------------------------------------------------------------
    | FAILED
    |--------------------------------------------------------------------------
    */

    if (
        status === "FAILED"
    ) {

        statusIcon.innerHTML =
            "❌";

        statusTitle.className =
            "status-title status-failed";

        statusTitle.innerHTML =
            '<span class="status-dot dot-failed"></span> FAILED';

        statusMessage.innerHTML =
            "Your document could not be printed.";

        if (
            job.error_message
        ) {

            errorBox.style.display =
                "block";

            errorBox.innerHTML =
                "<b>Reason:</b><br>"
                +
                escapeHtml(
                    job.error_message
                );

        }

        statusTime.innerHTML =
            job.completed_at
                ? "Failed: "
                    + formatDate(
                        job.completed_at
                    )
                : "The printing job failed.";

        stopPolling();

    }

}


/*
|--------------------------------------------------------------------------
| LOAD JOB STATUS
|--------------------------------------------------------------------------
*/

async function loadJobStatus()
{

    try {

        const response =
            await fetch(
                "job_status.php?order_id="
                +
                encodeURIComponent(
                    orderId
                )
                +
                "&_="
                +
                Date.now(),
                {
                    method:
                        "GET",

                    cache:
                        "no-store",

                    headers: {
                        "Accept":
                            "application/json"
                    }
                }
            );


        if (!response.ok) {

            throw new Error(
                "HTTP "
                +
                response.status
            );

        }


        const data =
            await response.json();


        if (!data.success) {

            statusTime.innerHTML =
                data.message
                ||
                "Unable to check print status.";

            return;

        }


        if (!data.found) {

            statusIcon.innerHTML =
                "⏳";

            statusTitle.className =
                "status-title status-waiting";

            statusTitle.innerHTML =
                '<span class="status-dot dot-waiting"></span> WAITING';

            statusMessage.innerHTML =
                data.message
                ||
                "Your print job is being added to the queue.";

            statusTime.innerHTML =
                "Waiting for the Printing Agent queue.";

            return;

        }


        const job =
            data.job;


        if (
            currentStatus !==
            job.status
        ) {

            currentStatus =
                job.status;

            updateStatus(
                job
            );

        }

    }
    catch (error) {

        console.error(
            "SmartPrint status error:",
            error
        );

        statusTime.innerHTML =
            "Checking connection...";

    }

}


/*
|--------------------------------------------------------------------------
| START POLLING
|--------------------------------------------------------------------------
*/

function startPolling()
{

    loadJobStatus();


    pollingTimer =
        setInterval(
            loadJobStatus,
            3000
        );

}


/*
|--------------------------------------------------------------------------
| STOP POLLING
|--------------------------------------------------------------------------
*/

function stopPolling()
{

    if (
        pollingTimer !== null
    ) {

        clearInterval(
            pollingTimer
        );

        pollingTimer =
            null;

    }

}


/*
|--------------------------------------------------------------------------
| FORMAT DATE
|--------------------------------------------------------------------------
*/

function formatDate(
    dateString
)
{

    if (!dateString) {

        return "";

    }


    const date =
        new Date(
            String(
                dateString
            ).replace(
                " ",
                "T"
            )
        );


    if (
        Number.isNaN(
            date.getTime()
        )
    ) {

        return dateString;

    }


    return date.toLocaleString(
        "en-RW",
        {
            dateStyle:
                "medium",

            timeStyle:
                "short"
        }
    );

}


/*
|--------------------------------------------------------------------------
| ESCAPE HTML
|--------------------------------------------------------------------------
*/

function escapeHtml(
    value
)
{

    return String(value)
        .replace(
            /&/g,
            "&amp;"
        )
        .replace(
            /</g,
            "&lt;"
        )
        .replace(
            />/g,
            "&gt;"
        )
        .replace(
            /"/g,
            "&quot;"
        )
        .replace(
            /'/g,
            "&#039;"
        );

}


/*
|--------------------------------------------------------------------------
| START
|--------------------------------------------------------------------------
*/

startPolling();

</script>

</body>

</html>