<?php

namespace Modules\SaasSwitcher\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Modules\SaasSwitcher\Support\ProjectRegistry;

/**
 * SaaS super-admin entry point.
 *
 * super-admin signs in (default `mysql` = host project DB) → /saas chooser →
 * pick a project → /saas/users dev-user picker (queried on the project
 * connection) → impersonate a user → /home inside that project.
 */
class SaasController extends Controller
{
    private function sessionKey(): string       { return config('saasswitcher.session_key', 'saas_project'); }
    private function adminKey(): string         { return config('saasswitcher.admin_key', 'saas_admin_id'); }
    private function impersonatingKey(): string { return config('saasswitcher.impersonating_key', 'saas_impersonating'); }

    /** Hard gate: only the host super-admin may use the SaaS switcher. */
    private function assertSuperAdmin(): void
    {
        DB::setDefaultConnection('mysql');
        abort_unless(Auth::check() && Auth::user()->can('superadmin'), 403, 'Super-admin only.');
    }

    /** One page after login: choose the project. */
    public function chooser()
    {
        $this->assertSuperAdmin();
        session()->forget($this->sessionKey());

        return view('saasswitcher::choose', [
            'projects'  => ProjectRegistry::all(),
            'adminName' => Auth::user()->surname ?? Auth::user()->username ?? 'Super Admin',
        ]);
    }

    /** Record the chosen project, then go to the dev-user picker. */
    public function select(string $key)
    {
        $this->assertSuperAdmin();
        abort_unless(ProjectRegistry::exists($key), 404);

        session([
            $this->sessionKey() => $key,
            $this->adminKey()   => Auth::id(),
        ]);

        return redirect()->route('saas.users');
    }

    /** Dev-test user picker for the chosen project (queried on its connection). */
    public function users()
    {
        $key = session($this->sessionKey());
        abort_unless($key && ProjectRegistry::exists($key) && session($this->adminKey()), 403);

        $project = ProjectRegistry::get($key);

        // Super-admin is still authenticated on the host connection, so query
        // the project's users explicitly on its connection (no default swap).
        $users = User::on($project['connection'])
            ->select('id', 'username', 'surname', 'first_name', 'email', 'business_id', 'user_type')
            ->orderBy('id')
            ->limit(200)
            ->get();

        return view('saasswitcher::users', compact('project', 'users'));
    }

    /** Impersonate the selected user inside the chosen project. */
    public function loginAs(Request $request, int $id)
    {
        $key = session($this->sessionKey());
        abort_unless($key && ProjectRegistry::exists($key) && session($this->adminKey()), 403);

        $connection = ProjectRegistry::connection($key);
        $user = User::on($connection)->findOrFail($id);

        // Fully clear the session (not just regenerate the id) so NONE of the
        // super-admin's stale ERP context — business, financial year, currency,
        // dates — leaks into the impersonated project user and breaks /home.
        // (Mirrors the ERP's own dev-login, which invalidates before Auth::login.)
        $adminId = session($this->adminKey());
        $request->session()->invalidate();
        session([
            $this->sessionKey()        => $key,
            $this->adminKey()          => $adminId,
            $this->impersonatingKey()  => true,
        ]);

        Auth::login($user);

        // Module visibility is now driven per-business by module_entitlements
        // (Modules\SaasSwitcher\Support\ModuleEntitlementService), not by a cookie. The active
        // project lives in the session ($this->sessionKey()) which
        // ResolveProjectConnection reads to switch the DB connection.

        return redirect('/home');
    }

    /** Drop the impersonation + project and return to the chooser. */
    public function exitProject(Request $request)
    {
        Auth::logout();
        $request->session()->forget([$this->sessionKey(), $this->impersonatingKey()]);

        return redirect()->route('saas.chooser');
    }
}
