<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/**
 * Ownership + optional stored config for VPN accesses.
 *
 * `kind` exists because a null user_id previously had to mean two different
 * things — "belongs to the admins" and "this is a host peer". A staff access
 * without an owner is a bug, a host peer with one is nonsense, and no code can
 * tell them apart from a null.
 *
 * user_id is restrictOnDelete on purpose: silently orphaning a live credential
 * into the management network is worse than refusing to delete the account.
 * Revoking a staff member also revokes their peers (Admin\Settings).
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::table('vpn_peers', function (Blueprint $table) {
            $table->string('kind')->default('staff')->after('name');   // staff|host|system
            $table->foreignId('user_id')->nullable()->after('kind')->constrained()->restrictOnDelete();
            // Encrypted with VPN_CONFIG_KEY (see ConfigVault) — never APP_KEY, so
            // a leaked application key does not also hand over VPN credentials.
            $table->text('config_secret')->nullable();
            $table->timestamp('secret_purged_at')->nullable();
            $table->timestamp('last_downloaded_at')->nullable();
            $table->unsignedInteger('download_count')->default(0);
        });

        // Existing rows fall into three groups, and the difference matters:
        // pipeline peers are host peers; peers someone created in the console
        // belong to that person; and peers the sync adopted off the interface
        // have no human behind them at all — calling those "staff" would break
        // the very invariant this migration introduces (a staff access has an
        // owner).
        DB::table('vpn_peers')->whereNotNull('host_id')->update(['kind' => 'host']);
        DB::table('vpn_peers')->whereNull('host_id')->whereNotNull('created_by')->update([
            'kind' => 'staff',
            'user_id' => DB::raw('created_by'),
        ]);
        DB::table('vpn_peers')->whereNull('host_id')->whereNull('created_by')->update(['kind' => 'system']);
    }

    public function down(): void
    {
        Schema::table('vpn_peers', function (Blueprint $table) {
            $table->dropForeign(['user_id']);
            $table->dropColumn(['kind', 'user_id', 'config_secret', 'secret_purged_at', 'last_downloaded_at', 'download_count']);
        });
    }
};
