<?php

namespace App\Listeners;

use App\Events\ProfileSwitchEvent;
use App\Models\User;
use App\Services\CallCreditService;
use App\Services\PresenceService;
use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session;

class LoginSuccessful
{
    protected $presenceService;

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct(PresenceService $presenceService)
    {
        $this->presenceService = $presenceService;
    }

    /**
     * Handle the event.
     *
     * @param  \Illuminate\Auth\Events\Login  $event
     * @return void
     */
    public function handle(Login $event)
    {
        $profile = $event->user;
        $guard = $event->guard ?? 'web';

        // Log out other guards when logging in to ensure clean state
        $this->logoutOtherGuards($guard);

        $firstName = explode(' ', $event->user->full_name)[0];
        // Store translation key and data instead of pre-translated message
        // This allows the message to be translated in the correct locale after redirect
        Session::flash('login-success-data', ['name' => $firstName]);

        // Set session properties
        Session([
                'activeProfileType' => get_class($profile),
                'activeProfileId' => $profile->id,
                'activeProfileName' => $profile->name,
                'activeProfilePhoto' => $profile->profile_photo_path,
                'active_guard' => $guard, // Set the active guard
               'activeProfileAccounts' => (method_exists($profile, 'accounts') && $profile->accounts())
                    ? $profile->accounts()->pluck('id')->toArray()
                    : [],
                    ]);

        $activeProfile = [
                    'userId' => $profile->id,
                    'type' => Session('activeProfileType'),
                    'id' => Session('activeProfileId'),
                    'name' => Session('activeProfileName'),
                    'photo' => Session('activeProfilePhoto')
                ];

        activity()
            ->useLog('Active profile')
            ->performedOn($profile)
            ->causedBy(Auth::guard('web')->user())
            ->withProperties([
                'attributes' => [
                    'login_ip'=> $profile->last_login_ip,
                    'login_at' => now()->toDateTimeString(),
                ],
                'old' => [
                    'login_at' => ($profile->last_login_at instanceof \Carbon\Carbon)
                        ? $profile->last_login_at->toDateTimeString()
                        : $profile->last_login_at,
                ],
            ])
            ->event('login')
            ->log('Logged in as ' . $profile->name);

        // Check if profile is using a default password
        $this->checkDefaultPassword();

        // Check if 2FA is required but not enabled
        $this->checkTwoFactorAuthentication();

        // Update presence to track login
        $this->presenceService->updatePresence($profile, $event->guard ?? 'web');

        // Pause calls if profile no longer has sufficient credits
        if (!CallCreditService::profileHasCredits(get_class($profile), $profile->id)) {
            CallCreditService::pauseAllActiveCalls(get_class($profile), $profile->id);
        }
    }

    /**
     * Log out all guards except the one being logged into
     * Special rule: Keep web guard authenticated when logging into admin/bank/organization
     * because these profiles require the base web user to remain authenticated
     */
    private function logoutOtherGuards($currentGuard)
    {
        $allGuards = ['web', 'admin', 'bank', 'organization'];

        foreach ($allGuards as $guard) {
            // Skip if this is the current guard
            if ($guard === $currentGuard) {
                continue;
            }

            // Special rule: Keep web guard when logging into admin, bank, or organization
            // because these profiles are linked to the web user
            if ($guard === 'web' && in_array($currentGuard, ['admin', 'bank', 'organization'])) {
                continue;
            }

            // Log out non-web guards when logging into web
            if (Auth::guard($guard)->check()) {
                $user = Auth::guard($guard)->user();

                // Set user offline before logging out
                $this->presenceService->setUserOffline($user, $guard);

                // Clear presence caches
                Cache::forget("presence_{$guard}_{$user->id}");
                Cache::forget("presence_last_update_{$guard}_{$user->id}");

                // Logout from this guard
                Auth::guard($guard)->logout();
            }
        }
    }

    /**
     * Check if the current profile is using a default password
     */
    private function checkDefaultPassword()
    {
        $currentProfile = getActiveProfile();

        if ($currentProfile && isset($currentProfile->password)) {
            $defaultPasswords = timebank_config('init_passwords');

            foreach ($defaultPasswords as $defaultPassword) {
                if (Hash::check($defaultPassword, $currentProfile->password)) {
                    Session::flash('notification.alert', __('You are still using a default password. Please change it immediately for security reasons. Edit your profile settings to update your password.'));
                    break;
                }
            }
        }
    }

    /**
     * Check if two-factor authentication is required but not enabled
     */
    private function checkTwoFactorAuthentication()
    {
        $currentUser = Auth::guard('web')->user();
        $activeProfileType = session('activeProfileType');
        $isTwoFactorEnabled = $currentUser && !is_null($currentUser->two_factor_secret) && !is_null($currentUser->two_factor_confirmed_at);

        $profileTypeToCheck = '';
        if (is_string($activeProfileType)) {
            if (str_contains(strtolower($activeProfileType), 'admin')) {
                $profileTypeToCheck = 'admin';
            } elseif (str_contains(strtolower($activeProfileType), 'bank')) {
                $profileTypeToCheck = 'bank';
            }
        }

        $showTwoFactorPrompt = $currentUser && in_array($profileTypeToCheck, ['admin', 'bank']) && !$isTwoFactorEnabled;

        if ($showTwoFactorPrompt) {
            Session::flash('notification.alert', __('Two-factor authentication is strongly advised for admin and bank profiles. Please enable it in your profile settings for enhanced protection.'));
        }
    }
}
