<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use Hypervel\Http\Request;
use Hypervel\Support\Facades\Cache;
use Hypervel\Support\Facades\Response;
use Psr\Http\Message\ResponseInterface;
use Hypervel\Support\Facades\Auth;
use App\Models\User;
use Hypervel\Support\Facades\Hash;
use Hypervel\Support\Facades\Log;

use Hypervel\Support\Facades\Redis;

class LoginController
{
    public function authenticate(Request $request): ResponseInterface
    {
        $credentials = $request->inputs(['mobile_number', 'password']);
        $keepalive = $request->input('keepalive');

        if (!$credentials['mobile_number'] || !$credentials['password']) {
            return Response::json([
                'success' => false,
                'message' => 'Missing fields.',
            ], 422);
        }

        $candidates = self::phMobileVariants($credentials['mobile_number']);

        $user = User::whereIn('mobile_number', $candidates)->first();

        if (!$user) {
            return Response::json([
                'success' => false,
                'message' => 'Account not found.',
            ], 401);
        }

        Log::info('Login attempt', [
            'mobile_number' => $credentials['mobile_number'],
            'candidates' => $candidates,
            'user_found' => true,
            'active' => $user->active,
            'acct_type' => $user->acct_type->value ?? null,
        ]);

        if (!$user->active) {
            return Response::json([
                'success' => false,
                'message' => 'Account is inactive. Please contact support.',
            ], 401);
        }

        if ($user && Hash::check($credentials['password'], $user->password)) {

            Auth::login($user); // or Auth::guard()->login($user)

            $current_userHashkey = $user->hashkey;
            $sessionId = session()->getId();




            Redis::sadd("user_sessions:{$current_userHashkey}", $sessionId);
            //  $request->session()->regenerate();

            Log::info('KeepAlive Value ' . $keepalive);
            if ($keepalive === true || $keepalive === 'true') {
                self::setSessiontoKeepAlive();
            }

            return Response::json([
                'success' => true,
                'message' => 'Login successful',
            ]);
        }

        return Response::json([
            'success' => false,
            'message' => 'Invalid credentials.',
        ], 401);

    }
    /**
     * Set or extends current session auth<br>
     * This Function is Not Working JWT Automatically sets based on config file ttl
     * @param string|bool $sessionid if false then get current sessionID
     * @param int|bool $aliveinseconds if true then consider it forever
     * @return null|bool //  Time To Live TTL
     */
    public static function setSessiontoKeepAlive(string|false $sessionId = false, int|bool $aliveinseconds = true)
    {
        $sessionId = $sessionId ?: session()->getId();
        if (!$sessionId) {
            return false;
        }

        if ($aliveinseconds === true) {
            $aliveinseconds = 7889472; // 3 months
        }
        if ($aliveinseconds === false) {
            return false;
        }

        // The redis session driver stores the key under the Redis connection prefix.
        // Cache::get/put uses a different prefix (cache store), so we use Redis::expire()
        // directly to extend the TTL of the existing session key without reading its value.
        $result = Redis::expire($sessionId, $aliveinseconds);
        if (!$result) {
            Log::warning('setSessiontoKeepAlive: session key not found in Redis, cannot extend TTL for: ' . $sessionId);
            return false;
        }

        $ttl = Redis::ttl($sessionId);
        Log::info('extended session: ' . $sessionId . ' for ' . $aliveinseconds . 's, TTL: ' . $ttl);
        return $ttl;
    }

    /**
     * Build all plausible stored forms of a Philippine mobile number so the
     * caller can match whichever variant is in the DB. Variants returned:
     *   - 09XXXXXXXXX
     *   - 9XXXXXXXXX  (no leading 0)
     *   - 639XXXXXXXXX
     *   - +639XXXXXXXXX
     * plus the original raw input as a final fallback.
     */
    public static function phMobileVariants(string $input): array
    {
        $digits = preg_replace('/\D+/', '', $input);
        $core = null; // the 10-digit 9XXXXXXXXX portion

        if (preg_match('/^639(\d{9})$/', $digits, $m)) {
            $core = '9' . $m[1];
        } elseif (preg_match('/^09(\d{9})$/', $digits, $m)) {
            $core = '9' . $m[1];
        } elseif (preg_match('/^9(\d{9})$/', $digits, $m)) {
            $core = '9' . $m[1];
        }

        $variants = [$input];
        if ($core) {
            $variants[] = '0' . $core;
            $variants[] = $core;
            $variants[] = '63' . $core;
            $variants[] = '+63' . $core;
        }

        return array_values(array_unique($variants));
    }

    /**
     * Back-compat shim: still used by UserModifyAdminPageController to
     * canonicalize on save (admin edit). Picks 09XXXXXXXXX when possible.
     */
    public static function normalizePhMobile(string $input): string
    {
        $digits = preg_replace('/\D+/', '', $input);

        if (preg_match('/^639(\d{9})$/', $digits, $m)) {
            return '09' . $m[1];
        }
        if (preg_match('/^9(\d{9})$/', $digits, $m)) {
            return '09' . $m[1];
        }
        if (preg_match('/^09\d{9}$/', $digits)) {
            return $digits;
        }

        return $input;
    }

    public function extendcurrentSession()
    {
       $ttl =  self::setSessiontoKeepAlive();

       return Response::make('TTL is '.$ttl);
      
    }
}