<?php

namespace apexl\Vault\interfaces;

use apexl\Vault\enums\SortDirection;
use apexl\Vault\enums\WhereCondition;
use apexl\Vault\enums\WhereType;
use Closure;
use stdClass;

interface driver
{
    public function executeRaw(string $sql): array;

    public function lastInsertId(): int;

    public function update(string $table): driver;

    public function delete(string $table): driver;

    public function insert(string $table): driver;

    public function describe(string $table): driver;

    public function select(string $table): driver;

    public function selectDistinct(string $table): driver;

    public function fields(?array $fields = null): driver;

    public function keyIsAutoIncrementing(string $keyField, string $table): bool;

    public function createTable(
        string $table,
        stdClass $colList,
        bool $existsCheck = true,
        string $engine = 'INNODB'
    ): driver;

    public function where(
        string $field,
        $value,
        WhereCondition|string $condition = WhereCondition::EQUALS,
        WhereType|string $type = WhereType::AND,
        string $postCondition = ''
    ): driver;

    public function orWhere(
        string $field,
        $value,
        WhereCondition $condition = WhereCondition::EQUALS
    ): driver;

    public function orderBy(string|array $fieldOrMultipleOrderBys, SortDirection $sort = SortDirection::ASC);

    public function limit(int $limit, int $offset = 0);

    public function join(
        string $table,
        string|array $field1,
        ?string $field2 = null,
        WhereCondition|string $condition = WhereCondition::EQUALS,
    ): driver;

    public function leftJoin(
        string $table,
        string|array $field1,
        ?string $field2 = null,
        WhereCondition|string $condition = WhereCondition::EQUALS
    ): driver;

    public function reset(): void;

    public function resetOrderBy(): void;

    public function resetFields(): void;

    public function subQuery(Closure $callback, ?string $alias = null): string;

    public function groupBy(string|array $field): driver;

    public function orWhereMultiple(array $groupedClauses, WhereType|string $type = WhereType::AND): driver;

    public function endWhereGroup(): driver;

    public function startWhereGroup(): driver;

}
