<?php

namespace App\Repositories;

/**
 * Acesso direto às tabelas de sistema do Firebird (RDB$).
 * Retorna apenas dados brutos — sem lógica de negócio.
 */
class TabelasRepository
{
    public function __construct(private \PDO $pdo) {}

    // -------------------------------------------------------------------------
    // Tabelas
    // -------------------------------------------------------------------------

    /**
     * Lista todas as tabelas de usuário do banco.
     *
     * @return array<array{nome: string, descricao: string}>
     */
    public function listarTabelas(): array
    {
        $sql = "
            SELECT
                TRIM(r.RDB\$RELATION_NAME)   AS nome,
                TRIM(COALESCE(r.RDB\$DESCRIPTION, '')) AS descricao
            FROM RDB\$RELATIONS r
            WHERE r.RDB\$SYSTEM_FLAG = 0
              AND r.RDB\$VIEW_BLR IS NULL
            ORDER BY r.RDB\$RELATION_NAME
        ";

        return $this->pdo->query($sql)->fetchAll();
    }

    // -------------------------------------------------------------------------
    // Colunas
    // -------------------------------------------------------------------------

    /**
     * Retorna as colunas de uma tabela específica com metadados de tipo.
     *
     * @return array<array{
     *   campo: string,
     *   tipo_cod: int,
     *   sub_tipo: int,
     *   tamanho: int,
     *   precisao: int,
     *   escala: int,
     *   permite_nulo: int,
     *   valor_padrao: string
     * }>
     */
    public function colunas(string $tabela): array
    {
        $sql = "
            SELECT
                TRIM(rf.RDB\$FIELD_NAME)                          AS campo,
                f.RDB\$FIELD_TYPE                                 AS tipo_cod,
                COALESCE(f.RDB\$FIELD_SUB_TYPE, 0)               AS sub_tipo,
                COALESCE(f.RDB\$FIELD_LENGTH, 0)                  AS tamanho,
                COALESCE(f.RDB\$FIELD_PRECISION, 0)               AS precisao,
                ABS(COALESCE(f.RDB\$FIELD_SCALE, 0))              AS escala,
                CASE WHEN rf.RDB\$NULL_FLAG = 1 THEN 0 ELSE 1 END AS permite_nulo,
                TRIM(COALESCE(rf.RDB\$DEFAULT_SOURCE, ''))         AS valor_padrao
            FROM RDB\$RELATION_FIELDS rf
            JOIN RDB\$FIELDS f ON rf.RDB\$FIELD_SOURCE = f.RDB\$FIELD_NAME
            WHERE TRIM(rf.RDB\$RELATION_NAME) = ?
            ORDER BY rf.RDB\$FIELD_POSITION
        ";

        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([$tabela]);
        return $stmt->fetchAll();
    }

    // -------------------------------------------------------------------------
    // Contagem
    // -------------------------------------------------------------------------

    /**
     * Conta os registros de uma tabela.
     * Retorna -1 em caso de erro (tabela vazia/bloqueada).
     */
    public function contarRegistros(string $tabela): int
    {
        // Sanitiza: apenas letras, números e underscore (Firebird não aceita outros)
        if (!preg_match('/^[A-Z0-9_$]+$/i', $tabela)) {
            return -1;
        }

        try {
            $stmt = $this->pdo->query("SELECT COUNT(*) FROM \"{$tabela}\"");
            return (int) $stmt->fetchColumn();
        } catch (\PDOException) {
            return -1;
        }
    }

    // -------------------------------------------------------------------------
    // Primeiras linhas (preview)
    // -------------------------------------------------------------------------

    /**
     * Retorna as primeiras $limite linhas de uma tabela para preview.
     */
    public function primeirasLinhas(string $tabela, int $limite = 10): array
    {
        if (!preg_match('/^[A-Z0-9_$]+$/i', $tabela)) {
            return [];
        }

        try {
            $stmt = $this->pdo->query(
                "SELECT FIRST {$limite} * FROM \"{$tabela}\""
            );
            return $stmt->fetchAll();
        } catch (\PDOException) {
            return [];
        }
    }
}
