<?php

namespace App\Http\Controllers;

use App\Events\ProfileSwitchEvent;
use App\Models\Admin;
use App\Models\User;
use App\Traits\SwitchGuardTrait;
use Hash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;


class AdminLoginController extends Controller
{
    use SwitchGuardTrait;

    /**
     * Direct link to admin login - can be used in emails
     * Handles the layered authentication flow:
     * 1. If user not authenticated -> redirect to user login first
     * 2. If user authenticated -> set intent and redirect to admin login
     * 3. After admin login -> redirect to intended URL or main page
     */
    public function directLogin(Request $request, $adminId)
    {
        // Validate admin exists and load users
        $admin = Admin::with('users')->find($adminId);
        if (!$admin) {
            abort(404, __('Admin not found'));
        }

        // Get optional intended destination after successful admin login
        $intendedUrl = $request->query('intended');

        // Store intended URL in session if provided
        if ($intendedUrl) {
            session(['admin_login_intended_url' => $intendedUrl]);
        }

        // Check if user is authenticated on web guard
        if (!Auth::guard('web')->check()) {
            // User not logged in - redirect to user login with return URL
            $returnUrl = route('admin.direct-login', ['adminId' => $adminId]);
            if ($intendedUrl) {
                $returnUrl .= '?intended=' . urlencode($intendedUrl);
            }
            // Store in session for Laravel to redirect after login
            session()->put('url.intended', $returnUrl);

            // Get the first user associated with this admin to pre-populate the login form
            $firstUser = $admin->users()->first();

            if ($firstUser) {
                // Build the login URL with the name parameter and localization
                $loginRoute = route('login') . '?name=' . urlencode($firstUser->name);
                $loginUrl = \Mcamara\LaravelLocalization\Facades\LaravelLocalization::getLocalizedURL(null, $loginRoute);
                return redirect($loginUrl);
            }

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

        // User is authenticated - verify they have this admin profile
        $user = Auth::guard('web')->user();
        $userWithRelations = User::with('admins')->find($user->id);

        if (!$userWithRelations || !$userWithRelations->admins->contains('id', $adminId)) {
            abort(403, __('You do not have access to this admin profile'));
        }

        // Set the profile switch intent in session
        session([
            'intended_profile_switch_type' => 'Admin',
            'intended_profile_switch_id' => $adminId,
        ]);

        // Redirect to admin login form
        return redirect()->route('admin.login');
    }

    public function showLoginForm()
    {
        $user = Auth::guard('web')->user();
        $type = session('intended_profile_switch_type');
        $id = session('intended_profile_switch_id');
        $profile = $this->getTargetProfileByTypeAndId($user, $type, $id);
    
        return view('profile-admin.login', ['profile' => $profile]);
    }


    public function login(Request $request)
    {
        $request->validate([
            'password' => 'required',
        ]);

        $user = Auth::guard('web')->user();
        $type = session('intended_profile_switch_type');
        $id = session('intended_profile_switch_id');
        $admin = $this->getTargetProfileByTypeAndId($user, $type, $id);

        if (!$admin) {
            return back()->withErrors(['index' => __('Admin not found')]);
        }

        // Legacy Cyclos password support
        if (!empty($admin->cyclos_salt)) {
            info('Auth attempt using original Cyclos password');
            $concatenated = $admin->cyclos_salt . $request->password;
            $hashedInputPassword = hash("sha256", $concatenated);

            if (strtolower($hashedInputPassword) === strtolower($admin->password)) {
                info('Auth success: Password is verified');
                // Rehash to Laravel hash and remove salt
                $admin->password = \Hash::make($request->password);
                $admin->cyclos_salt = null;
                $admin->save();
                info('Auth success: Cyclos password has been rehashed for next login');
            }
        }

        // Check if the provided password matches the hashed password in the database
        if (\Hash::check($request->password, $admin->password)) {

            $this->switchGuard('admin', $admin);    // log in as admin

            // Remove intended switch from session
            session()->forget(['intended_profile_switch_type', 'intended_profile_switch_id']);

            // Set active profile session as before
            session([
                'activeProfileType'  => get_class($admin),
                'activeProfileId'    => $admin->id,
                'activeProfileName'  => $admin->name,
                'activeProfilePhoto' => $admin->profile_photo_path,
                'last_activity' => now(),
                'profile-switched-notification' => true,
            ]);
            
            // Re-activate profile if inactive
            if (timebank_config('profile_inactive.re-activate_at_login')) {
                if (!$admin->isActive()) {
                    $admin->inactive_at = null;
                    $admin->save();
                    info('Admin re-activated: ' . $admin->name);
                }
            }

            event(new \App\Events\ProfileSwitchEvent($admin));

            // Check for intended URL from direct login flow
            $intendedUrl = session('admin_login_intended_url');
            if ($intendedUrl) {
                session()->forget('admin_login_intended_url');
                return redirect($intendedUrl);
            }

            return redirect()->route('main'); // Or your special admin main page
        }

        info('Auth failed: Input password does not match stored password');
        return back()->withErrors(['password' => __('Invalid admin password')]);
    }

    //TODO: Move to Trait as suggested below.
    /**
     * Helper method to get the target profile model based on the index.
     * Note: This duplicates logic from ProfileSelect::mount. Consider refactoring
     * this logic into a service or trait if used in multiple places.
     */
    private function getTargetProfileByTypeAndId($user, $type, $id)
    {
        if (!$type || !$id) {
            return null;
        }
    
        $userWithRelations = User::with(['organizations', 'banksManaged', 'admins'])->find($user->id);
        if (!$userWithRelations) return null;
    
        if (strtolower($type) === 'organization') {
            return $userWithRelations->organizations->firstWhere('id', $id);
        } elseif (strtolower($type) === 'bank') {
            return $userWithRelations->banksManaged->firstWhere('id', $id);
        } elseif (strtolower($type) === 'admin') {
            return $userWithRelations->admins->firstWhere('id', $id);
        }
        return null;
    }
}
