<?php
declare(strict_types=1);
namespace Services;

use Repositories\AuthRepository;
use Repositories\CartRepository;
use RuntimeException;

final class AuthService
{
    public function __construct(private ?AuthRepository $repo = null)
    {
        $this->repo ??= new AuthRepository();
    }

    public function register(array $payload): array
    {
        $email = strtolower(trim((string)($payload['email'] ?? '')));
        if ($this->repo->findByEmail($email)) throw new RuntimeException('Email already registered');
        $id = $this->repo->createUser([
            'name' => trim((string)$payload['name']),
            'email' => $email,
            'phone' => trim((string)($payload['phone'] ?? '')),
            'password_hash' => password_hash((string)$payload['password'], PASSWORD_DEFAULT),
            'role' => 'customer'
        ]);
        return $this->issueToken($id, $payload['guest_session_id'] ?? null);
    }

    public function login(array $payload): array
    {
        $user = $this->repo->findByEmail(strtolower(trim((string)$payload['email'])));
        if (!$user || !password_verify((string)$payload['password'], $user['password_hash'])) throw new RuntimeException('Invalid email or password');
        return $this->issueToken((int)$user['id'], $payload['guest_session_id'] ?? null);
    }

    private function issueToken(int $userId, ?string $guestSession): array
    {
        $token = bin2hex(random_bytes(32));
        $this->repo->createToken($userId, $token);
        if ($guestSession) (new CartRepository())->mergeGuestToUser($guestSession, $userId);
        return ['token' => $token, 'user' => $this->meById($userId)];
    }

    public function logout(?string $token): void
    {
        if ($token) $this->repo->deleteToken($token);
    }

    public function meById(int $id): array
    {
        $db = \Config\Database::connection();
        $stmt = $db->prepare('SELECT id,name,email,phone,role,status FROM users WHERE id=:id LIMIT 1');
        $stmt->execute(['id'=>$id]);
        return $stmt->fetch() ?: [];
    }
}
