<?php
/**
 * Upload data to a report. Pure file-upload form + run ReportEngine.
 */
require_once __DIR__ . '/../includes/config.php';
require_once __DIR__ . '/../includes/report-engine.php';

$me = require_login('internal');
$pdo = db();

$reportId = (int) ($_GET['report_id'] ?? $_POST['report_id'] ?? 0);
if (!$reportId) { flash('error','report_id missing.'); redirect('/admin/reports.php'); }
require_report_access($reportId);   // can only upload to a report they're granted

$stmt = $pdo->prepare('SELECT r.*, p.name AS process_name, c.name AS client_name
    FROM reports r JOIN processes p ON p.id = r.process_id JOIN clients c ON c.id = p.client_id
    WHERE r.id=? AND r.deleted_at IS NULL');
$stmt->execute([$reportId]);
$report = $stmt->fetch();
if (!$report) { flash('error','Report not found.'); redirect('/admin/report-builder.php'); }

$result = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_check_or_die();
    $mode = in_array($_POST['mode'] ?? '', ['append','replace_all','replace_by_period','upsert'], true)
            ? $_POST['mode'] : $report['upload_strategy'];

    if ($mode === 'replace_all' && (string)($_POST['confirm'] ?? '') !== 'DELETE') {
        flash('error', 'You must type DELETE to confirm a Replace All operation.');
        redirect("/admin/upload.php?report_id=$reportId&mode=replace_all");
    }
    if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
        flash('error', 'No file uploaded or upload error.');
        redirect("/admin/upload.php?report_id=$reportId&mode=$mode");
    }

    $tmp = $_FILES['file']['tmp_name'];
    $name = $_FILES['file']['name'];
    $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
    if (!in_array($ext, UPLOAD_ALLOWED_EXT, true)) {
        flash('error', "File extension '.$ext' not allowed. Use: " . implode(', ', UPLOAD_ALLOWED_EXT));
        redirect("/admin/upload.php?report_id=$reportId");
    }
    if ($_FILES['file']['size'] > UPLOAD_MAX_BYTES) {
        flash('error', 'File too large.');
        redirect("/admin/upload.php?report_id=$reportId");
    }

    $uploadsDir = __DIR__ . "/../storage/uploads/$reportId";
    if (!is_dir($uploadsDir)) mkdir($uploadsDir, 0755, true);
    $safeName = date('YmdHis') . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
    $dest = $uploadsDir . '/' . $safeName;
    if (!move_uploaded_file($tmp, $dest)) {
        flash('error', 'Failed to save uploaded file.');
        redirect("/admin/upload.php?report_id=$reportId");
    }

    // Pre-flight extension check
    $extNeeded = $ext === 'csv' ? ['mbstring'] : ['zip','mbstring'];
    $extMiss = array_filter($extNeeded, fn($x) => !extension_loaded($x));
    if ($extMiss) {
        @unlink($dest);
        flash('error', 'Missing PHP extension(s): ' . implode(', ', $extMiss)
            . '. Run enable-php-extensions.bat (as administrator) and restart Apache.');
        redirect("/admin/upload.php?report_id=$reportId");
    }

    try {
        $engine = new ReportEngine($reportId);
        $result = $engine->ingest($dest, $mode, (int)$me['id']);
        audit_log('report.upload', 'report', $reportId, null, $result);
        flash('success', sprintf('Upload complete: %d valid, %d errors, %d total.',
            $result['valid'], $result['errors'], $result['total']));
        redirect("/admin/report-view.php?id=$reportId&upload=" . $result['upload_id']);
    } catch (Throwable $t) {
        $msg = $t->getMessage();
        if (str_contains($msg, 'ZipArchive')) {
            $msg = 'PHP zip extension is not enabled in the Apache-loaded php.ini. Run enable-php-extensions.bat (as administrator), then RESTART Apache from XAMPP Control Panel, then try again.';
        } elseif (str_contains($msg, 'max_allowed_packet')) {
            $msg = 'MySQL packet size too small. Open C:\\xampp\\mysql\\bin\\my.ini, find [mysqld], add max_allowed_packet=64M, save, then restart MySQL from the XAMPP Control Panel. (See sql/fix-max-packet.sql for a quick reference.)';
        }
        flash('error', 'Ingestion failed: ' . $msg);
        redirect("/admin/upload.php?report_id=$reportId");
    }
}

$cols = $pdo->prepare('SELECT * FROM report_columns WHERE report_id=? ORDER BY col_order');
$cols->execute([$reportId]); $cols = $cols->fetchAll();

