<?php

declare(strict_types=1);

require DENTAL_ROOT . '/app/bootstrap.php';
require_login();
require_roles(['super_admin','clinic_admin']);
require_permission('system.transaction_integrity.view', ['super_admin','clinic_admin']);
require DENTAL_ROOT . '/app/layout.php';
require DENTAL_ROOT . '/app/module_helpers.php';

$pdo = db();
$role = active_role();
$branchId = superuser_primary_workspace() ? 0 : signed_user_branch_id();
$hours = max(1, min(720, (int)($_GET['hours'] ?? 24)));
$status = trim((string)($_GET['status'] ?? 'all'));
if (!in_array($status, ['all','processing','completed','failed'], true)) $status='all';
$q = trim((string)($_GET['q'] ?? ''));

$summary = operation_integrity_summary($pdo, $hours, $branchId > 0 ? $branchId : null);
$rows = [];
$error = '';
if (!operation_integrity_schema_ready()) {
    $error = 'Apply DentalCare v0.9.1.4 before using transaction-integrity monitoring.';
} else {
    $where = ['o.created_at>=DATE_SUB(NOW(),INTERVAL ' . $hours . ' HOUR)'];
    $args = [];
    if ($branchId > 0) { $where[]='o.branch_id=?'; $args[]=$branchId; }
    if ($status !== 'all') { $where[]='o.status=?'; $args[]=$status; }
    if ($q !== '') {
        $like='%'.$q.'%';
        $where[]='(o.route_name LIKE ? OR o.action_name LIKE ? OR o.entity_type LIKE ? OR o.response_reference LIKE ? OR o.last_error_message LIKE ?)';
        array_push($args,$like,$like,$like,$like,$like);
    }
    $stmt=$pdo->prepare(
        'SELECT o.*,u.name user_name,b.name branch_name FROM `' . table('operation_requests') . '` o '
        . 'LEFT JOIN `' . table('users') . '` u ON u.id=o.user_id '
        . 'LEFT JOIN `' . table('branches') . '` b ON b.id=o.branch_id '
        . 'WHERE ' . implode(' AND ',$where) . ' ORDER BY o.updated_at DESC,o.id DESC LIMIT 300'
    );
    $stmt->execute($args);
    $rows=$stmt->fetchAll();
}

render_header('Transaction Integrity');
render_module_intro(
    'Transaction integrity and duplicate protection',
    'Review high-risk actions protected against double-clicks, repeated browser submissions, and concurrent processing. Business records remain authoritative; this ledger records only request integrity metadata.'
);
?>
<?php if($error!==''):?><div class="flash error"><?=e($error)?></div><?php endif;?>
<section class="stat-grid">
    <?php stat_card('Completed',$summary['completed'],'Protected actions completed in the selected period'); ?>
    <?php stat_card('Processing',$summary['processing'],'Requests currently being processed'); ?>
    <?php stat_card('Duplicate submissions blocked',$summary['duplicates'],'Repeated requests stopped before a second transaction'); ?>
    <?php stat_card('Failed / retryable',$summary['failed'],'Failed attempts can be retried safely'); ?>
</section>
<?php if($summary['stale']>0):?><div class="alert warning"><strong><?=e((string)$summary['stale'])?> stale operation<?= $summary['stale']===1?'':'s' ?> detected.</strong> These requests exceeded the processing window. The next identical submission can safely take over the expired ledger entry.</div><?php endif;?>
<form method="get" class="card compact-filter" data-auto-submit>
    <label>Period<select name="hours"><option value="24" <?=$hours===24?'selected':''?>>Last 24 hours</option><option value="72" <?=$hours===72?'selected':''?>>Last 3 days</option><option value="168" <?=$hours===168?'selected':''?>>Last 7 days</option><option value="720" <?=$hours===720?'selected':''?>>Last 30 days</option></select></label>
    <label>Status<select name="status"><option value="all">All statuses</option><?php foreach(['processing','completed','failed'] as $value):?><option value="<?=e($value)?>" <?=$status===$value?'selected':''?>><?=e(module_status($value))?></option><?php endforeach;?></select></label>
    <label class="wide">Search<input type="search" name="q" value="<?=e($q)?>" placeholder="Route, action, record type, response or error"></label>
</form>
<section class="card">
<div class="card-head"><div><h2>Protected operations</h2><p>Only integrity metadata is shown. Clinical notes, dental findings, payment card data, passwords, and patient-health payloads are not stored here.</p></div></div>
<div class="table-wrap"><table><thead><tr><th>Time</th><th>User / Task View</th><th>Operation</th><th>Record</th><th>Status</th><th>Duplicates blocked</th><th>Result / error</th></tr></thead><tbody>
<?php foreach($rows as $row):?>
<tr>
<td><?=e(date('M j, Y g:i:s A',strtotime((string)$row['updated_at'])))?></td>
<td><strong><?=e((string)($row['user_name']?:'System'))?></strong><small><?=e(module_status((string)$row['active_role']))?><?=!empty($row['branch_name'])?' · '.e((string)$row['branch_name']):''?></small></td>
<td><strong><?=e((string)$row['route_name'])?></strong><small><?=e(module_status((string)$row['action_name']))?> · Attempt <?=(int)$row['attempt_count']?></small></td>
<td><?=e((string)($row['entity_type']?:'—'))?><?=!empty($row['entity_id'])?' #'.(int)$row['entity_id']:''?></td>
<td><span class="badge"><?=e(module_status((string)$row['status']))?></span></td>
<td><?=(int)$row['duplicate_count']?></td>
<td><?=e((string)($row['response_reference']?:$row['last_error_message']?:'—'))?></td>
</tr>
<?php endforeach;if(!$rows):?><tr><td colspan="7" class="muted">No protected operations matched the selected period and filters.</td></tr><?php endif;?>
</tbody></table></div>
</section>
<?php render_footer(); ?>
