#!/usr/bin/env php
<?php
/**
 * mutu – CLI Tool untuk Sistem SPM-KP
 * Penggunaan : php mutu <command> [options]
 * Mirip dengan php artisan di Laravel.
 */

define('BASE_PATH', __DIR__);
define('CLI_VERSION', '1.0.0');

// Warna ANSI
define('C_RESET',  "\033[0m");
define('C_GREEN',  "\033[0;32m");
define('C_YELLOW', "\033[0;33m");
define('C_CYAN',   "\033[0;36m");
define('C_RED',    "\033[0;31m");
define('C_BOLD',   "\033[1m");
define('C_DIM',    "\033[2m");
define('C_BLUE',   "\033[0;34m");

// ── bootstrap ────────────────────────────────────────────────
require_once BASE_PATH . '/koneksi/config.php';

$argv    = $_SERVER['argv'] ?? [];
$command = $argv[1] ?? 'help';
$args    = array_slice($argv, 2);

// ── router ───────────────────────────────────────────────────
match ($command) {
    'serve'            => cmd_serve($args),
    'migrate'          => cmd_migrate($args),
    'migrate:rollback' => cmd_migrate_rollback(),
    'migrate:fresh'    => cmd_migrate_fresh(),
    'make:user'        => cmd_make_user(),
    'db:seed'          => cmd_db_seed(),
    'list', 'help', '--help', '-h' => cmd_help(),
    default            => cmd_unknown($command),
};

// ════════════════════════════════════════════════════════════
//  COMMANDS
// ════════════════════════════════════════════════════════════

// ── serve ────────────────────────────────────────────────────
function cmd_serve(array $args): void
{
    $host = '127.0.0.1';
    $port = 8000;

    foreach ($args as $arg) {
        if (str_starts_with($arg, '--host=')) $host = substr($arg, 7);
        if (str_starts_with($arg, '--port=')) $port = (int) substr($arg, 7);
    }

    info("Server development SPM-KP");
    line(C_GREEN . "  INFO  Server running on " . C_RESET . "http://{$host}:{$port}");
    line(C_DIM   . "  Tekan Ctrl+C untuk menghentikan server." . C_RESET);
    blank();

    $docRoot = BASE_PATH;
    passthru("php -S {$host}:{$port} -t \"{$docRoot}\"");
}

