<?php

use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;

/**
 * PRC-176 SEC-Critical — encrypt SMS provider credentials at rest.
 *
 * The 13 SMS provider secret keys were added to Setting::SECRET_KEYS in
 * the same commit; future writes go through the model's encrypting mutator.
 * This migration retroactively encrypts whatever plaintext values already
 * sit in the `settings` table on production. Idempotent — re-running is
 * a no-op because already-encrypted rows decrypt cleanly and are skipped.
 */
return new class extends Migration
{
    private const SMS_SECRET_KEYS = [
        'sms_twilio_api_secret',
        'sms_netgsm_password',
        'sms_nexmo_secret',
        'sms_iletimerkezi_password',
        'sms_clickatell_api_key',
        'sms_whatsapp_business_access_token',
        'sms_ozteksms_password',
        'sms_plivo_auth_token',
        'sms_messagebird_api_key',
        'sms_infobip_api_key',
        'sms_bulksms_token_secret',
        'sms_clicksend_api_key',
        'sms_sms77_api_key',
    ];

    public function up(): void
    {
        foreach (self::SMS_SECRET_KEYS as $key) {
            $raw = DB::table('settings')->where('key', $key)->value('value');
            if ($raw === null || $raw === '') {
                continue;
            }
            try {
                Crypt::decryptString($raw);
                continue; // already encrypted
            } catch (DecryptException $e) {
                // plaintext — encrypt
            }
            DB::table('settings')
                ->where('key', $key)
                ->update([
                    'value' => Crypt::encryptString($raw),
                    'updated_at' => now(),
                ]);
        }
    }

    public function down(): void
    {
        foreach (self::SMS_SECRET_KEYS as $key) {
            $raw = DB::table('settings')->where('key', $key)->value('value');
            if ($raw === null || $raw === '') {
                continue;
            }
            try {
                $plain = Crypt::decryptString($raw);
            } catch (DecryptException $e) {
                continue;
            }
            DB::table('settings')
                ->where('key', $key)
                ->update([
                    'value' => $plain,
                    'updated_at' => now(),
                ]);
        }
    }
};
