<?php

declare(strict_types=1);

namespace Flowaxy\Domain\User\Services;

use Flowaxy\Contracts\Domain\User\UserRepositoryInterface;
use Flowaxy\Support\Facades\Hash;
use Flowaxy\Support\Facades\Log;
use Throwable;

use function bin2hex;
use function date;
use function random_bytes;

// Сервіс аутентифікації користувача
final class AuthenticateUserService
{
    public function __construct(private readonly UserRepositoryInterface $users)
    {
    }

    public function execute(string $username, string $password): AuthenticationResult
    {
        if ($username === '' || $password === '') {
            try {
                Log::Warning('AuthenticateUserService: Empty username or password');
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return new AuthenticationResult(false, message: 'Заповніть всі поля');
        }

        $users = $this->users->findAll(['username' => $username]);
        $user = $users[0] ?? null;
        if ($user === null) {
            try {
                Log::Warning('AuthenticateUserService: User not found', ['username' => $username]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return new AuthenticationResult(false, message: 'Невірний логін або пароль');
        }

        $passwordHash = $user->passwordHash ?? '';
        if (empty($passwordHash)) {
            try {
                Log::Error('AuthenticateUserService: Password hash is empty', [
                    'user_id' => $user->id,
                    'username' => $username
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return new AuthenticationResult(false, message: 'Невірний логін або пароль');
        }

        if (!($user->isActive ?? false)) {
            try {
                Log::Warning('AuthenticateUserService: User is inactive', [
                    'user_id' => $user->id,
                    'username' => $username
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return new AuthenticationResult(false, message: 'Невірний логін або пароль');
        }

        if (!Hash::check($password, $passwordHash)) {
            try {
                Log::Warning('AuthenticateUserService: Password verification failed', [
                    'user_id' => $user->id,
                    'username' => $username,
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
            return new AuthenticationResult(false, message: 'Невірний логін або пароль');
        }

        $sessionToken = bin2hex(random_bytes(32));
        $now = date('Y-m-d H:i:s');

        return new AuthenticationResult(true, userId: $user->id);
    }
}
