<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;

class LockedUsersController extends Controller
{
    /**
     * Hitung jumlah user yang sedang terblokir.
     * Dipakai oleh navigation.blade.php untuk badge counter.
     */
    public static function countLocked(): int
    {
        $users = User::select('email')->get();
        $count = 0;
        foreach ($users as $user) {
            if (self::getLockedSeconds($user->email) > 0) {
                $count++;
            }
        }
        return $count;
    }

    /**
     * Ambil semua user yang sedang terblokir rate-limit login.
     * Kita iterasi semua user ber-email, cek apakah throttle key-nya aktif.
     *
     * GET /admin/locked-users
     */
    public function index(Request $request)
    {
        $users   = User::select('id', 'name', 'email', 'role')->get();
        $locked  = [];

        foreach ($users as $user) {
            // Throttle key menggunakan email|IP, tapi admin tidak tahu IP user tsb.
            // Kita simpan key pakai wildcard lookup via cache prefix scan.
            // Karena Laravel RateLimiter key = sha1(transliterate(lower(email)|ip)),
            // kita tidak bisa langsung tahu IP-nya.
            // Solusi: simpan metadata lockout saat terjadi (via event Lockout).
            // Namun agar ini bisa berdiri sendiri tanpa event tambahan,
            // kita gunakan pendekatan: cek semua entry cache dengan prefix "laravel_cache_".
            // Alternatif simpel: gunakan cache key dengan format yang bisa di-scan.
            // Untuk implementasi ini kita gunakan cache tag custom yang di-set saat lockout.
            // Lihat: LockedUserTracker helper di bawah.

            $secondsLeft = self::getLockedSeconds($user->email);
            if ($secondsLeft > 0) {
                $locked[] = [
                    'id'           => $user->id,
                    'name'         => $user->name,
                    'email'        => $user->email,
                    'role'         => $user->role,
                    'seconds_left' => $secondsLeft,
                ];
            }
        }

        if ($request->expectsJson()) {
            return response()->json(['locked_users' => $locked]);
        }

        return view('admin.locked-users', compact('locked'));
    }

    /**
     * Buka blokir satu user berdasarkan email.
     * Admin bisa unlock tanpa tahu IP user (kita clear semua key yang mengandung email tsb).
     *
     * POST /admin/locked-users/unlock
     * Body: { email: "user@gmail.com" }
     */
    public function unlock(Request $request): JsonResponse
    {
        $request->validate([
            'email' => ['required', 'string', 'email'],
        ]);

        $email = strtolower(trim($request->email));

        // Cari user
        $user = User::where('email', $email)->first();
        if (!$user) {
            return response()->json(['success' => false, 'message' => 'User tidak ditemukan.'], 404);
        }

        // Hapus semua cache lockout yang mungkin ada untuk email ini
        // (berbagai IP bisa memblokir akun yang sama)
        self::clearAllLocksForEmail($email);

        return response()->json([
            'success' => true,
            'message' => "Blokir untuk {$user->name} ({$email}) berhasil dibuka.",
        ]);
    }

    /**
     * Polling endpoint — cek status semua locked users (untuk realtime update di halaman admin).
     *
     * GET /admin/locked-users/status
     */
    public function status(): JsonResponse
    {
        $users  = User::select('id', 'name', 'email', 'role')->get();
        $locked = [];

        foreach ($users as $user) {
            $secondsLeft = self::getLockedSeconds($user->email);
            if ($secondsLeft > 0) {
                $locked[] = [
                    'id'           => $user->id,
                    'email'        => $user->email,
                    'seconds_left' => $secondsLeft,
                ];
            }
        }

        return response()->json(['locked_users' => $locked]);
    }

    /**
     * Cek sisa detik lockout untuk sebuah email.
     * Kita coba beberapa format IP yang umum karena admin tidak tahu IP user.
     * Strategi: simpan entry cache khusus saat lockout terjadi (via LoginRequest event).
     * Format cache key khusus: "login_locked:{email}"
     */
    public static function getLockedSeconds(string $email): int
    {
        $cacheKey = 'login_locked:' . strtolower(trim($email));
        $data     = cache()->get($cacheKey);

        if (!$data) return 0;

        $expiresAt   = $data['expires_at'] ?? 0;
        $secondsLeft = $expiresAt - time();

        return $secondsLeft > 0 ? (int) $secondsLeft : 0;
    }

    /**
     * Bersihkan lockout cache untuk email tertentu.
     * Juga clear RateLimiter keys yang mungkin ada (semua IP yang pernah coba).
     */
    public static function clearAllLocksForEmail(string $email): void
    {
        $email    = strtolower(trim($email));
        $cacheKey = 'login_locked:' . $email;

        // Hapus custom cache key kita
        cache()->forget($cacheKey);

        // Coba clear RateLimiter key juga (meski kita tidak tahu IP-nya,
        // kita manfaatkan bahwa key = sha1(transliterate(lower_email|ip))
        // Untuk admin unlock, kita hapus via helper yang sama yang dipakai LoginRequest.
        // Karena kita tidak tahu IP, kita scan cache keys dengan prefix 'laravel_cache_'.
        // Alternatif: kita store throttle key saat lockout di cache kita juga.
        // Lihat LoginRequest yang sudah diupdate — ia menyimpan throttleKey di cache kita.
        $throttleKey = cache()->get('login_locked_throttle_key:' . $email);
        if ($throttleKey) {
            RateLimiter::clear($throttleKey);
            cache()->forget('login_locked_throttle_key:' . $email);
        }
    }
}