<?php

namespace App\Http\Controllers;

use App\Models\AuditLog;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
use Illuminate\View\View;

class AuthController extends Controller
{
    public function create(): View|RedirectResponse
    {
        return Auth::check() ? redirect()->route('dashboard') : view('auth.login');
    }

    public function store(Request $request): RedirectResponse
    {
        $credentials = $request->validate([
            'identity' => ['required', 'string', 'max:255'],
            'password' => ['required', 'string'],
        ], [
            'identity.required' => 'Introduza o email ou nome de utilizador.',
            'password.required' => 'Introduza a palavra-passe.',
        ]);

        $user = User::query()
            ->where('email', $credentials['identity'])
            ->orWhere('username', $credentials['identity'])
            ->first();

        if ($user?->locked_until) {
            return back()->withErrors(['identity' => 'Esta conta está bloqueada. Contacte um administrador autorizado.'])->onlyInput('identity');
        }

        if (! $user || ! $user->is_active || ! Hash::check($credentials['password'], $user->password)) {
            if ($user) {
                $attempts = $user->failed_login_attempts + 1;
                $maximum = config('nestab.security.maximum_login_attempts', 5);
                $user->forceFill([
                    'failed_login_attempts' => $attempts,
                    'locked_until' => $attempts >= $maximum ? now() : null,
                ])->saveQuietly();

                AuditLog::query()->create([
                    'actor_id' => $user->id,
                    'event' => $attempts >= $maximum ? 'conta_bloqueada' : 'login_falhado',
                    'description' => 'Tentativa de acesso sem sucesso',
                    'metadata' => ['attempts' => $attempts],
                    'ip_address' => $request->ip(),
                    'user_agent' => $request->userAgent(),
                ]);
            }

            return back()->withErrors(['identity' => 'Credenciais inválidas.'])->onlyInput('identity');
        }

        Auth::login($user, false);
        $request->session()->regenerate();
        $request->session()->put('operating_mode', 'operation');

        $primaryAssignment = $user->assignments()->where('is_primary', true)->where('is_active', true)->first();
        $request->session()->put('active_branch_id', $primaryAssignment?->branch_id);

        $user->forceFill([
            'failed_login_attempts' => 0,
            'locked_until' => null,
            'last_login_at' => now(),
            'last_seen_at' => now(),
        ])->saveQuietly();

        AuditLog::query()->create([
            'actor_id' => $user->id,
            'branch_id' => session('active_branch_id'),
            'event' => 'login',
            'description' => 'Sessão iniciada em Modo Normal',
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
        ]);

        return redirect()->intended(route('dashboard'));
    }

    public function editPassword(): View
    {
        return view('auth.change-password');
    }

    public function updatePassword(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'current_password' => ['required', 'current_password'],
            'password' => [
                'required', 'confirmed', 'different:current_password',
                Password::min(6)->mixedCase()->numbers(),
            ],
        ], [
            'current_password.current_password' => 'A palavra-passe actual não está correcta.',
            'password.confirmed' => 'A confirmação da nova palavra-passe não coincide.',
            'password.different' => 'A nova palavra-passe deve ser diferente da actual.',
        ]);

        $request->user()->forceFill([
            'password' => Hash::make($validated['password']),
            'must_change_password' => false,
        ])->save();

        return redirect()->route('dashboard')->with('success', 'Palavra-passe actualizada com sucesso.');
    }

    public function destroy(Request $request): RedirectResponse
    {
        AuditLog::query()->create([
            'actor_id' => $request->user()->id,
            'branch_id' => session('active_branch_id'),
            'event' => 'logout',
            'description' => 'Sessão terminada',
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
        ]);

        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

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