<?php

namespace Velis\Db;

use Closure;
use Velis\Db\QueryBuilder\Enums\JoinExpressionType;
use Velis\Db\QueryBuilder\Enums\WhereSeparator;

interface QueryBuilderInterface
{
    /**
     * Sets the class that will be used to map the results
     * @param class-string $mapperClass
     */
    public function setMapperClass(string $mapperClass): self;
    /**
     * Sets the table to select from
     * @param \Closure(QueryBuilderInterface):void|\Velis\Db\QueryBuilderInterface|string $table
     */
    public function from(Closure|QueryBuilderInterface|string $table, ?string $as = null): self;
    /**
     * Selects columns to be fetched
     */
    public function select(?array $columns = ['*']): self;
    /**
     * Adds a where clause
     * @param \Closure(QueryBuilderInterface):void|string|array $column
     */
    public function where(Closure|string|array $column, mixed $operator = null, mixed $value = null, WhereSeparator $boolean = WhereSeparator::AND): self;
    public function whereRaw(string $sql, array $bindParams = []): self;
    /**
     * Adds an "or where" clause
     * @param \Closure(QueryBuilderInterface):void|string|array $column
     */
    public function orWhere(Closure|string|array $column, mixed $operator = null, mixed $value = null): self;
    public function join(string $table, string $first, ?string $operator = null, ?string $second = null, JoinExpressionType $type = JoinExpressionType::INNER): self;
    public function limit(int $value): self;
    public function offset(int $value): self;
    public function orderBy(string $field, string $direction = 'ASC'): self;
    public function toSql(): string;
    public function get(): array;
    public function getParams(): array;
}
