<?php
/**
 * SIPIUTANG — Wizard Instalasi
 *
 * Berkas mandiri (tanpa dependensi aplikasi) yang memandu pemasangan di
 * shared hosting / cPanel dalam 5 langkah:
 *   1. Pemeriksaan kebutuhan sistem
 *   2. Konfigurasi basis data
 *   3. Pemasangan skema & data
 *   4. Pembuatan akun administrator
 *   5. Selesai & pengamanan
 *
 * Setelah instalasi selesai, folder /install WAJIB dihapus.
 */
declare(strict_types=1);

@set_time_limit(0);
@ini_set('memory_limit', '512M');
error_reporting(E_ALL);
ini_set('display_errors', '1');
session_start();

define('ROOT', dirname(__DIR__));
define('CONFIG_FILE', ROOT . '/config/config.php');
define('LOCK_FILE', ROOT . '/storage/.installed');

const MIN_PHP = '8.1.0';

$step   = max(1, min(5, (int)($_GET['langkah'] ?? 1)));
$errors = [];
$notice = null;

/* ------------------------------------------------------------------ util */

function h($v): string { return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
function post(string $k, string $d = ''): string { return trim((string)($_POST[$k] ?? $d)); }
function sess(string $k, $d = null) { return $_SESSION['inst'][$k] ?? $d; }
function setSess(string $k, $v): void { $_SESSION['inst'][$k] = $v; }
function urlLangkah(int $n): string { return '?langkah=' . $n; }

function ukuran(int $b): string
{
    $u = ['B', 'KB', 'MB', 'GB'];
    $i = 0;
    while ($b >= 1024 && $i < 3) { $b /= 1024; $i++; }
    return number_format($b, $i ? 1 : 0, ',', '.') . ' ' . $u[$i];
}

function iniBytes(string $key): int
{
    $v = trim((string)ini_get($key));
    if ($v === '' || $v === '-1') return PHP_INT_MAX;
    $unit = strtolower(substr($v, -1));
    $n = (int)$v;
    return match ($unit) { 'g' => $n * 1024 ** 3, 'm' => $n * 1024 ** 2, 'k' => $n * 1024, default => $n };
}

/** Daftar pemeriksaan kebutuhan sistem. */
function pemeriksaan(): array
{
    $c = [];
    $c[] = ['Versi PHP >= ' . MIN_PHP, PHP_VERSION, version_compare(PHP_VERSION, MIN_PHP, '>='), true,
            'Naikkan versi PHP melalui menu "MultiPHP Manager" di cPanel.'];
    foreach (['pdo_mysql' => true, 'mbstring' => true, 'zip' => true, 'json' => true,
              'openssl' => true, 'fileinfo' => true, 'gd' => false, 'intl' => false] as $ext => $wajib) {
        $c[] = ['Ekstensi ' . $ext, extension_loaded($ext) ? 'aktif' : 'tidak aktif',
                extension_loaded($ext), $wajib,
                'Aktifkan melalui menu "Select PHP Version → Extensions" di cPanel.'];
    }
    $c[] = ['Fungsi XMLReader', class_exists('XMLReader') ? 'tersedia' : 'tidak ada',
            class_exists('XMLReader'), true, 'Dibutuhkan untuk membaca berkas Excel (.xlsx).'];

    $mem = iniBytes('memory_limit');
    $c[] = ['Batas memori >= 128 MB', ini_get('memory_limit'), $mem >= 128 * 1024 ** 2, false,
            'Tambahkan "memory_limit = 256M" pada berkas .htaccess atau php.ini.'];
    $up = iniBytes('upload_max_filesize');
    $c[] = ['Ukuran unggah >= 16 MB', ini_get('upload_max_filesize'), $up >= 16 * 1024 ** 2, false,
            'Diperlukan untuk mengunggah berkas Excel besar.'];
    $ex = (int)ini_get('max_execution_time');
    $c[] = ['Batas waktu eksekusi >= 120 detik', $ex === 0 ? 'tanpa batas' : $ex . ' detik',
            $ex === 0 || $ex >= 120, false, 'Import data dalam jumlah besar membutuhkan waktu lebih lama.'];

    foreach (['config' => ROOT . '/config', 'storage' => ROOT . '/storage',
              'storage/uploads' => ROOT . '/storage/uploads', 'storage/exports' => ROOT . '/storage/exports',
              'storage/logs' => ROOT . '/storage/logs', 'storage/backups' => ROOT . '/storage/backups',
              'storage/tmp' => ROOT . '/storage/tmp'] as $label => $dir) {
        if (!is_dir($dir)) @mkdir($dir, 0755, true);
        $c[] = ['Folder ' . $label . ' dapat ditulis', is_writable($dir) ? 'dapat ditulis' : 'hanya baca',
                is_writable($dir), true,
                'Ubah izin folder menjadi 755 (atau 775) melalui File Manager cPanel.'];
    }
    $c[] = ['Berkas skema basis data', is_file(ROOT . '/database/01_schema.sql') ? 'ditemukan' : 'tidak ada',
            is_file(ROOT . '/database/01_schema.sql'), true, 'Pastikan folder /database ikut terunggah.'];
    return $c;
}

/** Membuka koneksi PDO ke server basis data. */
function koneksi(array $d, bool $withDb = true): PDO
{
    $dsn = "mysql:host={$d['host']};port={$d['port']}" . ($withDb ? ";dbname={$d['database']}" : '') . ';charset=utf8mb4';
    return new PDO($dsn, $d['username'], $d['password'], [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ]);
}

/**
 * Menjalankan berkas SQL besar baris demi baris (hemat memori),
 * menghormati tanda kutip dan komentar.
 */
function jalankanSql(PDO $pdo, string $file, ?callable $progress = null): int
{
    $fh = fopen($file, 'rb');
    if (!$fh) throw new RuntimeException("Tidak dapat membuka berkas SQL: " . basename($file));

    $buffer = '';
    $inStr = false; $q = ''; $n = 0;
    while (($line = fgets($fh)) !== false) {
        $t = ltrim($line);
        if (!$inStr && ($t === '' || str_starts_with($t, '--') || str_starts_with($t, '#')
                        || (str_starts_with($t, '/*') && str_ends_with(rtrim($t), '*/')))) {
            continue;
        }
        $len = strlen($line);
        for ($i = 0; $i < $len; $i++) {
            $ch = $line[$i];
            $buffer .= $ch;
            if ($inStr) {
                if ($ch === '\\' && $i + 1 < $len) { $buffer .= $line[++$i]; continue; }
                if ($ch === $q) $inStr = false;
                continue;
            }
            if ($ch === "'" || $ch === '"' || $ch === '`') { $inStr = true; $q = $ch; continue; }
            if ($ch === ';') {
                $sql = trim($buffer);
                $buffer = '';
                if ($sql !== '' && $sql !== ';') {
                    $pdo->exec($sql);
                    $n++;
                    if ($progress && $n % 200 === 0) $progress($n);
                }
            }
        }
    }
    fclose($fh);
    $sisa = trim($buffer);
    if ($sisa !== '' && $sisa !== ';') { $pdo->exec($sisa); $n++; }
    return $n;
}

function tulisConfig(array $db, array $app): bool
{
    $tpl = <<<'PHP'
<?php
/**
 * SIPIUTANG - Berkas Konfigurasi
 * Dibuat otomatis oleh wizard instalasi pada {TANGGAL}.
 * Jangan bagikan berkas ini; berisi kredensial basis data.
 */
return [
    'db' => [
        'host'     => '{HOST}',
        'port'     => {PORT},
        'database' => '{DBNAME}',
        'username' => '{DBUSER}',
        'password' => '{DBPASS}',
        'charset'  => 'utf8mb4',
    ],
    'app' => [
        'base_url'     => '{BASEURL}',
        'timezone'     => 'Asia/Jakarta',
        'locale'       => 'id_ID',
        'env'          => '{ENV}',
        'debug'        => {DEBUG},
        'key'          => '{KEY}',
        'session_name' => 'sipiutang_session',
    ],
    'paths' => [
        'storage' => dirname(__DIR__) . '/storage',
        'uploads' => dirname(__DIR__) . '/storage/uploads',
        'exports' => dirname(__DIR__) . '/storage/exports',
        'logs'    => dirname(__DIR__) . '/storage/logs',
        'tmp'     => dirname(__DIR__) . '/storage/tmp',
        'backups' => dirname(__DIR__) . '/storage/backups',
    ],
];
PHP;
    $out = strtr($tpl, [
        '{TANGGAL}' => date('d-m-Y H:i'),
        '{HOST}'    => addslashes($db['host']),
        '{PORT}'    => (string)(int)$db['port'],
        '{DBNAME}'  => addslashes($db['database']),
        '{DBUSER}'  => addslashes($db['username']),
        '{DBPASS}'  => addslashes($db['password']),
        '{BASEURL}' => addslashes($app['base_url']),
        '{ENV}'     => $app['env'],
        '{DEBUG}'   => $app['debug'] ? 'true' : 'false',
        '{KEY}'     => $app['key'],
    ]);
    return (bool)@file_put_contents(CONFIG_FILE, $out, LOCK_EX);
}

/* --------------------------------------------------------------- routing */

$sudahTerpasang = is_file(LOCK_FILE) && is_file(CONFIG_FILE);
if ($sudahTerpasang && !isset($_GET['paksa'])) $step = 5;

// ---- Langkah 2: uji koneksi & simpan
if ($step === 2 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    $db = ['host' => post('host', 'localhost'), 'port' => (int)(post('port', '3306') ?: 3306),
           'database' => post('database'), 'username' => post('username'), 'password' => (string)($_POST['password'] ?? '')];
    $buatDb = isset($_POST['buat_database']);

    if ($db['database'] === '') $errors[] = 'Nama basis data wajib diisi.';
    if ($db['username'] === '') $errors[] = 'Nama pengguna basis data wajib diisi.';

    if (!$errors) {
        try {
            try {
                $pdo = koneksi($db);
            } catch (PDOException $e) {
                if ($buatDb && (int)$e->getCode() === 1049) {
                    $root = koneksi($db, false);
                    $root->exec('CREATE DATABASE `' . str_replace('`', '', $db['database'])
                                . '` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
                    $pdo = koneksi($db);
                    $notice = 'Basis data "' . $db['database'] . '" berhasil dibuat.';
                } else {
                    throw $e;
                }
            }
            $versi = (string)$pdo->query('SELECT VERSION()')->fetchColumn();
            $angka = preg_replace('/[^0-9.].*$/', '', $versi);
            $mariadb = stripos($versi, 'mariadb') !== false;
            if ($mariadb ? version_compare($angka, '10.4', '<') : version_compare($angka, '5.7', '<')) {
                $errors[] = 'Versi server basis data ' . $versi
                          . ' terlalu lama. Dibutuhkan MySQL 5.7+ atau MariaDB 10.4+.';
            } else {
                setSess('db', $db);
                setSess('db_versi', $versi);
                header('Location: ' . urlLangkah(3));
                exit;
            }
        } catch (Throwable $e) {
            $errors[] = 'Koneksi gagal: ' . $e->getMessage();
        }
    }
}

// ---- Langkah 3: pasang skema & data
if ($step === 3 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    $db = sess('db');
    if (!$db) { header('Location: ' . urlLangkah(2)); exit; }
    $mode = post('mode', 'demo');   // demo | kosong
    try {
        $pdo = koneksi($db);
        $ada = (int)$pdo->query("SELECT COUNT(*) FROM information_schema.tables
                                  WHERE table_schema = DATABASE() AND table_name = 'invoices'")->fetchColumn();
        if ($ada && !isset($_POST['timpa'])) {
            $errors[] = 'Basis data sudah berisi tabel SIPIUTANG. Centang "Timpa struktur yang ada" '
                      . 'bila Anda yakin ingin memasang ulang (SELURUH DATA LAMA AKAN HILANG).';
        } else {
            $pdo->exec('SET FOREIGN_KEY_CHECKS = 0');
            $t0 = microtime(true);
            $n = jalankanSql($pdo, ROOT . '/database/01_schema.sql');
            $n += jalankanSql($pdo, ROOT . '/database/02_seed_master.sql');
            $pesanData = 'struktur & data master';
            if ($mode === 'demo' && is_file(ROOT . '/database/03_seed_data.sql')) {
                $n += jalankanSql($pdo, ROOT . '/database/03_seed_data.sql');
                $pesanData = 'struktur, data master, dan data contoh';
            }
            $pdo->exec('SET FOREIGN_KEY_CHECKS = 1');
            $detik = round(microtime(true) - $t0, 1);

            $jml = (int)$pdo->query('SELECT COUNT(*) FROM invoices')->fetchColumn();
            setSess('pasang', ['perintah' => $n, 'detik' => $detik, 'invoice' => $jml, 'mode' => $mode]);
            setSess('pesan_data', $pesanData);
            header('Location: ' . urlLangkah(4));
            exit;
        }
    } catch (Throwable $e) {
        $errors[] = 'Pemasangan gagal: ' . $e->getMessage();
    }
}

// ---- Langkah 4: akun administrator + tulis config
if ($step === 4 && $_SERVER['REQUEST_METHOD'] === 'POST') {
    $db = sess('db');
    if (!$db) { header('Location: ' . urlLangkah(2)); exit; }

    $nama  = post('nama');
    $user  = strtolower(preg_replace('/[^A-Za-z0-9_.]/', '', post('username')));
    $email = post('email');
    $pass  = (string)($_POST['password'] ?? '');
    $pass2 = (string)($_POST['password2'] ?? '');
    $perusahaan = post('perusahaan', 'PT Roto-Rooter Indonesia');
    $baseUrl = rtrim(post('base_url'), '/');
    $hapusDemo = isset($_POST['hapus_akun_demo']);

    if ($nama === '')  $errors[] = 'Nama lengkap administrator wajib diisi.';
    if (strlen($user) < 4) $errors[] = 'Nama pengguna minimal 4 karakter (huruf, angka, titik, garis bawah).';
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Alamat email tidak valid.';
    if (strlen($pass) < 8) $errors[] = 'Kata sandi minimal 8 karakter.';
    if (!preg_match('/[A-Z]/', $pass) || !preg_match('/[a-z]/', $pass) || !preg_match('/[0-9]/', $pass)) {
        $errors[] = 'Kata sandi harus memuat huruf besar, huruf kecil, dan angka.';
    }
    if ($pass !== $pass2) $errors[] = 'Konfirmasi kata sandi tidak sama.';

    if (!$errors) {
        try {
            $pdo = koneksi($db);
            $hash = password_hash($pass, PASSWORD_BCRYPT, ['cost' => 12]);

            $ada = $pdo->prepare('SELECT id FROM users WHERE username = ?');
            $ada->execute([$user]);
            $idAda = $ada->fetchColumn();

            if ($idAda) {
                $st = $pdo->prepare('UPDATE users SET name=?, email=?, password_hash=?, role_id=1,
                                     must_change_password=0, is_active=1, password_changed_at=NOW() WHERE id=?');
                $st->execute([$nama, $email, $hash, $idAda]);
                $adminId = (int)$idAda;
            } else {
                $st = $pdo->prepare('INSERT INTO users (username, name, email, password_hash, role_id,
                                     must_change_password, is_active, password_changed_at)
                                     VALUES (?,?,?,?,1,0,1,NOW())');
                $st->execute([$user, $nama, $email, $hash]);
                $adminId = (int)$pdo->lastInsertId();
                $pdo->prepare('INSERT IGNORE INTO user_roles (user_id, role_id) VALUES (?,1)')->execute([$adminId]);
            }

            if ($hapusDemo) {
                $pdo->exec("UPDATE users SET is_active = 0
                             WHERE username IN ('superadmin','finance','collection','sales','manajemen','auditor')
                               AND id <> " . $adminId);
            }

            $st = $pdo->prepare('UPDATE application_settings SET setting_value = ? WHERE setting_key = ?');
            $st->execute([$perusahaan, 'nama_perusahaan']);

            $ok = tulisConfig($db, [
                'base_url' => $baseUrl,
                'env'      => 'production',
                'debug'    => false,
                'key'      => bin2hex(random_bytes(16)),
            ]);
            if (!$ok) {
                $errors[] = 'Gagal menulis berkas config/config.php. Pastikan folder config dapat ditulis (izin 755).';
            } else {
                @file_put_contents(LOCK_FILE, date('c') . PHP_EOL . 'versi=1.0.0' . PHP_EOL);
                setSess('admin', ['username' => $user, 'nama' => $nama]);
                setSess('base_url', $baseUrl);
                setSess('demo_nonaktif', $hapusDemo);
                header('Location: ' . urlLangkah(5));
                exit;
            }
        } catch (Throwable $e) {
            $errors[] = 'Pembuatan akun gagal: ' . $e->getMessage();
        }
    }
}

$cek = $step === 1 ? pemeriksaan() : [];
$wajibGagal = 0;
foreach ($cek as $c) if ($c[3] && !$c[2]) $wajibGagal++;

$judulLangkah = [
    1 => 'Pemeriksaan Kebutuhan Sistem',
    2 => 'Konfigurasi Basis Data',
    3 => 'Pemasangan Skema & Data',
    4 => 'Akun Administrator',
    5 => 'Instalasi Selesai',
];
?>
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Instalasi SIPIUTANG — Langkah <?= $step ?> dari 5</title>
<link href="../public/assets/vendor/bootstrap.min.css" rel="stylesheet">
<link href="../public/assets/vendor/bootstrap-icons.css" rel="stylesheet">
<style>
  body{background:#f1f4f9;font-family:'Segoe UI',system-ui,sans-serif}
  .wrap{max-width:900px;margin:32px auto;padding:0 16px}
  .brand{display:flex;align-items:center;gap:12px;margin-bottom:20px}
  .brand-logo{width:46px;height:46px;border-radius:12px;background:linear-gradient(135deg,#0d6efd,#0a58ca);
              color:#fff;display:grid;place-items:center;font-size:22px}
  .card{border:0;box-shadow:0 2px 14px rgba(16,24,40,.08);border-radius:14px}
  .steps{display:flex;gap:6px;margin-bottom:18px;flex-wrap:wrap}
  .steps div{flex:1 1 120px;padding:9px 10px;border-radius:9px;background:#fff;font-size:12.5px;color:#667085;
             border:1px solid #e6e9ef;text-align:center}
  .steps div.on{background:#0d6efd;color:#fff;border-color:#0d6efd;font-weight:600}
  .steps div.done{background:#e7f4ec;color:#146c43;border-color:#c7e6d3}
  table.cek td{vertical-align:middle;font-size:13.5px}
  .hint{font-size:12px;color:#667085}
  code{background:#f1f4f9;padding:1px 5px;border-radius:4px;color:#a5133a}
</style>
</head>
<body>
<div class="wrap">

  <div class="brand">
    <div class="brand-logo"><i class="bi bi-cash-coin"></i></div>
    <div>
      <div class="fw-bold fs-5">SIPIUTANG</div>
      <div class="text-body-secondary" style="font-size:13px">
        Sistem Informasi Piutang, Average Collection Period &amp; Pelaporan Keuangan
      </div>
    </div>
  </div>

  <div class="steps">
    <?php foreach ($judulLangkah as $i => $t): ?>
      <div class="<?= $i === $step ? 'on' : ($i < $step ? 'done' : '') ?>">
        <?= $i < $step ? '<i class="bi bi-check-lg"></i> ' : $i . '. ' ?><?= h($t) ?>
      </div>
    <?php endforeach; ?>
  </div>

  <?php if ($errors): ?>
    <div class="alert alert-danger">
      <div class="fw-semibold mb-1"><i class="bi bi-exclamation-octagon-fill me-1"></i>Terjadi kesalahan:</div>
      <ul class="mb-0 ps-3"><?php foreach ($errors as $e): ?><li><?= h($e) ?></li><?php endforeach; ?></ul>
    </div>
  <?php endif; ?>
  <?php if ($notice): ?>
    <div class="alert alert-success"><i class="bi bi-check-circle-fill me-1"></i><?= h($notice) ?></div>
  <?php endif; ?>

  <div class="card">
    <div class="card-header bg-white py-3">
      <span class="fw-semibold">Langkah <?= $step ?> dari 5 — <?= h($judulLangkah[$step]) ?></span>
    </div>
    <div class="card-body p-4">

<?php if ($step === 1): ?>
      <p class="text-body-secondary">
        Wizard memeriksa apakah server hosting Anda memenuhi kebutuhan minimum SIPIUTANG.
        Baris bertanda <span class="badge bg-danger">Wajib</span> harus terpenuhi sebelum instalasi dapat dilanjutkan.
      </p>
      <div class="table-responsive">
        <table class="table table-sm align-middle cek">
          <thead class="table-light">
            <tr><th style="width:44%">Pemeriksaan</th><th style="width:22%">Hasil</th>
                <th style="width:12%">Status</th><th>Keterangan</th></tr>
          </thead>
          <tbody>
          <?php foreach ($cek as [$label, $nilai, $lulus, $wajib, $saran]): ?>
            <tr class="<?= !$lulus && $wajib ? 'table-danger' : (!$lulus ? 'table-warning' : '') ?>">
              <td><?= h($label) ?> <?= $wajib ? '<span class="badge bg-danger-subtle text-danger-emphasis">Wajib</span>'
                                            : '<span class="badge bg-secondary-subtle text-secondary-emphasis">Opsional</span>' ?></td>
              <td class="font-monospace" style="font-size:12.5px"><?= h($nilai) ?></td>
              <td><?= $lulus ? '<span class="text-success"><i class="bi bi-check-circle-fill"></i> OK</span>'
                             : '<span class="text-danger"><i class="bi bi-x-circle-fill"></i> Gagal</span>' ?></td>
              <td class="hint"><?= $lulus ? '&mdash;' : h($saran) ?></td>
            </tr>
          <?php endforeach; ?>
          </tbody>
        </table>
      </div>
      <div class="d-flex justify-content-between align-items-center mt-3">
        <div class="hint">
          <?= $wajibGagal === 0
              ? '<span class="text-success fw-semibold">Semua kebutuhan wajib terpenuhi.</span>'
              : '<span class="text-danger fw-semibold">' . $wajibGagal . ' kebutuhan wajib belum terpenuhi.</span>' ?>
        </div>
        <div>
          <a class="btn btn-outline-secondary" href="<?= urlLangkah(1) ?>"><i class="bi bi-arrow-clockwise"></i> Periksa Ulang</a>
          <a class="btn btn-primary <?= $wajibGagal ? 'disabled' : '' ?>" href="<?= urlLangkah(2) ?>">
            Lanjut <i class="bi bi-arrow-right"></i></a>
        </div>
      </div>

<?php elseif ($step === 2): ?>
      <?php $d = sess('db', ['host' => 'localhost', 'port' => 3306, 'database' => '', 'username' => '', 'password' => '']); ?>
      <p class="text-body-secondary">
        Masukkan kredensial basis data MySQL/MariaDB. Pada cPanel, buat terlebih dahulu basis data dan
        pengguna melalui menu <strong>MySQL® Databases</strong>, lalu berikan hak akses
        <em>ALL PRIVILEGES</em> kepada pengguna tersebut.
      </p>
      <form method="post" autocomplete="off">
        <div class="row g-3">
          <div class="col-md-8">
            <label class="form-label">Host Basis Data</label>
            <input class="form-control" name="host" value="<?= h(post('host', $d['host'])) ?>" required>
            <div class="hint mt-1">Umumnya <code>localhost</code> pada hosting cPanel.</div>
          </div>
          <div class="col-md-4">
            <label class="form-label">Port</label>
            <input class="form-control" name="port" value="<?= h(post('port', (string)$d['port'])) ?>">
          </div>
          <div class="col-md-6">
            <label class="form-label">Nama Basis Data</label>
            <input class="form-control" name="database" value="<?= h(post('database', $d['database'])) ?>" required>
            <div class="hint mt-1">Contoh: <code>namaakun_sipiutang</code></div>
          </div>
          <div class="col-md-6">
            <label class="form-label">Nama Pengguna</label>
            <input class="form-control" name="username" value="<?= h(post('username', $d['username'])) ?>" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Kata Sandi</label>
            <input class="form-control" type="password" name="password" value="<?= h((string)($_POST['password'] ?? $d['password'])) ?>">
          </div>
          <div class="col-md-6 d-flex align-items-end">
            <div class="form-check">
              <input class="form-check-input" type="checkbox" id="buatdb" name="buat_database" <?= isset($_POST['buat_database']) ? 'checked' : '' ?>>
              <label class="form-check-label" for="buatdb">
                Buat basis data bila belum ada
                <span class="hint d-block">Hanya berhasil bila pengguna memiliki hak CREATE DATABASE.</span>
              </label>
            </div>
          </div>
        </div>
        <div class="d-flex justify-content-between mt-4">
          <a class="btn btn-outline-secondary" href="<?= urlLangkah(1) ?>"><i class="bi bi-arrow-left"></i> Kembali</a>
          <button class="btn btn-primary">Uji Koneksi &amp; Lanjut <i class="bi bi-arrow-right"></i></button>
        </div>
      </form>

<?php elseif ($step === 3): ?>
      <?php $d = sess('db'); ?>
      <?php if (!$d): ?>
        <div class="alert alert-warning">
          Sesi instalasi berakhir. Silakan <a href="<?= urlLangkah(2) ?>">ulangi dari langkah 2</a>.
        </div>
      <?php else: ?>
      <div class="alert alert-success py-2">
        <i class="bi bi-database-check me-1"></i>
        Terhubung ke <strong><?= h($d['database']) ?></strong> di <?= h($d['host']) ?>
        (<?= h((string)sess('db_versi')) ?>)
      </div>
      <p class="text-body-secondary">Pilih data awal yang ingin dipasang.</p>
      <form method="post">
        <div class="form-check border rounded-3 p-3 mb-2">
          <input class="form-check-input" type="radio" name="mode" id="m1" value="demo" checked>
          <label class="form-check-label" for="m1">
            <span class="fw-semibold">Struktur + data master + data contoh (disarankan)</span>
            <span class="hint d-block">
              Memasang 49 tabel, seluruh data master (peran, hak akses, 66 pengaturan, jenis pekerjaan,
              bucket aging, dan lainnya), serta 3.072 invoice, 1.210 customer, dan 2.281 pembayaran
              hasil konversi workbook <em>AR RPP 2026.xlsx</em> yang sudah dibersihkan dan dihitung ulang.
              Cocok untuk pelatihan dan penelusuran fitur.
            </span>
          </label>
        </div>
        <div class="form-check border rounded-3 p-3">
          <input class="form-check-input" type="radio" name="mode" id="m2" value="kosong">
          <label class="form-check-label" for="m2">
            <span class="fw-semibold">Struktur + data master saja (basis data kosong)</span>
            <span class="hint d-block">
              Tanpa transaksi contoh. Pilih ini untuk penggunaan produksi, lalu masukkan data
              melalui menu <em>Import Data Excel</em>.
            </span>
          </label>
        </div>
        <div class="form-check mt-3">
          <input class="form-check-input" type="checkbox" id="timpa" name="timpa">
          <label class="form-check-label text-danger" for="timpa">
            Timpa struktur yang ada — <strong>seluruh data lama pada basis data ini akan dihapus permanen</strong>.
          </label>
        </div>
        <div class="alert alert-warning mt-3 py-2 hint mb-0">
          <i class="bi bi-hourglass-split me-1"></i>
          Pemasangan data contoh membutuhkan waktu sekitar 30–90 detik. Jangan menutup atau memuat ulang halaman ini.
        </div>
        <div class="d-flex justify-content-between mt-4">
          <a class="btn btn-outline-secondary" href="<?= urlLangkah(2) ?>"><i class="bi bi-arrow-left"></i> Kembali</a>
          <button class="btn btn-primary" onclick="this.disabled=true;this.form.submit();this.innerHTML='Memasang…'">
            Pasang Sekarang <i class="bi bi-arrow-right"></i></button>
        </div>
      </form>
      <?php endif; ?>

<?php elseif ($step === 4): ?>
      <?php $p = sess('pasang'); ?>
      <?php if ($p): ?>
      <div class="alert alert-success py-2">
        <i class="bi bi-check-circle-fill me-1"></i>
        Pemasangan <?= h((string)sess('pesan_data')) ?> selesai:
        <strong><?= number_format((int)$p['perintah'], 0, ',', '.') ?></strong> perintah SQL dalam
        <strong><?= h((string)$p['detik']) ?> detik</strong>,
        <strong><?= number_format((int)$p['invoice'], 0, ',', '.') ?></strong> invoice tersedia.
      </div>
      <?php endif; ?>
      <p class="text-body-secondary">
        Buat akun administrator utama Anda. Akun ini memiliki seluruh hak akses sistem.
      </p>
      <form method="post" autocomplete="off">
        <div class="row g-3">
          <div class="col-md-6">
            <label class="form-label">Nama Lengkap</label>
            <input class="form-control" name="nama" value="<?= h(post('nama')) ?>" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Nama Pengguna (untuk login)</label>
            <input class="form-control" name="username" value="<?= h(post('username')) ?>" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Email</label>
            <input class="form-control" type="email" name="email" value="<?= h(post('email')) ?>" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Nama Perusahaan</label>
            <input class="form-control" name="perusahaan" value="<?= h(post('perusahaan', 'PT Roto-Rooter Indonesia')) ?>">
          </div>
          <div class="col-md-6">
            <label class="form-label">Kata Sandi</label>
            <input class="form-control" type="password" name="password" required>
            <div class="hint mt-1">Minimal 8 karakter, memuat huruf besar, huruf kecil, dan angka.</div>
          </div>
          <div class="col-md-6">
            <label class="form-label">Ulangi Kata Sandi</label>
            <input class="form-control" type="password" name="password2" required>
          </div>
          <div class="col-12">
            <label class="form-label">URL Dasar Aplikasi</label>
            <input class="form-control" name="base_url" value="<?= h(post('base_url')) ?>" placeholder="Kosongkan untuk deteksi otomatis">
            <div class="hint mt-1">
              Isi hanya bila aplikasi dipasang di subfolder, misalnya <code>/sipiutang</code>.
            </div>
          </div>
          <div class="col-12">
            <div class="form-check">
              <input class="form-check-input" type="checkbox" id="hd" name="hapus_akun_demo" checked>
              <label class="form-check-label" for="hd">
                Nonaktifkan akun demo bawaan (<code>superadmin</code>, <code>finance</code>,
                <code>collection</code>, <code>sales</code>, <code>manajemen</code>, <code>auditor</code>)
                <span class="hint d-block">Sangat disarankan untuk pemasangan produksi.</span>
              </label>
            </div>
          </div>
        </div>
        <div class="d-flex justify-content-between mt-4">
          <a class="btn btn-outline-secondary" href="<?= urlLangkah(3) ?>"><i class="bi bi-arrow-left"></i> Kembali</a>
          <button class="btn btn-primary">Simpan &amp; Selesaikan <i class="bi bi-arrow-right"></i></button>
        </div>
      </form>

<?php else: ?>
      <?php $adm = sess('admin'); $base = (string)sess('base_url', ''); ?>
      <div class="text-center py-3">
        <div style="font-size:56px;line-height:1" class="text-success"><i class="bi bi-check-circle-fill"></i></div>
        <h4 class="mt-3 mb-1">Instalasi Berhasil</h4>
        <p class="text-body-secondary mb-4">SIPIUTANG siap digunakan.</p>
      </div>

      <div class="alert alert-danger">
        <div class="fw-semibold mb-1"><i class="bi bi-shield-exclamation me-1"></i>Langkah pengamanan wajib</div>
        <ol class="mb-0 ps-3">
          <li><strong>Hapus folder <code>/install</code></strong> dari server melalui File Manager cPanel atau FTP.
              Selama folder ini ada, siapa pun dapat memasang ulang sistem Anda.</li>
          <li>Pastikan berkas <code>config/config.php</code> berizin <code>640</code> atau <code>644</code>
              dan tidak dapat diakses dari browser.</li>
          <li>Arahkan <em>Document Root</em> domain ke folder <code>public/</code>, atau gunakan
              berkas <code>.htaccess</code> yang sudah disertakan.</li>
          <li>Aktifkan HTTPS (SSL gratis Let's Encrypt tersedia di cPanel) sebelum digunakan.</li>
        </ol>
      </div>

      <?php if ($adm): ?>
      <table class="table table-sm">
        <tr><th style="width:200px">Nama pengguna admin</th><td class="font-monospace"><?= h($adm['username']) ?></td></tr>
        <tr><th>Nama lengkap</th><td><?= h($adm['nama']) ?></td></tr>
        <tr><th>Akun demo</th>
            <td><?= sess('demo_nonaktif') ? 'Dinonaktifkan' : '<span class="text-danger">Masih aktif — nonaktifkan melalui menu Pengguna</span>' ?></td></tr>
      </table>
      <?php else: ?>
      <div class="alert alert-info">
        Sistem ini sudah terpasang sebelumnya. Untuk memasang ulang, hapus berkas
        <code>storage/.installed</code> lalu buka <code>?paksa=1</code>.
      </div>
      <?php endif; ?>

      <div class="d-grid gap-2 d-sm-flex justify-content-sm-center mt-4">
        <a class="btn btn-primary btn-lg" href="<?= h($base !== '' ? $base . '/masuk' : '../public/masuk') ?>">
          <i class="bi bi-box-arrow-in-right me-1"></i> Masuk ke SIPIUTANG</a>
        <a class="btn btn-outline-secondary btn-lg" href="../docs/MANUAL_PENGGUNA.md">
          <i class="bi bi-book me-1"></i> Manual Pengguna</a>
      </div>
<?php endif; ?>

    </div>
  </div>

  <p class="text-center hint mt-3 mb-5">
    SIPIUTANG v1.0.0 &middot; PHP <?= h(PHP_VERSION) ?> &middot;
    Batas unggah <?= h(ini_get('upload_max_filesize')) ?> &middot; Memori <?= h(ini_get('memory_limit')) ?>
  </p>
</div>
</body>
</html>
