<?php

declare(strict_types=1);

namespace Apexl\Vault\Results;

use Apexl\Vault\Interfaces\ResultInterface;
use PDO;
use PDOStatement;
use stdClass;

/**
 * A PDOStatement that has already been executed, and the error state it reported.
 *
 * Owns its statement outright: nothing else holds a reference, so a later query on
 * the builder that produced it cannot reach in and replace it.
 */
final class PdoResult implements ResultInterface
{
    /**
     * @param string[] $error errorInfo() as read immediately after execution — kept
     *                        because PDO reports it per-statement, and the statement
     *                        is no longer reachable from the builder.
     */
    public function __construct(
        private readonly PDOStatement $statement,
        private readonly array $error = ['00000', null, null],
    ) {}

    public function statement(): PDOStatement
    {
        return $this->statement;
    }

    /** @return string[] */
    public function error(): array
    {
        return $this->error;
    }

    public function succeeded(): bool
    {
        return ($this->error[0] ?? '00000') === '00000';
    }

    public function fetch(): stdClass|false
    {
        return $this->statement->fetch(PDO::FETCH_OBJ);
    }

    public function fetchColumn(int $ix = 0): mixed
    {
        return $this->statement->fetchColumn($ix);
    }

    public function fetchAll(): array|false
    {
        return $this->statement->fetchAll(PDO::FETCH_OBJ);
    }

    public function fetchAllAssoc(): array|false
    {
        return $this->statement->fetchAll(PDO::FETCH_ASSOC);
    }

    public function fetchAssoc(): array|false
    {
        return $this->statement->fetch(PDO::FETCH_ASSOC);
    }

    public function rowCount(): int
    {
        return $this->statement->rowCount();
    }
}