// ── migrate ──────────────────────────────────────────────────
function cmd_migrate(array $args): void
{
    global $dbConn;

    banner("Running Migrations");

    $migrationDir = BASE_PATH . '/database/migrations';

    if (is_dir($migrationDir)) {
        $files = glob($migrationDir . '/*.sql');
        sort($files);

        if (empty($files)) {
            warn("Tidak ada file migration di database/migrations/");
            return;
        }

        // Buat tabel tracker jika belum ada
        mysqli_query($dbConn, "SET GLOBAL innodb_file_format=Barracuda");
        mysqli_query($dbConn, "CREATE TABLE IF NOT EXISTS `_migrations` (
            `id`         INT UNSIGNED NOT NULL AUTO_INCREMENT,
            `migration`  VARCHAR(191) NOT NULL,
            `ran_at`     DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (`id`),
            UNIQUE KEY `uq_migration` (`migration`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC");

        $ran = [];
        $res = mysqli_query($dbConn, "SELECT migration FROM `_migrations`");
        while ($row = mysqli_fetch_assoc($res)) $ran[] = $row['migration'];

        $count = 0;
        foreach ($files as $file) {
            $name = basename($file);
            if (in_array($name, $ran, true)) {
                line(C_DIM . "  [skip]  {$name}" . C_RESET);
                continue;
            }
            run_sql_file($dbConn, $file, $name);
            $safe = mysqli_real_escape_string($dbConn, $name);
            mysqli_query($dbConn, "INSERT IGNORE INTO `_migrations` (migration) VALUES ('{$safe}')");
            $count++;
        }

        if ($count === 0) {
            line(C_YELLOW . "  Tidak ada migration baru untuk dijalankan." . C_RESET);
        }

    } else {
        // Fallback ke file tunggal migration.sql
        $fallback = BASE_PATH . '/database/migration.sql';
        if (!file_exists($fallback)) {
            error("File migration tidak ditemukan: database/migration.sql");
            return;
        }
        run_sql_file($dbConn, $fallback, 'migration.sql');
    }

    blank();
    success("Migration selesai.");
}

// ── migrate:rollback ─────────────────────────────────────────
function cmd_migrate_rollback(): void
{
    global $dbConn;
    banner("Rollback Migration Terakhir");

    $res = mysqli_query($dbConn, "SELECT migration FROM `_migrations` ORDER BY id DESC LIMIT 1");
    if (!$res || mysqli_num_rows($res) === 0) {
        warn("Tidak ada migration yang tercatat.");
        return;
    }

    $row  = mysqli_fetch_assoc($res);
    $name = $row['migration'];

    $rollbackFile = BASE_PATH . "/database/migrations/" . str_replace('.sql', '.rollback.sql', $name);
    if (file_exists($rollbackFile)) {
        run_sql_file($dbConn, $rollbackFile, $name . ' (rollback)');
    } else {
        warn("File rollback tidak ditemukan: " . basename($rollbackFile));
    }

    $safe = mysqli_real_escape_string($dbConn, $name);
    mysqli_query($dbConn, "DELETE FROM `_migrations` WHERE migration = '{$safe}'");
    success("Rollback '{$name}' selesai.");
}

// ── migrate:fresh ────────────────────────────────────────────
function cmd_migrate_fresh(): void
{
    global $dbConn;
    banner("MIGRATE FRESH – Semua tabel akan dihapus & dibuat ulang!");
    echo C_RED . "  Peringatan: Semua data akan hilang!\n" . C_RESET;
    echo "  Ketik " . C_BOLD . "yes" . C_RESET . " untuk melanjutkan: ";

    $confirm = trim(fgets(STDIN));
    if (strtolower($confirm) !== 'yes') {
        warn("Dibatalkan.");
        return;
    }

    $tables = [];
    $res = mysqli_query($dbConn, "SHOW TABLES");
    while ($row = mysqli_fetch_row($res)) $tables[] = $row[0];

    if ($tables) {
        mysqli_query($dbConn, "SET FOREIGN_KEY_CHECKS = 0");
        foreach ($tables as $t) {
            mysqli_query($dbConn, "DROP TABLE IF EXISTS `{$t}`");
            line(C_RED . "  [drop]  {$t}" . C_RESET);
        }
        mysqli_query($dbConn, "SET FOREIGN_KEY_CHECKS = 1");
    }

    blank();
    cmd_migrate([]);
}

// ── make:user ────────────────────────────────────────────────
function cmd_make_user(): void
{
    global $dbConn;
    banner("Buat Akun Pengguna Baru");

    $nama     = prompt("Nama Lengkap");
    $username = prompt("Username");
    $email    = prompt("Email");
    $password = prompt_hidden("Kata Sandi");
    $role     = prompt("Role [admin/dokter/perawat/manajemen/viewer]", 'viewer');
    $unit     = prompt("Unit/Departemen", '-');

    $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);

    $n  = mysqli_real_escape_string($dbConn, $nama);
    $u  = mysqli_real_escape_string($dbConn, $username);
    $e  = mysqli_real_escape_string($dbConn, $email);
    $r  = mysqli_real_escape_string($dbConn, $role);
    $un = mysqli_real_escape_string($dbConn, $unit);

    $ok = mysqli_query($dbConn,
        "INSERT INTO `users` (nama_lengkap, username, email, password, role, unit, status)
         VALUES ('{$n}', '{$u}', '{$e}', '{$hash}', '{$r}', '{$un}', 'aktif')"
    );

    blank();
    if ($ok) {
        success("Akun '{$username}' berhasil dibuat! (ID: " . mysqli_insert_id($dbConn) . ")");
    } else {
        error("Gagal: " . mysqli_error($dbConn));
    }
}

// ── db:seed ──────────────────────────────────────────────────
function cmd_db_seed(): void
{
    global $dbConn;
    banner("Running Database Seeder");

    $seederDir = BASE_PATH . '/database/seeders';
    if (!is_dir($seederDir)) {
        warn("Folder database/seeders/ tidak ditemukan.");
        return;
    }

    $files = glob($seederDir . '/*.sql');
    sort($files);

    foreach ($files as $file) {
        run_sql_file($dbConn, $file, basename($file));
    }

    success("Seeder selesai.");
}

// ── help ─────────────────────────────────────────────────────
function cmd_help(): void
{
    blank();
    line(C_BOLD . C_CYAN . "  mutu v" . CLI_VERSION . "  –  CLI Tool Sistem SPM-KP" . C_RESET);
    blank();
    line(C_YELLOW . "  Usage:" . C_RESET);
    line("    php mutu <command> [options]");
    blank();
    line(C_YELLOW . "  Available Commands:" . C_RESET);

    $cmds = [
        'serve'            => ['Jalankan development server PHP',      '--host=127.0.0.1 --port=8000'],
        'migrate'          => ['Jalankan semua migration SQL',          ''],
        'migrate:rollback' => ['Rollback migration terakhir',           ''],
        'migrate:fresh'    => ['Drop semua tabel lalu migrate ulang',   ''],
        'make:user'        => ['Buat akun pengguna baru (interaktif)',  ''],
        'db:seed'          => ['Jalankan file seeder SQL',              ''],
        'list'             => ['Tampilkan daftar perintah ini',         ''],
    ];

    foreach ($cmds as $cmd => [$desc, $opt]) {
        $padCmd = str_pad($cmd, 22);
        $padOpt = $opt ? C_DIM . " {$opt}" . C_RESET : '';
        line("    " . C_GREEN . $padCmd . C_RESET . " {$desc}{$padOpt}");
    }

    blank();
    line(C_YELLOW . "  Contoh:" . C_RESET);
    line("    " . C_DIM . "php mutu serve" . C_RESET);
    line("    " . C_DIM . "php mutu serve --port=8080" . C_RESET);
    line("    " . C_DIM . "php mutu migrate" . C_RESET);
    line("    " . C_DIM . "php mutu migrate:fresh" . C_RESET);
    line("    " . C_DIM . "php mutu make:user" . C_RESET);
    blank();
}

function cmd_unknown(string $cmd): void
{
    error("Perintah '{$cmd}' tidak dikenal. Jalankan 'php mutu list' untuk daftar perintah.");
}

// ════════════════════════════════════════════════════════════
//  HELPERS
// ════════════════════════════════════════════════════════════

function run_sql_file($dbConn, string $file, string $label): void
{
    $sql = file_get_contents($file);
    if ($sql === false) {
        error("Tidak bisa membaca: {$file}");
        return;
    }

    if (mysqli_multi_query($dbConn, $sql)) {
        do {
            if ($result = mysqli_store_result($dbConn)) {
                mysqli_free_result($result);
            }
        } while (mysqli_more_results($dbConn) && mysqli_next_result($dbConn));
    }

    if (mysqli_errno($dbConn)) {
        $err = mysqli_error($dbConn);
        if (!str_contains($err, 'already exists') && !str_contains($err, 'Duplicate entry')) {
            error("SQL Error: {$err}");
            return;
        }
    }

    line(C_GREEN . "  [done]  " . C_RESET . $label);
}

function prompt(string $label, string $default = ''): string
{
    $hint = $default !== '' ? " [{$default}]" : '';
    echo C_CYAN . "  {$label}{$hint}: " . C_RESET;
    $val = trim(fgets(STDIN));
    return $val !== '' ? $val : $default;
}

function prompt_hidden(string $label): string
{
    echo C_CYAN . "  {$label}: " . C_RESET;
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        $val = trim(fgets(STDIN));
    } else {
        system('stty -echo');
        $val = trim(fgets(STDIN));
        system('stty echo');
        echo "\n";
    }
    return $val;
}

function banner(string $text): void
{
    blank();
    line(C_BOLD . C_BLUE . "  ┌─ {$text}" . C_RESET);
    blank();
}

function info(string $text): void    { line("  " . C_CYAN . C_BOLD . "{$text}" . C_RESET); blank(); }
function success(string $text): void { line("  " . C_GREEN . "OK  {$text}" . C_RESET); blank(); }
function warn(string $text): void    { line("  " . C_YELLOW . "!   {$text}" . C_RESET); }
function error(string $text): void   { line("  " . C_RED    . "ERR {$text}" . C_RESET); }
function blank(): void               { echo "\n"; }
function line(string $text): void    { echo $text . "\n"; }
