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

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

class Create extends Ideal\Query implements Define\Query\Create
{
    protected string $name;
    protected array $definitions;
    protected array $options;
    protected array $partitions;

    public function table(string $name): Define\Query\Create
    {
        $this->name = $name;
        return $this;
    }
    public function definitions(Define\Query\Create\CreateDefinition|array|string $create_definitions): Define\Query\Create
    {
        if (is_array($create_definitions)) {
            foreach ($create_definitions as $definition) {
                $this->addDefinition($definition);
            }
            return $this;
        }
        return $this->addDefinition($create_definitions);
    }
    public function options(array|string $table_options): Define\Query\Create
    {
        if (is_string($table_options)) {
            return $this->addOption($table_options);
        }
        foreach ($table_options as $option) {
            $this->addOption($option);
        }
        return $this;
    }
    public function partition(array|string $partition_options): Define\Query\Create
    {
        if (is_string($partition_options)) {
            return $this->addPartition($partition_options);
        }
        foreach ($partition_options as $option) {
            $this->addPartition($option);
        }
        return $this;
    }
    public function build(): string
    {
        $query = [
            "CREATE TABLE {$this->name}",
            $this->getDefinitions(),
            $this->getOptions(),
            $this->getPartitions()
        ];
        return implode('', $query);
    }

    protected function addDefinition(string $definition): Create
    {
        if (!isset($this->definitions)) {
            $this->definitions = [];
        }
        $this->definitions []= $definition;
        return $this;
    }
    protected function addOption(string $option): Create
    {
        if (!isset($this->options)) {
            $this->options = [];
        }
        $this->options []= $option;
        return $this;
    }
    protected function addPartition(string $partition): Create
    {
        if (!isset($this->partitions)) {
            $this->partitions = [];
        }
        $this->partitions []= $partition;
        return $this;
    }
    protected function getDefinitions(): string
    {
        return ' (' . implode(', ', $this->definitions) . ')';
    }
    protected function getOptions(): string
    {
        if (!isset($this->options) or count($this->options) <= 0) {
            return '';
        }
        return ' ' . implode(' ', $this->options);
    }
    protected function getPartitions(): string
    {
        if (!isset($this->partitions) or count($this->partitions) <= 0) {
            return '';
        }
        return ' PARTITION BY (' . implode(', ', $this->partitions) . ')';
    }
}
