<?php
namespace Bot\Services;

use Bot\Config;
use Bot\Database;
use PDO;

/**
 * Persists conversational state per user so multi-step flows can resume across
 * Telegram messages. States automatically expire after a configurable timeout.
 */
class StateService
{
    private PDO $pdo;
    private int $timeoutMinutes;

    public function __construct()
    {
        $this->pdo = Database::connection();
        $this->timeoutMinutes = (int) Config::get()->getValue('state_timeout_minutes', 10);
    }

    public function setState(int $userId, string $state, array $data = []): void
    {
        $json = $data ? json_encode($data, JSON_THROW_ON_ERROR) : null;
        $stmt = $this->pdo->prepare(
            "INSERT INTO user_states (user_id, state, data, updated_at)
             VALUES (:user_id, :state, :data, NOW())
             ON DUPLICATE KEY UPDATE state = VALUES(state), data = VALUES(data), updated_at = NOW()"
        );
        $stmt->execute([
            ':user_id' => $userId,
            ':state'   => $state,
            ':data'    => $json,
        ]);
    }

    public function clearState(int $userId): void
    {
        $stmt = $this->pdo->prepare('DELETE FROM user_states WHERE user_id = ?');
        $stmt->execute([$userId]);
    }

    /**
     * @return array{state:string,data:?array}|null
     */
    public function getState(int $userId): ?array
    {
        $stmt = $this->pdo->prepare('SELECT state, data, updated_at FROM user_states WHERE user_id = ?');
        $stmt->execute([$userId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            return null;
        }
        if ($this->timeoutMinutes > 0 && strtotime($row['updated_at']) < strtotime('-' . $this->timeoutMinutes . ' minutes')) {
            $this->clearState($userId);
            return null;
        }
        $data = $row['data'] ? json_decode($row['data'], true) : null;
        return [
            'state' => $row['state'],
            'data'  => $data,
        ];
    }
}
