<?php
namespace Incoviba\Common\Implement\Database\Query;

use Incoviba\Common\Define;
use Incoviba\Common\Ideal;

class Update extends Ideal\Query implements Define\Query\Update
{
    protected string $table;
    protected array $setPairs;
    protected array $conditions;
    protected array $orders;
    protected int $limit;

    public function table(string $table): Define\Query\Update
    {
        $this->table = $table;
        return $this;
    }
    public function set(array|string $column_pairs): Define\Query\Update
    {
        if (is_string($column_pairs)) {
            return $this->addSet($column_pairs);
        }
        foreach ($column_pairs as $pair) {
            $this->addSet($pair);
        }
        return $this;
    }
    public function where(array|string $conditions): Define\Query\Update
    {
        if (is_string($conditions)) {
            return $this->addCondition($conditions);
        }
        foreach ($conditions as $condition) {
            $this->addCondition($condition);
        }
        return $this;
    }
    public function order(array|string $ordering): Define\Query\Update
    {
        if (is_string($ordering)) {
            return $this->addOrder($ordering);
        }
        foreach ($ordering as $order) {
            $this->addOrder($order);
        }
        return $this;
    }
    public function limit(int $limit): Define\Query\Update
    {
        $this->limit = $limit;
        return $this;
    }
    public function build(): string
    {
        $query = [
            "UPDATE {$this->table}",
            $this->getSet(),
            $this->getConditions(),
            $this->getOrder(),
            $this->getLimit()
        ];
        return implode('', $query);
    }

    protected function addSet(string $pair): Update
    {
        if (!isset($this->setPairs)) {
            $this->setPairs = [];
        }
        $this->setPairs []= $pair;
        return $this;
    }
    protected function addCondition(string $condition): Update
    {
        if (!isset($this->conditions)) {
            $this->conditions = [];
        }
        $this->conditions []= $condition;
        return $this;
    }
    protected function addOrder(string $order): Update
    {
        if (!isset($this->orders)) {
            $this->orders = [];
        }
        $this->orders []= $order;
        return $this;
    }
    protected function getSet(): string
    {
        return ' SET ' . implode(', ', $this->setPairs);
    }
    protected function getConditions(): string
    {
        return ' WHERE ' . implode(' AND ', $this->conditions);
    }
    protected function getOrder(): string
    {
        if (!isset($this->orders) or count($this->orders) === 0) {
            return '';
        }
        return ' ORDER BY ' . implode(', ', $this->orders);
    }
    protected function getLimit(): string
    {
        if (!isset($this->limit) or $this->limit <= 0) {
            return '';
        }
        return " LIMIT {$this->limit}";
    }
}
