<?php
/* Verifiziert eine Unterschrift-Seite: liest den gespeicherten Hash aus der
 * zugehörigen .meta.json und rechnet den aktuellen Hash über die Seiten
 * die zum Signaturzeitpunkt existierten nach.
 *
 * POST: pageid, token
 *
 * Antwort:
 *   { success: true, verified: true, meta: {...} }
 *     → Hash stimmt, keine nachträgliche Änderung
 *   { success: true, verified: false, reason: "...", meta: {...}, current_hash: "..." }
 *     → Hash stimmt nicht, nachträgliche Änderung erkannt
 */
require_once __DIR__.'/_inc.php';

global $db, $user;
if (!$user->hasRight('bericht', 'read')) bericht_ajax_fail('Permission denied', 403);

$pageid = (int) ($_POST['pageid'] ?? $_GET['pageid'] ?? 0);
if (!$pageid) bericht_ajax_fail('pageid fehlt');

$sqlr = $db->query("SELECT rowid, fk_bericht, source_path FROM ".$db->prefix()."bericht_page WHERE rowid = ".$pageid);
if (!$sqlr || !($row = $db->fetch_object($sqlr))) bericht_ajax_fail('Seite nicht gefunden', 404);

$full = bericht_resolve_data_path($row->source_path);
if (!$full || !file_exists($full)) bericht_ajax_fail('Datei nicht gefunden', 404);

$meta_path = $full.'.meta.json';
if (!file_exists($meta_path)) {
    bericht_ajax_ok(array(
        'verified' => false,
        'reason' => 'Keine Metadaten-Datei — diese Seite ist keine aufgewertete Unterschrift',
    ));
}

$meta = json_decode(file_get_contents($meta_path), true);
if (!is_array($meta) || empty($meta['chain_hash_sha256'])) {
    bericht_ajax_ok(array(
        'verified' => false,
        'reason' => 'Metadaten ungültig oder kein Hash enthalten',
    ));
}

// Wir brauchen den Bericht
$bericht = new Bericht($db);
if ($bericht->fetch($row->fk_bericht) <= 0) bericht_ajax_fail('Bericht nicht gefunden', 404);

// Die zum Signaturzeitpunkt existierenden Seiten: alle mit page_order < unserer.
// Sort nach page_order wie beim Signieren.
$prev_pages = BerichtPage::fetchAllForBericht($db, $row->fk_bericht);
// Nur die Seiten die VOR der Signatur waren — wir nehmen die ersten N entsprechend meta.page_count_at_signing
$expected_count = (int) ($meta['page_count_at_signing'] ?? 0);
$to_hash = array_slice($prev_pages, 0, $expected_count);

$current_count = 0;
foreach ($prev_pages as $pp) {
    if ($pp->id == $row->rowid) break;
    $current_count++;
}

// Hash nachrechnen
$hash_ctx = hash_init('sha256');
hash_update($hash_ctx, 'bericht:'.$bericht->id.'|ref:'.$bericht->ref);
foreach ($to_hash as $pp) {
    $full_pp = bericht_resolve_data_path($pp->source_path);
    if ($full_pp && file_exists($full_pp)) {
        hash_update_file($hash_ctx, $full_pp);
    }
    hash_update($hash_ctx, '|order:'.$pp->page_order.'|note:'.($pp->note ?? ''));
}
$current_hash = hash_final($hash_ctx);
$stored_hash = $meta['chain_hash_sha256'];

$verified = hash_equals($stored_hash, $current_hash);

$result = array(
    'verified' => $verified,
    'stored_hash' => $stored_hash,
    'current_hash' => $current_hash,
    'expected_page_count' => $expected_count,
    'current_page_count' => $current_count,
    'meta' => array(
        'signer_name' => $meta['signer_name'] ?? '',
        'signed_at' => $meta['signed_at'] ?? '',
        'user_login' => $meta['user_login'] ?? '',
        'kunde' => $meta['kunde'] ?? '',
        'parent_ref' => $meta['parent_ref'] ?? '',
        'gps_lat' => $meta['gps_lat'] ?? null,
        'gps_lon' => $meta['gps_lon'] ?? null,
        'remote_ip' => $meta['remote_ip'] ?? '',
    ),
);

if (!$verified) {
    if ($current_count !== $expected_count) {
        $result['reason'] = "Seitenanzahl hat sich geändert ($expected_count → $current_count)";
    } else {
        $result['reason'] = "Hash der Vorseiten stimmt nicht — eine Seite wurde nach der Unterschrift verändert";
    }
}

bericht_ajax_ok($result);
