<?php
/**
 * Antara — one-shot migrator from /data/users.json (legacy plaintext) to the
 * encrypted store at /storage/secure/users.enc.
 *
 * Idempotent: if users.enc already exists with at least one user, the script
 * exits without touching anything (returns ['migrated' => false, ...]).
 *
 * The legacy JSON uses a custom HMAC scheme for passwords (raw base64 hashes),
 * which is incompatible with PHP password_verify(). We therefore mark every
 * migrated user as requirePasswordReset = true and seed a random temporary
 * password_hash so the account exists and is recoverable through the admin
 * panel without leaving a permanent unverifiable hash.
 *
 * Email "colivares@sinapsysdevops.com" is promoted to super_admin per spec.
 */

require_once __DIR__ . '/store.php';
require_once __DIR__ . '/../security/logger.php';

if (!defined('ANTARA_ROOT')) {
    define('ANTARA_ROOT', dirname(__DIR__, 2));
}

final class AntaraMigrator
{
    public const SUPER_ADMIN_EMAIL = 'colivares@sinapsysdevops.com';

    public static function needsMigration(): bool
    {
        if (!is_file(ANTARA_ROOT . '/data/users.json')) return false;
        $blob = AntaraStore::usersAll();
        return empty($blob['users']);
    }

    public static function run(): array
    {
        $legacyPath = ANTARA_ROOT . '/data/users.json';
        $report = ['migrated' => false, 'users' => 0, 'super_admin' => null, 'backup' => null];

        if (!is_file($legacyPath)) {
            return $report;
        }
        if (!self::needsMigration()) {
            $report['skipped_reason'] = 'users.enc already populated';
            return $report;
        }

        $raw = @file_get_contents($legacyPath);
        if ($raw === false) {
            throw new RuntimeException('Cannot read legacy users.json');
        }
        $legacy = json_decode($raw, true);
        if (!is_array($legacy) || empty($legacy['users']) || !is_array($legacy['users'])) {
            $report['skipped_reason'] = 'legacy users.json has no users';
            return $report;
        }

        $now = gmdate('Y-m-d\TH:i:s\Z');
        $count = 0;
        $superAdminId = null;

        foreach ($legacy['users'] as $u) {
            $email = strtolower(trim($u['email'] ?? ''));
            if ($email === '') continue;

            $isSuper = ($email === strtolower(self::SUPER_ADMIN_EMAIL));
            $legacyRole = strtolower(trim((string)($u['role'] ?? '')));
            if ($isSuper) {
                $role = AntaraStore::ROLE_SUPER;
            } elseif ($legacyRole === AntaraStore::ROLE_SUPER) {
                $role = AntaraStore::ROLE_SUPER;
            } elseif ($legacyRole === AntaraStore::ROLE_ADMIN || $legacyRole === 'admin') {
                $role = AntaraStore::ROLE_ADMIN;
            } else {
                $role = AntaraStore::ROLE_USER;
            }

            // Throwaway random password; user must reset on first login.
            $tempPwd = bin2hex(random_bytes(24));
            $hash = password_hash($tempPwd, PASSWORD_DEFAULT);

            $patch = [
                'id'        => $u['id'] ?? AntaraStore::uuid(),
                'username'  => $u['username'] ?? '',
                'email'     => $email,
                'phone'     => $u['phone'] ?? '',
                'role'      => $role,
                'active'    => true,
                'blocked'   => false,
                'deletedAt' => null,
                'createdAt' => $u['createdAt'] ?? $now,
                'updatedAt' => $now,
                'lastLoginAt' => null,
                'failedAttempts' => 0,
                'lockedUntil' => null,
                'passwordHash' => $hash,
                'requirePasswordReset' => true,
                'webauthnCredentialIds' => [],
                'metadata' => [
                    'migratedFromLegacy' => true,
                    'migratedAt' => $now,
                ],
            ];
            AntaraStore::upsertUser($patch, $patch['id']);
            $count++;
            if ($isSuper) $superAdminId = $patch['id'];
        }

        // Backup the legacy file.
        $backup = $legacyPath . '.bak.' . date('Ymd-His');
        if (@rename($legacyPath, $backup)) {
            $report['backup'] = $backup;
        }

        // Touch the auth_config so it gets written with defaults right now.
        try {
            AntaraStore::configRead();
        } catch (\RuntimeException $e) {
            AntaraLogger::log('migrate.touch_config_failed', ['error' => $e->getMessage()]);
        }

        AntaraLogger::log('migrate.legacy_users', [
            'count'        => $count,
            'super_admin'  => $superAdminId,
            'backup'       => $report['backup'],
        ]);

        $report['migrated']    = true;
        $report['users']       = $count;
        $report['super_admin'] = $superAdminId;
        return $report;
    }
}

// CLI helper: php core/auth/migrate.php
if (PHP_SAPI === 'cli' && isset($_SERVER['argv'][0]) && realpath($_SERVER['argv'][0]) === __FILE__) {
    try {
        $r = AntaraMigrator::run();
        echo json_encode($r, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL;
        exit(0);
    } catch (\Throwable $e) {
        fwrite(STDERR, 'Migration failed: ' . $e->getMessage() . PHP_EOL);
        exit(1);
    }
}
