<?php

class UserRepository
{
    private PDO $pdo;

    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function paginate(int $page = 1, int $limit = 20): array
    {
        $page = max(1, $page);
        $limit = max(1, min($limit, 100));

        $total = (int) $this->pdo->query('SELECT COUNT(*) FROM users')->fetchColumn();
        $totalPages = max(1, (int) ceil($total / $limit));
        $page = min($page, $totalPages);
        $offset = ($page - 1) * $limit;

        $stmt = $this->pdo->prepare(
            'SELECT id, name, email, phone, avatar, country, agent, ip, is_active, role, last_login_at, last_login_ip, created_at, updated_at
             FROM users
             ORDER BY id DESC
             LIMIT :limit OFFSET :offset'
        );
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();

        return [
            'items' => $stmt->fetchAll(),
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => $total,
                'totalPages' => $totalPages,
                'hasNext' => $page < $totalPages,
                'hasPrev' => $page > 1,
            ],
        ];
    }

    public function all(): array
    {
        return $this->paginate(1, 100000)['items'];
    }

    public function findById(int $id): ?array
    {
        $stmt = $this->pdo->prepare('SELECT id, name, email, phone, avatar, country, agent, ip, is_active, role, last_login_at, last_login_ip, created_at, updated_at FROM users WHERE id = :id LIMIT 1');
        $stmt->execute(['id' => $id]);
        $user = $stmt->fetch();
        return $user ?: null;
    }

    public function findByEmail(string $email): ?array
    {
        $stmt = $this->pdo->prepare('SELECT * FROM users WHERE email = :email LIMIT 1');
        $stmt->execute(['email' => $email]);
        $user = $stmt->fetch();
        return $user ?: null;
    }

    public function create(array $data): int
    {
        $stmt = $this->pdo->prepare('INSERT INTO users (name, email, password, phone, avatar, country, agent, ip, is_active, role, created_at, updated_at) VALUES (:name, :email, :password, :phone, :avatar, :country, :agent, :ip, :is_active, :role, NOW(), NOW())');
        $stmt->execute([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => $data['password'],
            'phone' => $data['phone'],
            'avatar' => $data['avatar'],
            'country' => $data['country'],
            'agent' => $data['agent'],
            'ip' => $data['ip'],
            'is_active' => $data['is_active'],
            'role' => $data['role'],
        ]);

        return (int)$this->pdo->lastInsertId();
    }

    public function update(int $id, array $data): void
    {
        $sql = 'UPDATE users SET name = :name, email = :email, phone = :phone, avatar = :avatar, country = :country, agent = :agent, ip = :ip, is_active = :is_active, role = :role, updated_at = NOW()';
        $params = [
            'id' => $id,
            'name' => $data['name'],
            'email' => $data['email'],
            'phone' => $data['phone'],
            'avatar' => $data['avatar'],
            'country' => $data['country'],
            'agent' => $data['agent'],
            'ip' => $data['ip'],
            'is_active' => $data['is_active'],
            'role' => $data['role'],
        ];

        if (!empty($data['password'])) {
            $sql .= ', password = :password';
            $params['password'] = $data['password'];
        }

        $sql .= ' WHERE id = :id';

        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
    }

    public function delete(int $id): void
    {
        $stmt = $this->pdo->prepare('DELETE FROM users WHERE id = :id');
        $stmt->execute(['id' => $id]);
    }
}
