<?php

declare(strict_types=1);

namespace Bot\Infrastructure\Repository\Database;

use Bot\Domain\Entity\User;
use Bot\Domain\Repository\UserRepositoryInterface;
use PDO;

final class DatabaseUserRepository implements UserRepositoryInterface
{
    public function __construct(
        private readonly PDO $pdo,
    ) {
    }

    public function findByTelegramId(int $telegramId): ?User
    {
        $stmt = $this->pdo->prepare('SELECT * FROM users WHERE telegram_id = :telegram_id');
        $stmt->execute(['telegram_id' => $telegramId]);
        $row = $stmt->fetch();

        if ($row === false) {
            return null;
        }

        return new User(
            (int) $row['id'],
            (int) $row['telegram_id'],
            $row['mode']
        );
    }

    /**
     * @return User[]
     */
    public function getAll(): array
    {
        $stmt = $this->pdo->query('SELECT * FROM users');
        $rows = $stmt->fetchAll();

        $users = [];
        foreach ($rows as $row) {
            $users[] = new User(
                (int) $row['id'],
                (int) $row['telegram_id'],
                $row['mode']
            );
        }

        return $users;
    }

    public function save(User $user): void
    {
        $id = $user->getId();
        
        if ($id === 0) {
            // Insert
            $stmt = $this->pdo->prepare(
                'INSERT INTO users (telegram_id, mode) VALUES (:telegram_id, :mode)'
            );
            $stmt->execute([
                'telegram_id' => $user->getTelegramId(),
                'mode' => $user->getMode(),
            ]);
            
            // گرفتن ID جدید
            $newId = (int) $this->pdo->lastInsertId();
            // در یک پیاده‌سازی واقعی، باید User جدید با ID برگردانیم
            // اما چون User readonly است، نمی‌توانیم آن را تغییر دهیم
            // این مشکل در استفاده از Database Repository ها وجود دارد
        } else {
            // Update
            $stmt = $this->pdo->prepare(
                'UPDATE users SET mode = :mode WHERE id = :id'
            );
            $stmt->execute([
                'id' => $id,
                'mode' => $user->getMode(),
            ]);
        }
    }
}

