<?php

namespace App\Providers;

use App\Support\LegacyCrypto\CiSeedCrypto;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\Fortify;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        if (class_exists(Fortify::class)) {
            Fortify::ignoreRoutes();
        }

        if (app()->environment('local','development')) {
            \DB::listen(function ($q) {
                if ($q->time >= 50) { // 50ms 이상만
                    \Log::info('[SQL SLOW]', [
                        'ms' => $q->time,
                        'sql' => $q->sql,
                        'bindings' => $q->bindings,
                    ]);
                }
            });
        }

        $this->app->singleton(CiSeedCrypto::class, function () {
            $key = config('legacy.seed_user_key_default', '');
            $iv  = config('legacy.iv', []);

            // key는 string
            if (!is_string($key) || $key === '') {
                throw new \RuntimeException('legacy crypto key missing (seed_user_key_default)');
            }

            // iv는 array (16 bytes)
            if (!is_array($iv)) {
                throw new \RuntimeException('legacy iv must be array');
            }
            if (count($iv) !== 16) {
                throw new \RuntimeException('legacy iv array must be 16 bytes');
            }
            foreach ($iv as $b) {
                if (!is_int($b) || $b < 0 || $b > 255) {
                    throw new \RuntimeException('legacy iv array values must be ints 0~255');
                }
            }

            return new CiSeedCrypto($key, $iv);
        });
    }

    public function boot(): void
    {
        RateLimiter::for('admin-login', function (Request $request) {
            $email = (string) $request->input('email', $request->input('userid', $request->input('admin_email', '')));
            $emailKey = $email !== '' ? mb_strtolower(trim($email)) : 'guest';

            return [
                Limit::perMinute(10)->by('ip:'.$request->ip()),
                Limit::perMinute(5)->by('admin-login:'.$emailKey),
            ];
        });

        RateLimiter::for('admin-otp', function (Request $request) {
            return [
                Limit::perMinute(10)->by('ip:'.$request->ip()),
                Limit::perMinute(5)->by('admin-otp:'.$request->session()->getId()),
            ];
        });

        RateLimiter::for('admin-mail-smtp', function () {
            return Limit::perMinute(30)->by('admin-mail-smtp');
        });
    }
}
