<?php

namespace App\Services;

use App\Models\AuditLog;
use App\Models\ImpersonationLog;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

class ImpersonationService
{
    public function startImpersonation(User $platformStaff, Tenant $targetTenant, string $reason): User
    {
        // Find tenant owner or admin user to impersonate
        $targetUser = User::where('tenant_id', $targetTenant->id)->first();
        if (! $targetUser) {
            throw new \Exception('Target tenant has no active user accounts to impersonate.');
        }

        // Record Impersonation Log
        $log = ImpersonationLog::create([
            'platform_user_id' => $platformStaff->id,
            'tenant_id' => $targetTenant->id,
            'reason' => $reason,
            'started_at' => now(),
            'ip_address' => request()->ip(),
            'user_agent' => request()->userAgent(),
            'session_id' => session()->getId(),
        ]);

        // Save original platform staff ID in session
        Session::put('impersonator_id', $platformStaff->id);
        Session::put('impersonated_log_id', $log->id);
        Session::put('impersonated_tenant_name', $targetTenant->company_name);

        AuditLog::record('impersonation', 'impersonation.started', $targetTenant, null, ['reason' => $reason, 'staff_id' => $platformStaff->id]);

        // Login as target tenant user
        Auth::login($targetUser);

        return $targetUser;
    }

    public function stopImpersonation(): ?User
    {
        $impersonatorId = Session::get('impersonator_id');
        $logId = Session::get('impersonated_log_id');

        if ($logId) {
            $log = ImpersonationLog::find($logId);
            if ($log) {
                $log->update(['ended_at' => now()]);
            }
        }

        Session::forget(['impersonator_id', 'impersonated_log_id', 'impersonated_tenant_name']);

        if ($impersonatorId) {
            $staff = User::find($impersonatorId);
            if ($staff) {
                Auth::login($staff);
                AuditLog::record('impersonation', 'impersonation.ended', $staff);

                return $staff;
            }
        }

        return null;
    }

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