<?php
declare(strict_types=1);

require_once __DIR__ . '/../includes/layout.php';

require_permission($conn, 'audit_report');
ensure_audit_log_schema($conn);

function audit_report_text(string $thaiText, string $englishText): string
{
    return ui_text($thaiText, $englishText);
}

function audit_report_date_value(string $value, string $default): string
{
    $timestamp = strtotime($value);

    if ($timestamp === false) {
        return $default;
    }

    return date('Y-m-d', $timestamp);
}

function audit_report_module_labels(): array
{
    return array(
        'bill' => audit_report_text('บิล', 'Bill'),
        'payment' => audit_report_text('การชำระเงิน', 'Payment'),
        'void' => audit_report_text('ยกเลิกบิล', 'Void'),
        'package' => audit_report_text('แพ็กเกจ', 'Package'),
        'loyalty' => audit_report_text('แต้มสะสม', 'Loyalty'),
        'customer' => audit_report_text('ลูกค้า', 'Customer'),
        'car' => audit_report_text('รถ', 'Vehicle'),
        'employee' => audit_report_text('พนักงาน', 'Employee'),
        'position' => audit_report_text('ตำแหน่ง', 'Position'),
        'permission' => audit_report_text('สิทธิ์ใช้งาน', 'Permission'),
        'service' => audit_report_text('บริการ', 'Service'),
        'category' => audit_report_text('หมวดหมู่', 'Category'),
        'group' => audit_report_text('กลุ่มบริการ', 'Service Group'),
        'queue' => audit_report_text('คิว / งาน', 'Queue / Job'),
    );
}

function audit_report_action_labels(): array
{
    return array(
        'create' => audit_report_text('สร้าง', 'Create'),
        'update' => audit_report_text('อัปเดต', 'Update'),
        'hold' => audit_report_text('พักรายการ', 'Hold'),
        'receive' => audit_report_text('รับชำระ', 'Receive'),
        'delete' => audit_report_text('ลบ', 'Delete'),
        'cancel' => audit_report_text('ยกเลิก', 'Cancel'),
        'usage' => audit_report_text('ใช้งาน', 'Usage'),
        'reverse' => audit_report_text('ย้อนกลับ', 'Reverse'),
        'earn' => audit_report_text('ได้รับ', 'Earn'),
        'assign' => audit_report_text('กำหนด', 'Assign'),
        'disable' => audit_report_text('ปิดใช้งาน', 'Disable'),
        'status' => audit_report_text('เปลี่ยนสถานะ', 'Status'),
        'reopen' => audit_report_text('เปิดใหม่', 'Reopen'),
    );
}

