<?php
  
namespace App\Http\Controllers\Auth;
  
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\AdminLoginRequest;
use App\Http\Requests\Auth\InstituteLoginRequest;
use App\Http\Requests\Auth\InstituteRegistrationRequest;
use App\Http\Requests\Auth\ResetForgotPasswordRequest;
use App\Http\Requests\Auth\SendOtpRequest;
use App\Http\Requests\Auth\StudentLoginRequest;
use App\Http\Requests\Auth\StudentRegistrationRequest;
use App\Http\Requests\Auth\UpdateOwnPasswordRequest;
use App\Http\Requests\Auth\VerifyForgotPasswordOtpRequest;
use App\Models\Attachment;
use App\Models\CompetitionAssignment;
use App\Models\GameplayHistory;
use App\Models\MatchContest;
use App\Models\QuestionManagement;
use App\Models\QuestionSetup;
use App\Models\StudentProfile;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Session;
use Illuminate\Support\Facades\Redirect;
use App\Models\User;
use App\Models\WalletHistory;
use Hash;
use DB; 
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Response;
use Illuminate\Support\Str;
use Throwable;
  
class AuthController extends Controller
{
    /**
     * Write code on Method
     *
     * @return response()
     */
    
    public function logindata(Request $request): RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        return $this->issueAdminLoginRedirect($request);
    }  

    public function secureLogin(Request $request, string $token): Response|RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        $payload = $this->getValidAdminLoginTokenPayload($request, $token);

        if (! $payload) {
            return $this->issueAdminLoginRedirect(
                $request,
                'Admin login URL expired ya invalid tha. Fresh secure URL generate kiya gaya hai.'
            );
        }

        if (! empty($payload['viewed_at'])) {
            return $this->issueAdminLoginRedirect(
                $request,
                'Page refresh ya back open detect hua. Naya secure admin URL generate kiya gaya hai.'
            );
        }

        $payload['viewed_at'] = now()->toDateTimeString();
        $this->storeAdminLoginToken($token, $payload);

        return response()->view('auth.secure-admin-login', [
            'submitUrl' => route('login.post', ['token' => $token]),
            'tokenRefreshUrl' => route('admin.logindata'),
            'tokenTtlMinutes' => config('security.admin_login_ttl_minutes', 5),
        ])->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
            ->header('Pragma', 'no-cache')
            ->header('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT');
    }

    public function index(): RedirectResponse
    {
        return redirect()->route('admin.logindata');
    }

    private function attachmentUrl(?int $attachmentId, string $fallback): string
    {
        if (! $attachmentId) {
            return $fallback;
        }

        $attachment = Attachment::query()->find($attachmentId);

        return $attachment ? ASSETURL . 'files/' . $attachment->att_url : $fallback;
    }

    private function portalBrandUser(int $userId = 1): ?User
    {
        return User::query()->find($userId);
    }

    private function portalBrandImageUrl(?User $user): string
    {
        return $this->attachmentUrl(
            (int) ($user?->profileimh ?? 0),
            ASSETURL . 'public/frontend/images/logo.png'
        );
    }

    private function publicPortalStats(): array
    {
        return [
            [
                'value' => MatchContest::query()->count(),
                'label' => 'Competitions',
            ],
            [
                'value' => User::query()->where('usertype', 4)->count(),
                'label' => 'Students',
            ],
            [
                'value' => QuestionSetup::query()->count(),
                'label' => 'Exam Sets',
            ],
        ];
    }

    private function safePublicPortalViewData(): array
    {
        $userdata = null;
        $brandImageUrl = ASSETURL . 'public/frontend/images/logo.png';
        $loginStats = [
            ['value' => 0, 'label' => 'Competitions'],
            ['value' => 0, 'label' => 'Students'],
            ['value' => 0, 'label' => 'Exam Sets'],
        ];

        try {
            $userdata = $this->portalBrandUser();
        } catch (Throwable) {
            $userdata = null;
        }

        try {
            $brandImageUrl = $this->portalBrandImageUrl($userdata);
        } catch (Throwable) {
            $brandImageUrl = ASSETURL . 'public/frontend/images/logo.png';
        }

        try {
            $loginStats = $this->publicPortalStats();
        } catch (Throwable) {
            $loginStats = [
                ['value' => 0, 'label' => 'Competitions'],
                ['value' => 0, 'label' => 'Students'],
                ['value' => 0, 'label' => 'Exam Sets'],
            ];
        }

        return compact('userdata', 'brandImageUrl', 'loginStats');
    }

    private function normalizeMobile(?string $mobile): string
    {
        return preg_replace('/\D+/', '', (string) $mobile) ?? '';
    }

    private function looksLikeMobile(string $value): bool
    {
        return preg_match('/^[6-9][0-9]{9}$/', $this->normalizeMobile($value)) === 1;
    }

    private function findUserByMobile(string $mobile, ?array $allowedUserTypes = null): ?User
    {
        $normalizedMobile = $this->normalizeMobile($mobile);

        if ($normalizedMobile === '') {
            return null;
        }

        return User::query()
            ->when($allowedUserTypes, fn ($query) => $query->whereIn('usertype', $allowedUserTypes))
            ->where('mobileno', $normalizedMobile)
            ->first();
    }

    private function resolvePortalLoginUser(string $identifier, array $allowedUserTypes): ?User
    {
        $identifier = trim($identifier);

        if ($this->looksLikeMobile($identifier)) {
            return $this->findUserByMobile($identifier, $allowedUserTypes);
        }

        return User::query()
            ->whereIn('usertype', $allowedUserTypes)
            ->where('email', $identifier)
            ->first();
    }

    private function sendPasswordResetOtp(User $user): void
    {
        $otp = random_int(100000, 999999);
        $user->update(['otpnumber' => $otp]);
        $this->dispatchSmsOtp((string) $user->mobileno, $otp);
    }

    private function dispatchSmsOtp(string $mobile, int $otp): void
    {
        $number = urlencode($mobile);
        $message = rawurlencode(
            "Dear user your registration mobile number verification OTP is {$otp} please do not share the otp with any one. HARIHAR LANGUAGE"
        );
        $smsUrl = 'http://msg.smscluster.com/rest/services/sendSMS/sendGroupSms?AUTH_KEY=f470fdd03171fb2bfe46d29c9f3e936&message='
            . $message
            . '&senderId=HRIHRL&routeId=1&mobileNos='
            . $number;

        try {
            $ch = curl_init($smsUrl);

            if ($ch === false) {
                return;
            }

            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_exec($ch);
            curl_close($ch);
        } catch (Throwable) {
            // Keep the existing flow resilient even if SMS gateway is unavailable locally.
        }
    }

    private function storeForgotPasswordVerification(Request $request, string $mobile): void
    {
        $request->session()->put('forgot_password.mobile', $mobile);
        $request->session()->put('forgot_password.verified_at', now()->timestamp);
    }

    private function clearForgotPasswordVerification(Request $request): void
    {
        $request->session()->forget('forgot_password');
    }

    private function hasValidForgotPasswordVerification(Request $request, string $mobile): bool
    {
        $verifiedMobile = (string) $request->session()->get('forgot_password.mobile', '');
        $verifiedAt = (int) $request->session()->get('forgot_password.verified_at', 0);
        $ttlSeconds = 15 * 60;

        return $verifiedMobile === $mobile
            && $verifiedAt > 0
            && ($verifiedAt + $ttlSeconds) >= now()->timestamp;
    }

    public function caminslogin(Request $request): RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        return $this->issuePortalLoginRedirect($request, 'institute');
    }  

    public function teacherlogin($id): View
    {
        $userdata = User::query()->find($id);

        return view('auth.teacherlogin')->with('userdata',$userdata);
    } 
    
 

    

    public function studentslogin(Request $request): RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        return $this->issuePortalLoginRedirect($request, 'student');
    }

    public function legacyInstituteLoginRedirect(Request $request): RedirectResponse
    {
        return redirect()
            ->route('institute.entry')
            ->withInput($request->except('password'))
            ->with('message', 'Direct institute login endpoint disabled hai. Fresh secure institute login URL use kijiye.');
    }

    public function legacyStudentLoginRedirect(Request $request): RedirectResponse
    {
        return redirect()
            ->route('student.entry')
            ->withInput($request->except('password'))
            ->with('message', 'Direct student login endpoint disabled hai. Fresh secure student login URL use kijiye.');
    }

    public function secureInstituteLogin(Request $request, string $token): Response|RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        $payload = $this->getValidPortalLoginTokenPayload($request, 'institute', $token);

        if (! $payload) {
            return $this->issuePortalLoginRedirect(
                $request,
                'institute',
                'Institute login URL expired ya invalid tha. Fresh secure URL generate kiya gaya hai.'
            );
        }

        if (! empty($payload['viewed_at'])) {
            return $this->issuePortalLoginRedirect(
                $request,
                'institute',
                'Page refresh ya back open detect hua. Naya secure institute URL generate kiya gaya hai.'
            );
        }

        $payload['viewed_at'] = now()->toDateTimeString();
        $this->storePortalLoginToken('institute', $token, $payload);

        ['userdata' => $userdata, 'brandImageUrl' => $brandImageUrl, 'loginStats' => $loginStats] = $this->safePublicPortalViewData();

        return $this->noStoreAuthView('auth.institutelogin', [
            'userdata' => $userdata,
            'brandImageUrl' => $brandImageUrl,
            'loginStats' => $loginStats,
            'loginActionUrl' => route('login.instpostLogin.secure', ['token' => $token]),
            'secureEntryMode' => true,
            'tokenRefreshUrl' => route('institute.entry'),
            'tokenTtlMinutes' => config('security.portal_login_ttl_minutes', 5),
        ]);
    }

    public function secureStudentLogin(Request $request, string $token): Response|RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        $payload = $this->getValidPortalLoginTokenPayload($request, 'student', $token);

        if (! $payload) {
            return $this->issuePortalLoginRedirect(
                $request,
                'student',
                'Student login URL expired ya invalid tha. Fresh secure URL generate kiya gaya hai.'
            );
        }

        if (! empty($payload['viewed_at'])) {
            return $this->issuePortalLoginRedirect(
                $request,
                'student',
                'Page refresh ya back open detect hua. Naya secure student URL generate kiya gaya hai.'
            );
        }

        $payload['viewed_at'] = now()->toDateTimeString();
        $this->storePortalLoginToken('student', $token, $payload);

        ['userdata' => $userdata, 'brandImageUrl' => $brandImageUrl, 'loginStats' => $loginStats] = $this->safePublicPortalViewData();

        return $this->noStoreAuthView('auth.studentslogin', [
            'userdata' => $userdata,
            'brandImageUrl' => $brandImageUrl,
            'loginStats' => $loginStats,
            'loginActionUrl' => route('login.studentpostLogin.secure', ['token' => $token]),
            'secureEntryMode' => true,
            'tokenRefreshUrl' => route('student.entry'),
            'tokenTtlMinutes' => config('security.portal_login_ttl_minutes', 5),
        ]);
    }

    public function loginuser(): View
    {
        $userdata = User::query()->find(114704);

        return view('auth.studentslogin')->with('userdata',$userdata);
    }  

    
    
    
      
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function registration(Request $request): View|RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        return view('auth.register')->with('schoolCode', trim((string) $request->query('schoolcode', 'jel_215617')));
    }

    public function instituteregistration(): View|RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        ['userdata' => $userdata, 'brandImageUrl' => $brandImageUrl, 'loginStats' => $loginStats] = $this->safePublicPortalViewData();

        return view('auth.instituteregistration', [
            'userdata' => $userdata,
            'brandImageUrl' => $brandImageUrl,
            'loginStats' => $loginStats,
        ]);
    }

    public function blockedPortalUser(): View
    {
        ['brandImageUrl' => $brandImageUrl] = $this->safePublicPortalViewData();

        return view('auth.blockuser', [
            'brandImageUrl' => $brandImageUrl,
            'blockedDescription' => 'This institute or school account is currently blocked and cannot open the admin panel right now.',
            'backRouteName' => 'institute.entry',
            'backButtonText' => 'Back to Institute Login',
            'supportSteps' => [
                [
                    'title' => 'Why this screen appeared',
                    'body' => 'The account status is not active, so secure admin access has been stopped automatically.',
                ],
                [
                    'title' => 'What to do next',
                    'body' => 'Please contact the platform administrator to review the account status and reactivate access.',
                ],
            ],
        ]);
    }

    public function blockedStudentPortalUser(): View
    {
        ['brandImageUrl' => $brandImageUrl] = $this->safePublicPortalViewData();

        return view('auth.blockuser', [
            'brandImageUrl' => $brandImageUrl,
            'blockedDescription' => 'This student account is currently blocked and cannot open the competition dashboard right now.',
            'backRouteName' => 'student.entry',
            'backButtonText' => 'Back to Student Login',
            'supportSteps' => [
                [
                    'title' => 'Why this screen appeared',
                    'body' => 'The student account status is not active, so secure exam access has been stopped automatically.',
                ],
                [
                    'title' => 'What to do next',
                    'body' => 'Please contact the institute or platform administrator to review and reactivate this account.',
                ],
            ],
        ]);
    }

    
      
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function postLogin(AdminLoginRequest $request, string $token): RedirectResponse
    {
        if (! $this->consumeAdminLoginToken($request, $token)) {
            Session::flash('message', 'Admin login URL expired ya already use ho chuka hai. Fresh secure URL open kijiye.');

            return redirect()->route('admin.logindata');
        }

        $validated = $request->validated();
        $email = $validated['email'];
        $adminUser = User::query()->where('email', $email)->first();

        if (! $adminUser || ! $this->isPlatformAdminUser($adminUser)) {
            Session::flash('message', 'Invalid admin credentials.');

            return redirect()->route('admin.logindata');
        }

        if ((bool) ($adminUser->admin_is_locked ?? false)) {
            Session::flash('message', 'Admin account permanently locked hai. Database se unlock kijiye.');

            return redirect()->route('admin.logindata');
        }

        if (! Hash::check($validated['password'], (string) $adminUser->password)) {
            $isLockedNow = $this->registerAdminFailure($adminUser->id);

            Session::flash(
                'message',
                $isLockedNow
                    ? '2 wrong attempts ke baad admin account permanently lock ho gaya. Database se unlock kijiye.'
                    : 'Invalid admin credentials. Next wrong attempt par permanent lock lag jayega.'
            );

            return redirect()->route('admin.logindata');
        }

        Auth::login($adminUser);
        $request->session()->regenerate();
        $this->resetAdminFailureState($adminUser->id);

        Session::flash('sucmessage', 'Successful, admin has logged in.');

        return redirect()->route('admin.dashboard');
    }

    public function instpostLogin(InstituteLoginRequest $request, ?string $token = null): RedirectResponse
    {
        if ($token === null) {
            Session::flash('message', 'Old institute login submit URL disabled hai. Fresh secure institute login URL open kijiye.');

            return redirect()->route('institute.entry');
        }

        if ($token !== null && ! $this->consumePortalLoginToken($request, 'institute', $token)) {
            Session::flash('message', 'Institute login URL expired ya already use ho chuka hai. Fresh secure URL open kijiye.');

            return redirect()->route('institute.entry');
        }

        $validated = $request->validated();
        $portalUser = $this->resolvePortalLoginUser($validated['email'], [1, 3]);

        if (! $portalUser) {
            return $this->portalLoginFailureRedirect($request, 'institute', 'Invalid UserEmail/Phone Number Or Password.', $token);
        }

        if (! Auth::attempt(['email' => $portalUser->email, 'password' => $validated['password']])) {
            return $this->portalLoginFailureRedirect($request, 'institute', 'Invalid UserEmail/Phone Number Or Password.', $token);
        }

        $request->session()->regenerate();
        $loggedInUser = Auth::user();

        if (! in_array((int) ($loggedInUser->usertype ?? 0), [1, 3], true)) {
            Auth::logout();
            $request->session()->invalidate();
            $request->session()->regenerateToken();

            return $this->portalLoginFailureRedirect($request, 'institute', 'Invalid UserEmail/Phone Number Or Password.', $token);
        }

        if ((int) ($loggedInUser->status ?? 0) !== 1) {
            Auth::logout();
            $request->session()->invalidate();
            $request->session()->regenerateToken();

            Session::flash('message', 'Sorry, Institute / School has been blocked.');

            return redirect()->route('admin.blockuser');
        }

        $successMessage = match ((int) $loggedInUser->usertype) {
            1 => 'Successful, Institute has logged in.',
            3 => 'Successful, School panel has logged in.',
            default => 'Successful, User has logged in.',
        };

        Session::flash('sucmessage', $successMessage);

        return redirect()->intended(route('admin.dashboard'));
    }


    

    public function studentpostLogin(StudentLoginRequest $request, ?string $token = null): RedirectResponse
    {
        if ($token === null) {
            Session::flash('message', 'Old student login submit URL disabled hai. Fresh secure student login URL open kijiye.');

            return redirect()->route('student.entry');
        }

        if ($token !== null && ! $this->consumePortalLoginToken($request, 'student', $token)) {
            Session::flash('message', 'Student login URL expired ya already use ho chuka hai. Fresh secure URL open kijiye.');

            return redirect()->route('student.entry');
        }

        $validated = $request->validated();
        $studentUser = $this->resolvePortalLoginUser($validated['email'], [4]);

        if (! $studentUser) {
            return $this->portalLoginFailureRedirect($request, 'student', 'Invalid UserEmail/Phone Number Or Password.', $token);
        }

        if (! Auth::attempt([
            'email' => $studentUser->email,
            'password' => $validated['password'],
        ], (bool) ($validated['remember'] ?? false))) {
            return $this->portalLoginFailureRedirect($request, 'student', 'Invalid UserEmail/Phone Number Or Password.', $token);
        }

        $request->session()->regenerate();
        $loggedInUser = Auth::user();

        if ((int) ($loggedInUser->usertype ?? 0) !== 4) {
            Auth::logout();
            $request->session()->invalidate();
            $request->session()->regenerateToken();

            return $this->portalLoginFailureRedirect($request, 'student', 'Invalid UserEmail/Phone Number Or Password.', $token);
        }

        if ((int) ($loggedInUser->status ?? 0) !== 1) {
            Auth::logout();
            $request->session()->invalidate();
            $request->session()->regenerateToken();

            Session::flash('message', 'Sorry, Student account has been blocked.');

            return redirect()->route('student.blockuser');
        }

        Session::flash('sucmessage', 'Successful, Student has logged in.');

        return redirect()->intended(route('competitionlist'));
    }

    
      
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function postRegistration(StudentRegistrationRequest $request): RedirectResponse
    {  
        $validated = $request->validated();

        $user = User::query()->create([
            'name' => $validated['username'],
            'email' => $validated['email'],
            'mobileno' => $validated['mobilenumber'],
            'usertype' => 4,
            'password' => $validated['password'],
            'status' => 1,
            'showpassword' => '',
            'institutecode' => $validated['schoolcode'] ?: 'jel_215617',
            'createdby' => 1,
            'updated_at' => now(),
            'created_at' => now(),
        ]);

        Auth::login($user);
        $request->session()->regenerate();
        Session::flash('sucmessage', 'Successful, User has logged in.');

        return $this->redirectAuthenticatedUser();
    }


    public function instregistrationsave(InstituteRegistrationRequest $request): RedirectResponse
    {  
        $validated = $request->validated();

        User::query()->create([
            'name' => $validated['username'],
            'email' => $validated['email'],
            'mobileno' => $validated['mobilenumber'],
            'usertype' => 3,
            'password' => $validated['password'],
            'status' => 1,
            'showpassword' => '',
            'createdby' => 1,
            'updated_at' => now(),
            'created_at' => now(),
        ]);

        Session::flash('sucmessage', 'Thanks, Institute has registered. After verification panel will be provided to you.');

        return redirect()->intended(route('student.entry'));

 
        /* $credentials = $request->only('email', 'password');
        if (Auth::attempt($credentials)) {
            if (Auth::user()->status == 1) { 
                Session::flash('sucmessage', "Successful,  User has logedin"); 
                return redirect()->intended('/');
                }  

        }  */
    }

    public function sendotp(SendOtpRequest $request): RedirectResponse
    {  
        $validated = $request->validated();
        $studentsdetails = $this->findUserByMobile($validated['mobilenumber']);

        if (! $studentsdetails) {
            Session::flash('message', 'Mobile Number does not exist.');

            return Redirect::back()->withInput();
        }

        $this->sendPasswordResetOtp($studentsdetails);
        $this->clearForgotPasswordVerification($request);

        Session::flash('sucmessage', 'OTP has been sent.');

        return redirect()->route('admin.varifyotp', ['mobile' => $validated['mobilenumber']]);
    }

    
    public function varifyotp(Request $request): View|RedirectResponse
    {
        if (Auth::check()) {
            return $this->redirectAuthenticatedUser();
        }

        $mobile = $this->normalizeMobile((string) $request->query('mobile'));
        if (! $this->looksLikeMobile($mobile)) {
            Session::flash('message', 'Valid mobile number required before OTP verification.');

            return redirect()->route('admin.forgotpassword');
        }

        return view('auth.varifyotp')->with('mobile', $mobile);
    }

    
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function dashboard(): View|RedirectResponse
    {
        if (Auth::check()) {
            return view('admin.dashboard', $this->buildDashboardViewData(Auth::user()));
        }
  
        return redirect()->route('admin.logindata')->with('message', 'Please login to continue.');
    }

    private function buildDashboardViewData(User $user): array
    {
        $userType = (int) ($user->usertype ?? 0);
        $today = now()->toDateString();

        if ($userType === 3) {
            $studentIds = User::query()
                ->where('usertype', 4)
                ->where('institutecode', 'LIKE', '%'.$user->id.'%')
                ->pluck('id');

            $classIds = $studentIds->isEmpty()
                ? collect()
                : StudentProfile::query()
                    ->whereIn('studentid', $studentIds)
                    ->whereNotNull('classid')
                    ->distinct()
                    ->pluck('classid');

            return [
                'dashboardTitle' => 'School Dashboard',
                'dashboardSubtitle' => 'Apne school ke students, payment requests aur competition activity ka quick overview.',
                'dashboardStats' => [
                    [
                        'label' => 'School Students',
                        'value' => $studentIds->count(),
                        'icon' => 'users',
                        'tone' => 'sky',
                        'url' => route('admin.schoolstudents'),
                        'help' => 'Registered students linked to your school',
                    ],
                    [
                        'label' => 'Pending Wallet Requests',
                        'value' => $studentIds->isEmpty()
                            ? 0
                            : WalletHistory::query()->whereIn('userid', $studentIds)->where('status', 2)->count(),
                        'icon' => 'credit-card',
                        'tone' => 'amber',
                        'url' => route('admin.studentpaymentdetails'),
                        'help' => 'Student recharge requests awaiting review',
                    ],
                    [
                        'label' => 'Competition Entries',
                        'value' => $studentIds->isEmpty()
                            ? 0
                            : GameplayHistory::query()->whereIn('userid', $studentIds)->count(),
                        'icon' => 'activity',
                        'tone' => 'mint',
                        'url' => route('admin.studentcompetition'),
                        'help' => 'Total joined exam entries from your students',
                    ],
                    [
                        'label' => 'Active Exam Windows',
                        'value' => $classIds->isEmpty()
                            ? 0
                            : CompetitionAssignment::query()
                                ->whereIn('groupclassid', $classIds)
                                ->where('startdate', '<=', $today)
                                ->where('enddate', '>=', $today)
                                ->count(),
                        'icon' => 'calendar',
                        'tone' => 'rose',
                        'url' => route('admin.studentcompetition'),
                        'help' => 'Open exam assignments for your student classes',
                    ],
                ],
                'dashboardHighlights' => [
                    [
                        'label' => 'School Profile',
                        'value' => 'Keep institute details updated',
                    ],
                    [
                        'label' => 'Competition-wise Report',
                        'value' => 'Track joined contests class wise',
                    ],
                ],
                'dashboardQuickLinks' => [
                    [
                        'label' => 'Edit School Profile',
                        'url' => route('admin.editschoolprofile', ['id' => $user->id]),
                    ],
                    [
                        'label' => 'View Students',
                        'url' => route('admin.schoolstudents'),
                    ],
                    [
                        'label' => 'Payment Details',
                        'url' => route('admin.studentpaymentdetails'),
                    ],
                    [
                        'label' => 'Competition Report',
                        'url' => route('admin.studentcompetition'),
                    ],
                ],
            ];
        }

        return [
            'dashboardTitle' => 'Admin Dashboard',
            'dashboardSubtitle' => 'Platform ka live summary yahan se milega. Students, schools, exams aur requests sab ek jagah.',
            'dashboardStats' => [
                [
                    'label' => 'Total Students',
                    'value' => User::query()->where('usertype', 4)->count(),
                    'icon' => 'users',
                    'tone' => 'sky',
                    'url' => route('admin.usersdetails'),
                    'help' => 'Registered student accounts',
                ],
                [
                    'label' => 'Institutes',
                    'value' => User::query()->whereIn('usertype', [1, 3])->count(),
                    'icon' => 'briefcase',
                    'tone' => 'mint',
                    'url' => route('admin.institutedetails'),
                    'help' => 'School and institute accounts',
                ],
                [
                    'label' => 'Competitions',
                    'value' => MatchContest::query()->count(),
                    'icon' => 'award',
                    'tone' => 'amber',
                    'url' => route('admin.managecontest'),
                    'help' => 'Competition templates configured',
                ],
                [
                    'label' => 'Assigned Exams',
                    'value' => CompetitionAssignment::query()->count(),
                    'icon' => 'clipboard',
                    'tone' => 'rose',
                    'url' => route('admin.assigncompetition'),
                    'help' => 'Competition exams mapped to class groups',
                ],
            ],
            'dashboardHighlights' => [
                [
                    'label' => 'Question Bank',
                    'value' => QuestionManagement::query()->count(),
                ],
                [
                    'label' => 'Question Sets',
                    'value' => QuestionSetup::query()->count(),
                ],
                [
                    'label' => 'Pending Wallet Requests',
                    'value' => WalletHistory::query()->where('status', 2)->count(),
                ],
                [
                    'label' => 'Exam Entries',
                    'value' => GameplayHistory::query()->count(),
                ],
            ],
            'dashboardQuickLinks' => [
                [
                    'label' => 'Students',
                    'url' => route('admin.usersdetails'),
                ],
                [
                    'label' => 'Add Institute',
                    'url' => route('admin.addinstitute'),
                ],
                [
                    'label' => 'Institutes',
                    'url' => route('admin.institutedetails'),
                ],
                [
                    'label' => 'Manage Competitions',
                    'url' => route('admin.managecontest'),
                ],
                [
                    'label' => 'Scholarship Results',
                    'url' => route('admin.scholarshipcompetition'),
                ],
            ],
        ];
    }
    
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function create(array $data)
    {
      return User::create([
        'name' => $data['username'],
        'email' => $data['email'],
        'showpassword' => '',
        'password' => Hash::make($data['password'])
      ]);
    }
    
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function logout(Request $request): RedirectResponse
    {
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect()->route('admin.logindata');
    }

    public function institutelogout(Request $request): RedirectResponse
    {
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect()->route('institute.entry');
    }

    public function teacherlogout(Request $request): RedirectResponse
    {
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect()->route('institute.entry');
    }


    public function studentslogout(Request $request): RedirectResponse
    {
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect()->route('student.entry');
    }

    private function redirectAuthenticatedUser(): RedirectResponse
    {
        $userType = (int) (Auth::user()->usertype ?? 0);

        if ($userType === 4) {
            return redirect()->route('competitionlist');
        }

        return redirect()->route('admin.dashboard');
    }

    private function adminLoginCacheKey(string $token): string
    {
        return 'secure_admin_login:'.$token;
    }

    private function activeAdminLoginCacheKey(string $fingerprint): string
    {
        return 'secure_admin_login_active:'.$fingerprint;
    }

    private function portalLoginEntryRoute(string $portal): string
    {
        return match ($portal) {
            'student' => 'student.entry',
            'institute' => 'institute.entry',
            default => 'admin.logindata',
        };
    }

    private function portalLoginSecureRoute(string $portal): string
    {
        return match ($portal) {
            'student' => 'student.secure.login',
            'institute' => 'institute.secure.login',
            default => 'admin.secure.login',
        };
    }

    private function portalLoginTtlMinutes(string $portal): int
    {
        return $portal === 'admin'
            ? max(1, (int) config('security.admin_login_ttl_minutes', 5))
            : max(1, (int) config('security.portal_login_ttl_minutes', 5));
    }

    private function portalLoginCacheKey(string $portal, string $token): string
    {
        return 'secure_'.$portal.'_login:'.$token;
    }

    private function activePortalLoginCacheKey(string $portal, string $fingerprint): string
    {
        return 'secure_'.$portal.'_login_active:'.$fingerprint;
    }

    private function noStoreAuthView(string $view, array $data): Response
    {
        return response()->view($view, $data)
            ->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
            ->header('Pragma', 'no-cache')
            ->header('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT');
    }

    private function issuePortalLoginRedirect(Request $request, string $portal, ?string $message = null): RedirectResponse
    {
        $fingerprint = $this->requestFingerprint($request);
        $activeTokenKey = $this->activePortalLoginCacheKey($portal, $fingerprint);
        $previousToken = Cache::get($activeTokenKey);

        if (is_string($previousToken) && $previousToken !== '') {
            Cache::forget($this->portalLoginCacheKey($portal, $previousToken));
            Cache::forget($activeTokenKey);
        }

        $token = Str::lower(Str::random(64));
        $expiresAt = now()->addMinutes($this->portalLoginTtlMinutes($portal));
        $payload = [
            'fingerprint' => $fingerprint,
            'issued_at' => now()->toDateTimeString(),
            'expires_at' => $expiresAt->timestamp,
            'viewed_at' => null,
        ];

        Cache::put($this->portalLoginCacheKey($portal, $token), $payload, $expiresAt);
        Cache::put($activeTokenKey, $token, $expiresAt);

        $redirect = redirect()->to(route($this->portalLoginSecureRoute($portal), ['token' => $token]));

        return $message ? $redirect->with('message', $message) : $redirect;
    }

    private function storePortalLoginToken(string $portal, string $token, array $payload): void
    {
        $expiresAtTimestamp = (int) ($payload['expires_at'] ?? 0);
        $secondsRemaining = $expiresAtTimestamp - now()->timestamp;

        if ($secondsRemaining <= 0) {
            $this->forgetPortalLoginToken($portal, $token, $payload['fingerprint'] ?? null);

            return;
        }

        $expiresAt = now()->addSeconds($secondsRemaining);

        Cache::put($this->portalLoginCacheKey($portal, $token), $payload, $expiresAt);

        if (! empty($payload['fingerprint'])) {
            Cache::put($this->activePortalLoginCacheKey($portal, $payload['fingerprint']), $token, $expiresAt);
        }
    }

    private function getValidPortalLoginTokenPayload(Request $request, string $portal, string $token): ?array
    {
        $payload = Cache::get($this->portalLoginCacheKey($portal, $token));
        $fingerprint = $this->requestFingerprint($request);

        if (! is_array($payload)) {
            return null;
        }

        if (($payload['fingerprint'] ?? null) !== $fingerprint) {
            return null;
        }

        if ((int) ($payload['expires_at'] ?? 0) <= now()->timestamp) {
            $this->forgetPortalLoginToken($portal, $token, $fingerprint);

            return null;
        }

        $activeToken = Cache::get($this->activePortalLoginCacheKey($portal, $fingerprint));

        return $activeToken === $token ? $payload : null;
    }

    private function consumePortalLoginToken(Request $request, string $portal, string $token): bool
    {
        if (! $this->getValidPortalLoginTokenPayload($request, $portal, $token)) {
            return false;
        }

        $this->forgetPortalLoginToken($portal, $token, $this->requestFingerprint($request));

        return true;
    }

    private function forgetPortalLoginToken(string $portal, string $token, ?string $fingerprint = null): void
    {
        if (! $fingerprint) {
            $payload = Cache::get($this->portalLoginCacheKey($portal, $token));
            $fingerprint = is_array($payload) ? ($payload['fingerprint'] ?? null) : null;
        }

        Cache::forget($this->portalLoginCacheKey($portal, $token));

        if ($fingerprint) {
            $activeTokenKey = $this->activePortalLoginCacheKey($portal, $fingerprint);

            if (Cache::get($activeTokenKey) === $token) {
                Cache::forget($activeTokenKey);
            }
        }
    }

    private function portalLoginFailureRedirect(Request $request, string $portal, string $message, ?string $token = null): RedirectResponse
    {
        if ($token !== null) {
            return redirect()
                ->route($this->portalLoginEntryRoute($portal))
                ->with('message', $message)
                ->withInput($request->except('password'));
        }

        return Redirect::back()
            ->with('message', $message)
            ->withInput($request->except('password'));
    }

    private function requestFingerprint(Request $request): string
    {
        return hash('sha256', implode('|', [
            $request->ip(),
            (string) $request->userAgent(),
        ]));
    }

    private function issueAdminLoginRedirect(Request $request, ?string $message = null): RedirectResponse
    {
        $fingerprint = $this->requestFingerprint($request);
        $activeTokenKey = $this->activeAdminLoginCacheKey($fingerprint);
        $previousToken = Cache::get($activeTokenKey);

        if (is_string($previousToken) && $previousToken !== '') {
            Cache::forget($this->adminLoginCacheKey($previousToken));
            Cache::forget($activeTokenKey);
        }

        $token = Str::lower(Str::random(64));
        $expiresAt = now()->addMinutes(config('security.admin_login_ttl_minutes', 5));
        $payload = [
            'fingerprint' => $fingerprint,
            'issued_at' => now()->toDateTimeString(),
            'expires_at' => $expiresAt->timestamp,
            'viewed_at' => null,
        ];

        Cache::put($this->adminLoginCacheKey($token), $payload, $expiresAt);
        Cache::put($activeTokenKey, $token, $expiresAt);

        $redirect = redirect()->to(route('admin.secure.login', ['token' => $token]));

        return $message ? $redirect->with('message', $message) : $redirect;
    }

    private function storeAdminLoginToken(string $token, array $payload): void
    {
        $expiresAtTimestamp = (int) ($payload['expires_at'] ?? 0);
        $secondsRemaining = $expiresAtTimestamp - now()->timestamp;

        if ($secondsRemaining <= 0) {
            $this->forgetAdminLoginToken($token, $payload['fingerprint'] ?? null);

            return;
        }

        $expiresAt = now()->addSeconds($secondsRemaining);

        Cache::put($this->adminLoginCacheKey($token), $payload, $expiresAt);

        if (! empty($payload['fingerprint'])) {
            Cache::put($this->activeAdminLoginCacheKey($payload['fingerprint']), $token, $expiresAt);
        }
    }

    private function getValidAdminLoginTokenPayload(Request $request, string $token): ?array
    {
        $payload = Cache::get($this->adminLoginCacheKey($token));
        $fingerprint = $this->requestFingerprint($request);

        if (! is_array($payload)) {
            return null;
        }

        if (($payload['fingerprint'] ?? null) !== $fingerprint) {
            return null;
        }

        if ((int) ($payload['expires_at'] ?? 0) <= now()->timestamp) {
            $this->forgetAdminLoginToken($token, $fingerprint);

            return null;
        }

        $activeToken = Cache::get($this->activeAdminLoginCacheKey($fingerprint));

        return $activeToken === $token ? $payload : null;
    }

    private function hasValidAdminLoginToken(Request $request, string $token): bool
    {
        return $this->getValidAdminLoginTokenPayload($request, $token) !== null;
    }

    private function consumeAdminLoginToken(Request $request, string $token): bool
    {
        if (! $this->hasValidAdminLoginToken($request, $token)) {
            return false;
        }

        $this->forgetAdminLoginToken($token, $this->requestFingerprint($request));

        return true;
    }

    private function forgetAdminLoginToken(string $token, ?string $fingerprint = null): void
    {
        if (! $fingerprint) {
            $payload = Cache::get($this->adminLoginCacheKey($token));
            $fingerprint = is_array($payload) ? ($payload['fingerprint'] ?? null) : null;
        }

        Cache::forget($this->adminLoginCacheKey($token));

        if ($fingerprint) {
            $activeTokenKey = $this->activeAdminLoginCacheKey($fingerprint);

            if (Cache::get($activeTokenKey) === $token) {
                Cache::forget($activeTokenKey);
            }
        }
    }

    private function isPlatformAdminUser(User $user): bool
    {
        return ! in_array((int) ($user->usertype ?? 0), [3, 4, 5], true);
    }

    private function registerAdminFailure(int $userId): bool
    {
        $user = User::query()->find($userId);
        if (! $user) {
            return false;
        }

        $failedAttempts = ((int) ($user->admin_failed_attempts ?? 0)) + 1;
        $maxAttempts = max(1, (int) config('security.admin_max_failed_attempts', 2));
        $isLocked = $failedAttempts >= $maxAttempts;

        $user->update([
            'admin_failed_attempts' => $failedAttempts,
            'admin_is_locked' => $isLocked ? 1 : 0,
            'admin_locked_at' => $isLocked ? now() : null,
        ]);

        return $isLocked;
    }

    private function resetAdminFailureState(int $userId): void
    {
        $user = User::query()->find($userId);

        if (! $user) {
            return;
        }

        $user->update([
            'admin_failed_attempts' => 0,
            'admin_is_locked' => 0,
            'admin_locked_at' => null,
        ]);
    }

    

    ///////////////////
    //// API Details
    ///////////////////



    	/*******	IOS Login	********/	
	
	public function login_ios(Request $request){ 
       
        $savedata =  $request->all();  

       //// echo '<pre>'; print_r(	 $savedata ); echo '</pre>';


        $device_name =  '';  $device_token =  ''; 
        if(isset($savedata['tokannum'])) {  $device_token =  $savedata['tokannum']; }
        // if(isset($savedata['device_name'])) {  $device_name =  $savedata['device_name']; }
   
        date_default_timezone_set("Asia/Calcutta");   //India time (GMT+5:30)
           
           if(is_numeric($savedata['email'])) {
               
               $allradydata = DB::table('users')->where('mobileno', '=', $savedata['email'])->first();
               
               
   
               //$request->email = $allradydata['email'];
               $email = $allradydata->email;
               
               $request->request->replace(['email' =>$email ]);
               
           }
        
           
           //print_r($loginData);
           
           $loginData = $request->validate([
               'email' => 'email|required',
               'password' => 'required'
           ]);
   
           $accessToken = null;
   
           if (!auth()->attempt($loginData)) {
               return response(['message' => 'Phone Number or Password is incorrect', 'response' => '2' ], 400);
           }
    
   
          
          $userhsh =  (auth()->user());  
   
          $userhsh->createdby =   (string)($userhsh->createdby); // $b is now string
   
        ///  settype( $userhsh->createdby, "string" ); 
   
        $userdevicesdetails = '';
               
           ///$userdevicesdetails = DB::table('userdevicesdetails')->where('devicemodalname','=',$device_name)->where('userid', Auth::user()->id)->first();
   
           $userection = DB::table('userdevicesdetails')->where('userid', Auth::user()->id)->first();
   
          
               $updatedatanew = array( 
                   'userid'=>Auth::user()->id,  
                   'devicetokenid'=>$device_token,  
                   'devicemodalname'=>$device_name,  
                   'devivetype'=>'IOS',  
                   'createdtime'=> date("Y-m-d H:i:s"),
           ); 
           DB::table('userdevicesdetails')->insert($updatedatanew);  
          
          
          return response(['user' =>$userhsh, 'message' => 'User logged in successfully', 'response' => '1' ]);
           
           
       }


       //////////////
       ///// Forgot Password
       //////////////
       
       public function forgotpassword(): View|RedirectResponse
       {
           if (Auth::check()) {
               return $this->redirectAuthenticatedUser();
           }

           return view('auth.forgotpassword');
       }

         public function passwordchange(Request $request): View|RedirectResponse
       {
           if (Auth::check()) {
               return $this->redirectAuthenticatedUser();
           }

           $mobile = $this->normalizeMobile((string) $request->query('mobile'));
           if (! $this->hasValidForgotPasswordVerification($request, $mobile)) {
               Session::flash('message', 'OTP verification session expired. Please verify again.');

               return redirect()->route('admin.forgotpassword');
           }

           return view('auth.passwordchange')->with('mobile', $mobile);
       }

       
         

       public function varifyotpsave(VerifyForgotPasswordOtpRequest $request): RedirectResponse
       {  
           $validated = $request->validated();
           $studentsdetails = $this->findUserByMobile($validated['varifymobile']);

           if (! $studentsdetails) {
               Session::flash('message', 'Mobile Number does not exist.');

               return Redirect::back()->withInput();
           }

           if ((string) $studentsdetails->otpnumber !== $validated['userotp']) {
               Session::flash('message', 'OTP Number is invalid.');

               return Redirect::back()->withInput();
           }

           $this->storeForgotPasswordVerification($request, $validated['varifymobile']);
           Session::flash('sucmessage', 'Mobile number has been verified.');

           return redirect()->route('admin.passwordchange', ['mobile' => $validated['varifymobile']]);
        }


           public function passwordsave(ResetForgotPasswordRequest $request): RedirectResponse
       {  
           $validated = $request->validated();
           $mobile = $validated['varifymobile'];

           if (! $this->hasValidForgotPasswordVerification($request, $mobile)) {
               Session::flash('message', 'OTP verification session expired. Please verify again.');

               return redirect()->route('admin.forgotpassword');
           }

           $user = $this->findUserByMobile($mobile);
           if (! $user) {
               Session::flash('message', 'Mobile Number does not exist.');

               return redirect()->route('admin.forgotpassword');
           }

           $user->update([
               'password' => $validated['password'],
               'showpassword' => '',
               'otpnumber' => null,
           ]);

           $this->clearForgotPasswordVerification($request);
           Session::flash('sucmessage', 'Your password has been changed.');

           return redirect()->route('student.entry');
       }

        public function userpasswordsave(UpdateOwnPasswordRequest $request): RedirectResponse
       {  
           $user = User::query()->find(Auth::id());
           if (! $user) {
               return redirect()->route('student.entry')->with('message', 'Please login to continue.');
           }

           $validated = $request->validated();
           $user->update([
               'password' => $validated['password'],
               'showpassword' => '',
           ]);

           Session::flash('sucmessage', 'Your password has been changed.');

           return redirect()->route('competitionlist');
       }

        

       
    
}