$history = $pdo->prepare('SELECT u.*, usr.name AS user_name FROM report_uploads u
    LEFT JOIN users usr ON usr.id = u.uploaded_by
    WHERE u.report_id=? ORDER BY u.created_at DESC LIMIT 20');
$history->execute([$reportId]); $history = $history->fetchAll();

/* ---------- Pre-flight check for required PHP extensions ---------- */
$requiredExt = ['zip','fileinfo','mbstring'];
$missingExt = [];
foreach ($requiredExt as $ext) {
    if (!extension_loaded($ext)) $missingExt[] = $ext;
}
$phpIniPath = php_ini_loaded_file() ?: '(unknown)';

$presetMode = $_GET['mode'] ?? '';
if (!in_array($presetMode, ['append','replace_all','replace_by_period','upsert'], true)) $presetMode = $report['upload_strategy'];

$modeMeta = [
    'append'            => ['title'=>'Append data',          'cls'=>'success', 'icon'=>'plus',   'desc'=>'Adds new rows to the existing dataset. No existing data is removed.'],
    'replace_by_period' => ['title'=>'Replace by Period',    'cls'=>'warning', 'icon'=>'refresh','desc'=>'Wipes only rows for the periods detected in your uploaded file. All other periods stay untouched.'],
    'replace_all'       => ['title'=>'Replace ALL data',     'cls'=>'danger',  'icon'=>'trash',  'desc'=>'Wipes the entire dataset and loads fresh. Current data is auto-archived for restore.'],
    'upsert'            => ['title'=>'Upsert (update or insert)', 'cls'=>'info',    'icon'=>'edit',   'desc'=>'For each row, updates if a row with the same unique-key already exists; otherwise inserts.'],
];
$pageTitle = 'Upload data';
require __DIR__ . '/../includes/header.php';
?>
<div class="page-header"><div class="container-xl">
    <a href="<?= e(url('/admin/report-builder.php')) ?>" class="text-secondary"><i class="ti ti-chevron-left"></i> Reports</a>
    <h2 class="page-title">Upload data &mdash; <?= e($report['name']) ?></h2>
    <div class="text-secondary"><?= e($report['client_name']) ?> &raquo; <?= e($report['process_name']) ?></div>
</div></div>

<div class="page-body"><div class="container-xl"><div class="row">
<div class="col-md-7">
    <?php if ($missingExt): ?>
        <div class="alert alert-danger mb-3">
            <h4 class="alert-heading"><i class="ti ti-alert-octagon me-2"></i>Cannot upload &mdash; required PHP extension(s) missing</h4>
            <p class="mb-2">The following PHP extension(s) need to be enabled in <code><?= e($phpIniPath) ?></code>:</p>
            <ul class="mb-3">
                <?php foreach ($missingExt as $x): ?>
                    <li><code>extension=<?= e($x) ?></code> &mdash; remove the leading <code>;</code> to enable</li>
                <?php endforeach; ?>
            </ul>
            <h5>Fix in 3 clicks:</h5>
            <ol class="mb-2">
                <li>Right-click <code>enable-php-extensions.bat</code> in the project folder &rarr; <strong>Run as administrator</strong></li>
                <li>Open <strong>XAMPP Control Panel</strong> &rarr; click <strong>Stop</strong> next to Apache, then <strong>Start</strong></li>
                <li>Refresh this page</li>
            </ol>
            <p class="mb-0 small">
                <strong>Why:</strong> the .xlsx format is a zip archive; PHP needs the <code>zip</code> extension to read it.
                XAMPP has it installed but disabled by default. Apache caches php.ini at startup, so Apache must be restarted after enabling.
            </p>
        </div>
    <?php endif; ?>

    <?php $m = $modeMeta[$presetMode]; ?>
    <div class="alert alert-<?= $m['cls'] ?> py-2 mb-3"><i class="ti ti-<?= $m['icon'] ?> me-2"></i>
        <strong><?= e($m['title']) ?>:</strong> <?= e($m['desc']) ?>
        <?php if ($presetMode === 'replace_all'): ?><br><strong class="text-danger">Current data will be archived &mdash; you can restore it later from History.</strong><?php endif; ?>
    </div>

    <div class="card mb-3"><div class="card-header py-2"><h3 class="card-title small mb-0">Upload file</h3></div>
        <form method="POST" enctype="multipart/form-data" class="card-body">
            <?= csrf_field() ?>
            <input type="hidden" name="report_id" value="<?= $reportId ?>">
            <div class="mb-3">
                <label class="form-label required">File (.xlsx, .xls, .csv)</label>
                <input type="file" name="file" accept=".xlsx,.xls,.csv" class="form-control" required>
                <div class="form-hint">Max <?= number_format(UPLOAD_MAX_BYTES/1024/1024) ?> MB.</div>
            </div>
            <div class="mb-3">
                <label class="form-label">Upload mode</label>
                <div class="btn-group w-100" role="group">
                    <?php foreach (['append','replace_by_period','upsert','replace_all'] as $mk):
                        $mm = $modeMeta[$mk]; $sel = $presetMode===$mk; ?>
                        <input type="radio" class="btn-check" name="mode" id="mode_<?= $mk ?>" value="<?= $mk ?>" <?= $sel?'checked':'' ?>>
                        <label class="btn btn-outline-<?= $mm['cls'] ?>" for="mode_<?= $mk ?>"><i class="ti ti-<?= $mm['icon'] ?> me-1"></i><?= e($mm['title']) ?></label>
                    <?php endforeach; ?>
                </div>
            </div>
            <?php if ($presetMode === 'replace_all'): ?>
                <div class="mb-3">
                    <label class="form-label text-danger required">Type DELETE to confirm</label>
                    <input type="text" name="confirm" pattern="DELETE" required class="form-control" placeholder="DELETE">
                </div>
            <?php endif; ?>
            <button class="btn btn-<?= $m['cls'] ?>"><i class="ti ti-upload me-1"></i>Upload and process (<?= e($m['title']) ?>)</button>
        </form>
    </div>

    <div class="card"><div class="card-header"><h3 class="card-title">Recent uploads</h3></div>
        <table class="table card-table">
            <thead><tr><th>When</th><th>By</th><th>Mode</th><th>Rows</th><th>Status</th><th></th></tr></thead>
            <tbody>
                <?php if (!$history): ?>
                    <tr><td colspan="6" class="text-secondary text-center py-3">No uploads yet.</td></tr>
                <?php else: foreach ($history as $h): ?>
                    <tr>
                        <td class="small text-secondary"><?= e($h['created_at']) ?></td>
                        <td><?= e($h['user_name'] ?? '--') ?></td>
                        <td><span class="badge bg-secondary-lt"><?= e($h['upload_mode_used']) ?></span></td>
                        <td>
                            <?= (int)$h['valid_rows'] ?> ok
                            <?php if ($h['error_rows']): ?> / <span class="text-danger"><?= (int)$h['error_rows'] ?> err</span><?php endif; ?>
                        </td>
                        <td>
                            <?php $cls = ['completed'=>'success','failed'=>'danger','processing'=>'info','pending'=>'warning','archived'=>'secondary'][$h['status']] ?? 'secondary'; ?>
                            <span class="badge bg-<?= $cls ?>-lt"><?= e($h['status']) ?></span>
                        </td>
                        <td>
                            <?php if ($h['status']==='completed'): ?>
                                <a href="<?= e(url('/admin/report-view.php?id='.$reportId.'&upload='.$h['id'])) ?>" class="btn btn-sm" title="View"><i class="ti ti-eye"></i></a>
                                <form method="POST" action="<?= e(url('/admin/restore.php')) ?>" style="display:inline"
                                      onsubmit="return confirm('Restore this snapshot? Current data will be archived.');">
                                    <?= csrf_field() ?>
                                    <input type="hidden" name="report_id" value="<?= $reportId ?>">
                                    <input type="hidden" name="upload_id" value="<?= $h['id'] ?>">
                                    <button class="btn btn-sm btn-ghost-warning" title="Restore this snapshot"><i class="ti ti-history"></i></button>
                                </form>
                            <?php endif; ?>
                        </td>
                    </tr>
                <?php endforeach; endif; ?>
            </tbody>
        </table>
    </div>
</div>

<div class="col-md-5">
    <div class="card"><div class="card-header"><h3 class="card-title">Expected columns (<?= count($cols) ?>)</h3></div>
        <div class="card-body p-0"><table class="table card-table table-sm">
            <thead><tr><th>#</th><th>Label (header in file)</th><th>Type</th></tr></thead>
            <tbody>
                <?php foreach ($cols as $c): ?>
                    <tr>
                        <td><?= (int)$c['col_order'] ?></td>
                        <td>
                            <strong><?= e($c['col_label']) ?></strong>
                            <?php if ($c['is_required']): ?> <span class="badge bg-red-lt">req</span><?php endif; ?>
                            <?php if ($c['is_period_col']): ?> <span class="badge bg-yellow-lt">period</span><?php endif; ?>
                            <?php if ($c['is_key_col']): ?> <span class="badge bg-purple-lt">key</span><?php endif; ?>
                        </td>
                        <td><span class="badge bg-secondary-lt"><?= e($c['data_type']) ?></span></td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table></div>
    </div>
    <div class="alert alert-info mt-3 small">
        <strong>Tip:</strong> Header row of your file must match the labels above (case insensitive). Extra columns are ignored. Missing required columns will fail every row.
    </div>
</div>
</div></div></div>
<?php require __DIR__ . '/../includes/footer.php'; ?>
