<?php

namespace App\Http\Controllers;

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


class OrganizationLoginController extends Controller
{
    use SwitchGuardTrait;

    /**
     * Direct link to organization profile - can be used in emails
     * Organizations don't require password re-authentication
     * Handles the authentication flow:
     * 1. If user not authenticated -> redirect to user login first
     * 2. If user authenticated -> verify access and switch to organization
     * 3. Redirect to intended URL or main page
     */
    public function directLogin(Request $request, $organizationId)
    {
        // Validate organization exists and load managers
        $organization = Organization::with('managers')->find($organizationId);
        if (!$organization) {
            abort(404, __('Organization not found'));
        }

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

        // 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('organization.direct-login', ['organizationId' => $organizationId]);
            if ($intendedUrl) {
                $returnUrl .= '?intended=' . urlencode($intendedUrl);
            }
            // Store in session for Laravel to redirect after login
            session()->put('url.intended', $returnUrl);

            // Get the first manager's name to pre-populate the login form
            $firstManager = $organization->managers()->first();

            \Log::info('OrganizationLoginController: Redirecting unauthenticated user', [
                'organization_id' => $organizationId,
                'manager_found' => $firstManager ? 'yes' : 'no',
                'manager_name' => $firstManager ? $firstManager->name : null,
            ]);

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

                \Log::info('OrganizationLoginController: Redirect URL', [
                    'url' => $loginUrl,
                ]);

                return redirect($loginUrl);
            }

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

        // User is authenticated - verify they own/manage this organization
        $user = Auth::guard('web')->user();
        $userWithRelations = User::with('organizations')->find($user->id);

        if (!$userWithRelations || !$userWithRelations->organizations->contains('id', $organizationId)) {
            abort(403, __('You do not have access to this organization'));
        }

        // Switch to organization guard directly (no password required for organizations)
        $this->switchGuard('organization', $organization);

        // Set active profile session
        session([
            'activeProfileType'  => get_class($organization),
            'activeProfileId'    => $organization->id,
            'activeProfileName'  => $organization->name,
            'activeProfilePhoto' => $organization->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 (!$organization->isActive()) {
                $organization->inactive_at = null;
                $organization->save();
                info('Organization re-activated: ' . $organization->name);
            }
        }

        // Broadcast profile switch event
        event(new \App\Events\ProfileSwitchEvent($organization));

        // Redirect to intended URL or main page
        if ($intendedUrl) {
            return redirect($intendedUrl);
        }

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

    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-organization.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');
        $organization = $this->getTargetProfileByTypeAndId($user, $type, $id);

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

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

            if (strtolower($hashedInputPassword) === strtolower($organization->password)) {
                info('Auth success: Password is verified');
                // Rehash to Laravel hash and remove salt
                $organization->password = \Hash::make($request->password);
                $organization->cyclos_salt = null;
                $organization->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, $organization->password)) {

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

            // 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($organization),
                'activeProfileId'    => $organization->id,
                'activeProfileName'  => $organization->name,
                'activeProfilePhoto' => $organization->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 (!$organization->isActive()) {
                    $organization->inactive_at = null;
                    $organization->save();
                    info('Organization re-activated: ' . $organization->name);
                }
            }

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

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

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

        info('Auth failed: Input password does not match stored password');
        return back()->withErrors(['password' => __('Invalid organization 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;
    }
}