function audit_report_flatten($value, string $prefix = ''): array
{
    $lines = array();

    if (!is_array($value)) {
        if ($value === null || $value === '') {
            return $lines;
        }

        $displayValue = is_bool($value)
            ? ($value ? audit_report_text('ใช่', 'Yes') : audit_report_text('ไม่ใช่', 'No'))
            : (string) $value;

        return array(($prefix !== '' ? $prefix . ': ' : '') . $displayValue);
    }

    foreach ($value as $key => $item) {
        $label = is_int($key) ? $prefix : trim($prefix !== '' ? $prefix . ' / ' . (string) $key : (string) $key);

        if (is_array($item)) {
            $isSequential = array_keys($item) === range(0, count($item) - 1);

            if ($isSequential) {
                $joined = implode(', ', array_map(static function ($entry): string {
                    if (is_scalar($entry) || $entry === null) {
                        return (string) $entry;
                    }

                    return json_encode($entry, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?: '';
                }, $item));

                if ($joined !== '') {
                    $lines[] = ($label !== '' ? $label . ': ' : '') . $joined;
                }
                continue;
            }

            $lines = array_merge($lines, audit_report_flatten($item, $label));
            continue;
        }

        if ($item === null || $item === '') {
            continue;
        }

        $displayValue = is_bool($item)
            ? ($item ? audit_report_text('ใช่', 'Yes') : audit_report_text('ไม่ใช่', 'No'))
            : (string) $item;
        $lines[] = ($label !== '' ? $label . ': ' : '') . $displayValue;
    }

    return $lines;
}

function audit_report_decode(?string $json): array
{
    if (!is_string($json) || trim($json) === '') {
        return array();
    }

    $decoded = json_decode($json, true);

    return is_array($decoded) ? $decoded : array();
}

$today = date('Y-m-d');
$defaultDateFrom = date('Y-m-01');
$shouldLoadReport = isset($_GET['load']) && (string) $_GET['load'] === '1';
$dateFrom = audit_report_date_value((string) ($_GET['date_from'] ?? $defaultDateFrom), $defaultDateFrom);
$dateTo = audit_report_date_value((string) ($_GET['date_to'] ?? $today), $today);
if ($dateTo < $dateFrom) {
    $dateTo = $dateFrom;
}

$moduleOptions = audit_report_module_labels();
$actionOptions = audit_report_action_labels();
$moduleFilter = trim((string) ($_GET['module'] ?? ''));
$actionFilter = trim((string) ($_GET['action'] ?? ''));
$branchFilter = trim((string) ($_GET['branch_name'] ?? ''));
$billFilter = trim((string) ($_GET['bill_number'] ?? ''));

if ($moduleFilter !== '' && !isset($moduleOptions[$moduleFilter])) {
    $moduleFilter = '';
}

if ($actionFilter !== '' && !isset($actionOptions[$actionFilter])) {
    $actionFilter = '';
}

$branchOptions = authorized_audit_branch_options($conn);

if ($branchFilter !== '' && !in_array($branchFilter, $branchOptions, true)) {
    $branchFilter = '';
}

$startAt = $dateFrom . ' 00:00:00';
$endAt = date('Y-m-d 00:00:00', strtotime($dateTo . ' +1 day'));
$rowLimit = 300;

$where = array(
    'al.created_at >= ?',
    'al.created_at < ?',
);
$types = 'ss';
$params = array($startAt, $endAt);

$branchAccessCondition = auth_branch_condition($conn, 'al', $types, $params);
if ($branchAccessCondition !== '') {
    $where[] = $branchAccessCondition;
}

if ($branchFilter !== '') {
    $where[] = 'al.branch_name = ?';
    $types .= 's';
    $params[] = $branchFilter;
}

if ($moduleFilter !== '') {
    $where[] = 'al.module_key = ?';
    $types .= 's';
    $params[] = $moduleFilter;
}

if ($actionFilter !== '') {
    $where[] = 'al.action_key = ?';
    $types .= 's';
    $params[] = $actionFilter;
}

if ($billFilter !== '') {
    $where[] = 'al.bill_number LIKE ?';
    $types .= 's';
    $params[] = '%' . $billFilter . '%';
}

$whereSql = implode(' AND ', $where);
$summary = array();
$rows = array();

if ($shouldLoadReport) {
    $summaryStmt = db_prepare($conn, "
        SELECT
            COUNT(*) AS total_logs,
            SUM(CASE WHEN al.module_key = 'bill' THEN 1 ELSE 0 END) AS bill_logs,
            SUM(CASE WHEN al.module_key = 'payment' THEN 1 ELSE 0 END) AS payment_logs,
            SUM(CASE WHEN al.module_key = 'void' THEN 1 ELSE 0 END) AS void_logs,
            COALESCE(SUM(al.amount), 0) AS affected_amount
        FROM audit_logs al
        WHERE {$whereSql}
    ");
    $summaryStmt->bind_param($types, ...$params);
    $summaryStmt->execute();
    $summary = $summaryStmt->get_result()->fetch_assoc() ?: array();
    $summaryStmt->close();

    $rowsStmt = db_prepare($conn, "
        SELECT
            al.audit_log_id,
            al.module_key,
            al.action_key,
            al.entity_type,
            al.order_id,
            al.payment_id,
            al.actor_name,
            al.branch_name,
            al.bill_number,
            al.amount,
            al.message,
            al.before_json,
            al.after_json,
            al.meta_json,
            al.created_at
        FROM audit_logs al
        WHERE {$whereSql}
        ORDER BY al.created_at DESC, al.audit_log_id DESC
        LIMIT {$rowLimit}
    ");
    $rowsStmt->bind_param($types, ...$params);
    $rowsStmt->execute();
    $result = $rowsStmt->get_result();
    while ($row = $result->fetch_assoc()) {
        $rows[] = $row;
    }
    $rowsStmt->close();
}

$pageTitle = audit_report_text('รายงานตรวจสอบ', 'Audit Report');
$pageDescription = audit_report_text('ตรวจสอบเฉพาะเหตุการณ์สำคัญ เช่น การสร้างบิล รับชำระ ลบการชำระเงิน และการยกเลิกบิล', 'Review only high-impact events such as bill creation, payment collection, payment deletion and void activity.');
$filtersLabel = audit_report_text('ตัวกรองรายงาน', 'Audit filters');
$dateFromLabel = audit_report_text('วันที่เริ่มต้น', 'Date from');
$dateToLabel = audit_report_text('วันที่สิ้นสุด', 'Date to');
$moduleLabel = audit_report_text('โมดูล', 'Module');
$allModulesLabel = audit_report_text('ทุกโมดูล', 'All modules');
$actionLabel = audit_report_text('การกระทำ', 'Action');
$allActionsLabel = audit_report_text('ทุกการกระทำ', 'All actions');
$branchLabel = audit_report_text('สาขา', 'Branch');
$allBranchesLabel = audit_report_text('ทุกสาขา', 'All branches');
$billNumberLabel = audit_report_text('เลขที่บิล', 'Bill no.');
$viewReportLabel = audit_report_text('ดูรายงาน', 'View report');
$resetLabel = audit_report_text('รีเซ็ต', 'Reset');
$logRowsLabel = audit_report_text('จำนวนบันทึก', 'Log rows');
$billEventsLabel = audit_report_text('เหตุการณ์บิล', 'Bill events');
$paymentEventsLabel = audit_report_text('เหตุการณ์ชำระเงิน', 'Payment events');
$voidEventsLabel = audit_report_text('เหตุการณ์ยกเลิกบิล', 'Void events');
$affectedAmountLabel = audit_report_text('ยอดเงินที่ได้รับผลกระทบ', 'Affected amount');
$loadPromptLabel = audit_report_text('กดดูรายงานเพื่อโหลดข้อมูล audit log', 'Click View report to load audit log data.');
$auditTrailLabel = audit_report_text('รายการเหตุการณ์', 'Audit trail');
$auditTrailHelperLabel = audit_report_text(
    count($rows) . ' รายการ เรียงจากใหม่ไปเก่า' . (count($rows) >= $rowLimit ? ' / แสดงสูงสุด ' . $rowLimit . ' รายการแรก' : ''),
    count($rows) . ' record(s), newest first' . (count($rows) >= $rowLimit ? ' / showing first ' . $rowLimit . ' rows' : '')
);
$emptyRowsLabel = audit_report_text('ไม่พบ audit log ตามตัวกรองที่เลือก', 'No audit log found for this filter.');
$dateLabel = audit_report_text('วันที่', 'Date');
$userLabel = audit_report_text('ผู้ใช้งาน', 'User');
$amountLabel = audit_report_text('จำนวนเงิน', 'Amount');
$summaryLabel = audit_report_text('สรุป', 'Summary');
$viewDetailsLabel = audit_report_text('ดูรายละเอียด', 'View details');
$beforeLabel = audit_report_text('ก่อนเปลี่ยน', 'Before');
$afterLabel = audit_report_text('หลังเปลี่ยน', 'After');
$metaLabel = audit_report_text('ข้อมูลประกอบ', 'Meta');

render_page_start($pageTitle, 'audit_report', array('translation_buffer' => false));
?>
<section class="hero">
    <div>
        <h1><?= e($pageTitle) ?></h1>
        <p><?= e($pageDescription) ?></p>
    </div>
</section>

<section class="grid-2" style="align-items: start;">
    <form class="card" method="GET">
        <h2 class="section-title"><?= e($filtersLabel) ?></h2>
        <input type="hidden" name="load" value="1">
        <div class="form-grid">
            <label>
                <span><?= e($dateFromLabel) ?></span>
                <input type="date" name="date_from" value="<?= e($dateFrom) ?>">
            </label>
            <label>
                <span><?= e($dateToLabel) ?></span>
                <input type="date" name="date_to" value="<?= e($dateTo) ?>">
            </label>
            <label>
                <span><?= e($moduleLabel) ?></span>
                <select name="module">
                    <option value=""><?= e($allModulesLabel) ?></option>
                    <?php foreach ($moduleOptions as $moduleKey => $moduleLabelText): ?>
                        <option value="<?= e($moduleKey) ?>"<?= $moduleFilter === $moduleKey ? ' selected' : '' ?>><?= e($moduleLabelText) ?></option>
                    <?php endforeach; ?>
                </select>
            </label>
            <label>
                <span><?= e($actionLabel) ?></span>
                <select name="action">
                    <option value=""><?= e($allActionsLabel) ?></option>
                    <?php foreach ($actionOptions as $actionKey => $actionLabelText): ?>
                        <option value="<?= e($actionKey) ?>"<?= $actionFilter === $actionKey ? ' selected' : '' ?>><?= e($actionLabelText) ?></option>
                    <?php endforeach; ?>
                </select>
            </label>
            <label>
                <span><?= e($branchLabel) ?></span>
                <select name="branch_name">
                    <option value=""><?= e($allBranchesLabel) ?></option>
                    <?php foreach ($branchOptions as $branchName): ?>
                        <option value="<?= e($branchName) ?>"<?= $branchFilter === $branchName ? ' selected' : '' ?>><?= e($branchName) ?></option>
                    <?php endforeach; ?>
                </select>
            </label>
            <label>
                <span><?= e($billNumberLabel) ?></span>
                <input type="text" name="bill_number" value="<?= e($billFilter) ?>" placeholder="SRN052026/0033">
            </label>
        </div>
        <div class="button-row" style="margin-top: 16px;">
            <button class="button" type="submit"><?= e($viewReportLabel) ?></button>
            <a class="button button-secondary" href="audit_report.php"><?= e($resetLabel) ?></a>
        </div>
    </form>

    <?php if ($shouldLoadReport): ?>
        <div class="stats-grid">
            <article class="stat-card">
                <span class="stat-label"><?= e($logRowsLabel) ?></span>
                <strong class="stat-value"><?= number_format((int) ($summary['total_logs'] ?? 0)) ?></strong>
            </article>
            <article class="stat-card">
                <span class="stat-label"><?= e($billEventsLabel) ?></span>
                <strong class="stat-value"><?= number_format((int) ($summary['bill_logs'] ?? 0)) ?></strong>
            </article>
            <article class="stat-card">
                <span class="stat-label"><?= e($paymentEventsLabel) ?></span>
                <strong class="stat-value"><?= number_format((int) ($summary['payment_logs'] ?? 0)) ?></strong>
            </article>
            <article class="stat-card">
                <span class="stat-label"><?= e($voidEventsLabel) ?></span>
                <strong class="stat-value"><?= number_format((int) ($summary['void_logs'] ?? 0)) ?></strong>
            </article>
            <article class="stat-card" style="grid-column: 1 / -1;">
                <span class="stat-label"><?= e($affectedAmountLabel) ?></span>
                <strong class="stat-value"><?= format_money((float) ($summary['affected_amount'] ?? 0)) ?></strong>
            </article>
        </div>
    <?php else: ?>
        <div class="card">
            <div class="empty-state"><?= e($loadPromptLabel) ?></div>
        </div>
    <?php endif; ?>
</section>

<?php if ($shouldLoadReport): ?>
    <section class="table-card" style="margin-top: 18px;">
        <div class="section-head" style="padding: 18px 18px 0;">
            <div>
                <h2 class="section-title"><?= e($auditTrailLabel) ?></h2>
                <p class="helper"><?= e($auditTrailHelperLabel) ?></p>
            </div>
        </div>

        <?php if (empty($rows)): ?>
            <div class="empty-state" style="margin: 18px;"><?= e($emptyRowsLabel) ?></div>
        <?php else: ?>
            <table>
                <thead>
                <tr>
                    <th><?= e($dateLabel) ?></th>
                    <th><?= e($moduleLabel) ?></th>
                    <th><?= e($actionLabel) ?></th>
                    <th><?= e($billNumberLabel) ?></th>
                    <th><?= e($branchLabel) ?></th>
                    <th><?= e($userLabel) ?></th>
                    <th><?= e($amountLabel) ?></th>
                    <th><?= e($summaryLabel) ?></th>
                </tr>
                </thead>
                <tbody>
                <?php foreach ($rows as $row): ?>
                    <?php
                    $before = audit_report_decode($row['before_json'] ?? null);
                    $after = audit_report_decode($row['after_json'] ?? null);
                    $meta = audit_report_decode($row['meta_json'] ?? null);
                    $beforeLines = audit_report_flatten($before);
                    $afterLines = audit_report_flatten($after);
                    $metaLines = audit_report_flatten($meta);
                    ?>
                    <tr>
                        <td><?= e(format_datetime((string) ($row['created_at'] ?? ''))) ?></td>
                        <td><?= e($moduleOptions[(string) ($row['module_key'] ?? '')] ?? (string) ($row['module_key'] ?? '-')) ?></td>
                        <td><?= e($actionOptions[(string) ($row['action_key'] ?? '')] ?? (string) ($row['action_key'] ?? '-')) ?></td>
                        <td><?= e((string) ($row['bill_number'] ?? '-')) ?></td>
                        <td><?= e((string) ($row['branch_name'] ?? '-')) ?></td>
                        <td><?= e((string) ($row['actor_name'] ?? '-')) ?></td>
                        <td><?= $row['amount'] !== null ? format_money((float) $row['amount']) : '-' ?></td>
                        <td>
                            <div class="stack">
                                <strong><?= e(translate_text((string) ($row['message'] ?? '-'))) ?></strong>
                                <?php if (!empty($beforeLines) || !empty($afterLines) || !empty($metaLines)): ?>
                                    <details class="audit-log-details">
                                        <summary><?= e($viewDetailsLabel) ?></summary>
                                        <?php if (!empty($beforeLines)): ?>
                                            <div class="audit-log-block">
                                                <strong><?= e($beforeLabel) ?></strong>
                                                <div class="audit-log-lines">
                                                    <?php foreach ($beforeLines as $line): ?>
                                                        <span><?= e(translate_text($line)) ?></span>
                                                    <?php endforeach; ?>
                                                </div>
                                            </div>
                                        <?php endif; ?>
                                        <?php if (!empty($afterLines)): ?>
                                            <div class="audit-log-block">
                                                <strong><?= e($afterLabel) ?></strong>
                                                <div class="audit-log-lines">
                                                    <?php foreach ($afterLines as $line): ?>
                                                        <span><?= e(translate_text($line)) ?></span>
                                                    <?php endforeach; ?>
                                                </div>
                                            </div>
                                        <?php endif; ?>
                                        <?php if (!empty($metaLines)): ?>
                                            <div class="audit-log-block">
                                                <strong><?= e($metaLabel) ?></strong>
                                                <div class="audit-log-lines">
                                                    <?php foreach ($metaLines as $line): ?>
                                                        <span><?= e(translate_text($line)) ?></span>
                                                    <?php endforeach; ?>
                                                </div>
                                            </div>
                                        <?php endif; ?>
                                    </details>
                                <?php endif; ?>
                            </div>
                        </td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        <?php endif; ?>
    </section>
<?php endif; ?>

<?php render_page_end(); ?>
