<?php

declare(strict_types=1);

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\ChangePasswordRequest;
use App\Models\User;
use App\Services\AuditLogger;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

/**
 * Lets a user set their own password.
 *
 * Serves both the voluntary change (from the profile menu) and the forced
 * change after a master has issued a temporary password. The two differ only in
 * whether the current password is required.
 */
class PasswordChangeController extends Controller
{
    public function show(Request $request): View
    {
        /** @var User $user */
        $user = $request->user();

        return view('auth.password-change', [
            'forced' => $user->must_change_password,
        ]);
    }

    public function update(ChangePasswordRequest $request, AuditLogger $auditLogger): RedirectResponse
    {
        /** @var User $user */
        $user = $request->user();

        $wasForced = $user->must_change_password;

        /*
         | The automatic "updated" entry would say only that a masked value
         | changed. The explicit entry below says who changed their password,
         | which is what the audit trail is read for.
         */
        $user->disableAuditing();

        $user->password = (string) $request->string('password');
        $user->must_change_password = false;
        $user->password_changed_at = now();
        $user->save();

        $user->enableAuditing();

        /*
         | Every other session for this account is destroyed. After a forced
         | change this is the point of the exercise: the master who issued the
         | temporary password must not retain a usable session.
         */
        $user->terminateSessions(exceptSessionId: $request->session()->getId());

        $auditLogger->passwordChanged($user);

        return redirect()
            ->to((string) config('ams.auth.home_path'))
            ->with('success', $wasForced
                ? __('Your password has been set. Welcome to Aumni AMS.')
                : __('Your password has been changed.'));
    }
}
