<?php
namespace App\Services;

use App\Models\Admin;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\Auth\Access\AuthorizationException;

class ImpersonationService
{
      public function loginAsUser(Admin $admin, User $user): void
      {
            if ($this->isImpersonating()) {
                  throw new AuthorizationException('Already impersonating a user.');
            }

            if ($user->profile?->status === \App\Models\Profile::STATUS_SUSPENDED) {
                  throw new AuthorizationException('Cannot impersonate suspended user.');
            }

            // Store impersonator
            Session::put([
                  'admin_impersonator_id' => $admin->id,
                  'admin_impersonator_from_user' => $user->id, // <-- store the user you were viewing
            ]);

            // Logout admin
            Auth::guard('admin')->logout();

            // Login as user
            Auth::guard('web')->login($user);

            // Prevent session fixation
            Session::regenerate();
      }

      public function leave(): void
      {
            $adminId = Session::pull('admin_impersonator_id');
            $fromUserId = Session::pull('admin_impersonator_from_user'); // clean this too

            if (!$adminId) {
                  throw new AuthorizationException('Not impersonating.');
            }

            // Logout user
            Auth::guard('web')->logout();

            $admin = Admin::findOrFail($adminId);

            // Login admin back
            Auth::guard('admin')->login($admin);

            Session::regenerate();
      }

      public function isImpersonating(): bool
      {
            return Session::has('admin_impersonator_id');
      }

      public function impersonator(): ?Admin
      {
            return $this->isImpersonating()
                  ? Admin::find(Session::get('admin_impersonator_id'))
                  : null;
      }
}
