<?php

declare(strict_types=1);

require_once __DIR__ . '/../Core/Database.php';

session_start();

$pdo = Database::connection();

if (empty($_SESSION['admin_id'])) {
    header('Location: ../public/login.php');
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: dashboard.php');
    exit;
}

$applicationId = (int)($_POST['application_id'] ?? 0);

$newStatus = trim(
    $_POST['status'] ?? ''
);

$adminNote = trim(
    $_POST['admin_note'] ?? ''
);

$allowedStatuses = [
    'SUBMITTED',
    'PROCESSING',
    'COMPLETED',
    'NEEDS_CORRECTION',
    'CANCELLED'
];

if (
    $applicationId <= 0 ||
    !in_array(
        $newStatus,
        $allowedStatuses,
        true
    )
) {
    header(
        'Location: dashboard.php?error=Invalid+status+request'
    );
    exit;
}

try {

    $pdo->beginTransaction();

    /*
    |--------------------------------------------------------------------------
    | GET CURRENT APPLICATION
    |--------------------------------------------------------------------------
    */

    $stmt = $pdo->prepare("
        SELECT
            id,
            status
        FROM applications
        WHERE id = ?
        LIMIT 1
        FOR UPDATE
    ");

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

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

    if (!$application) {

        throw new RuntimeException(
            'Application not found.'
        );
    }

    $oldStatus =
        $application['status'];

    /*
    |--------------------------------------------------------------------------
    | UPDATE APPLICATION
    |--------------------------------------------------------------------------
    */

    $stmt = $pdo->prepare("
        UPDATE applications
        SET
            status = ?,
            admin_note = ?,
            updated_at = NOW()
        WHERE id = ?
    ");

    $stmt->execute([
        $newStatus,
        $adminNote !== ''
            ? $adminNote
            : null,
        $applicationId
    ]);

    /*
    |--------------------------------------------------------------------------
    | STATUS HISTORY
    |--------------------------------------------------------------------------
    |
    | We keep history instead of destroying it.
    |
    */

    $historyExists = false;

    try {

        $check =
            $pdo->query("
                DESCRIBE application_status_history
            ");

        $columns =
            $check->fetchAll(
                PDO::FETCH_COLUMN
            );

        if (
            in_array(
                'application_id',
                $columns,
                true
            )
        ) {

            $historyExists = true;
        }

    } catch (Throwable $e) {
    }


    if ($historyExists) {

        /*
        | Try the most complete known structure first.
        */

        try {

            $stmt = $pdo->prepare("
                INSERT INTO application_status_history
                (
                    application_id,
                    old_status,
                    new_status,
                    admin_id,
                    note,
                    created_at
                )
                VALUES
                (?, ?, ?, ?, ?, NOW())
            ");

            $stmt->execute([
                $applicationId,
                $oldStatus,
                $newStatus,
                (int)$_SESSION['admin_id'],
                $adminNote !== ''
                    ? $adminNote
                    : null
            ]);

        } catch (Throwable $historyError) {

            /*
            | Fallback for installations where the history
            | table uses fewer columns.
            */

            try {

                $stmt = $pdo->prepare("
                    INSERT INTO application_status_history
                    (
                        application_id,
                        old_status,
                        new_status
                    )
                    VALUES
                    (?, ?, ?)
                ");

                $stmt->execute([
                    $applicationId,
                    $oldStatus,
                    $newStatus
                ]);

            } catch (Throwable $ignore) {
                /*
                | Application status has already been updated.
                | We do not break the operation because of an
                | optional history-column mismatch.
                */
            }
        }
    }

    $pdo->commit();

    header(
        'Location: dashboard.php?success=Status+updated'
    );

    exit;

} catch (Throwable $e) {

    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    header(
        'Location: dashboard.php?error=' .
        urlencode($e->getMessage())
    );

    exit;
}