<?php

declare(strict_types=1);

namespace App\Framework\Database\Schema;

use App\Framework\Database\ValueObjects\ColumnName;

/**
 * Column definition with fluent modifiers
 */
final class ColumnDefinition
{
    public readonly string $type;

    public readonly ColumnName $name;

    public readonly array $parameters;

    public bool $nullable = false;

    public mixed $default = null;

    public bool $hasDefault = false;

    public bool $autoIncrement = false;

    public bool $unsigned = false;

    public bool $unique = false;

    public bool $primary = false;

    public bool $index = false;

    public ?string $comment = null;

    public ?string $after = null;

    public bool $first = false;

    public ?string $charset = null;

    public ?string $collation = null;

    public bool $isGenerated = false;

    public ?string $generatedExpression = null;

    public function __construct(string $type, string|ColumnName $name, array $parameters = [])
    {
        $this->type = $type;
        $this->name = $name instanceof ColumnName ? $name : ColumnName::fromString($name);
        $this->parameters = $parameters;
    }

    /**
     * Fluent modifiers
     */
    public function nullable(bool $nullable = true): self
    {
        $this->nullable = $nullable;

        return $this;
    }

    public function default(mixed $value): self
    {
        $this->default = $value;
        $this->hasDefault = true;

        return $this;
    }

    public function useCurrent(): self
    {
        return $this->default('CURRENT_TIMESTAMP');
    }

    public function uuidDefault(): self
    {
        return $this->default('gen_random_uuid()');
    }

    public function autoIncrement(): self
    {
        $this->autoIncrement = true;

        return $this;
    }

    public function unsigned(): self
    {
        $this->unsigned = true;

        return $this;
    }

    public function unique(): self
    {
        $this->unique = true;

        return $this;
    }

    public function primary(): self
    {
        $this->primary = true;

        return $this;
    }

    public function index(): self
    {
        $this->index = true;

        return $this;
    }

    public function comment(string $comment): self
    {
        $this->comment = $comment;

        return $this;
    }

    public function after(string $column): self
    {
        $this->after = $column;

        return $this;
    }

    public function first(): self
    {
        $this->first = true;

        return $this;
    }

    public function charset(string $charset): self
    {
        $this->charset = $charset;

        return $this;
    }

    public function collation(string $collation): self
    {
        $this->collation = $collation;

        return $this;
    }

    public function storedAs(string $expression): self
    {
        $this->isGenerated = true;
        $this->generatedExpression = $expression;

        return $this;
    }
}
