<?php

declare(strict_types=1);

namespace App\Framework\Database\Platform;

use App\Framework\Database\ConnectionInterface;
use App\Framework\Database\Platform\ValueObjects\ColumnDefinition;
use App\Framework\Database\Platform\ValueObjects\TableOptions;
use App\Framework\Database\ValueObjects\SqlQuery;

/**
 * Fluent schema builder for database-independent table creation
 */
final readonly class SchemaBuilder
{
    public function __construct(
        private ConnectionInterface $connection,
        private DatabasePlatform $platform
    ) {
    }

    /**
     * Create a new table
     *
     * @param string $tableName
     * @param ColumnDefinition[] $columns
     * @param TableOptions $options
     */
    public function createTable(string $tableName, array $columns, ?TableOptions $options = null): void
    {
        $options = $options ?? TableOptions::default();
        $sql = $this->platform->getCreateTableSQL($tableName, $columns, $options);
        $this->connection->query(SqlQuery::create($sql));
    }

    /**
     * Drop a table
     */
    public function dropTable(string $tableName, bool $ifExists = false): void
    {
        $sql = $this->platform->getDropTableSQL($tableName, $ifExists);
        $this->connection->query(SqlQuery::create($sql));
    }

    /**
     * Create an auto-increment primary key column
     */
    public function id(string $name = 'id'): ColumnDefinition
    {
        return ColumnDefinition::id($name);
    }

    /**
     * Create a string/varchar column
     */
    public function string(string $name, int $length = 255): ColumnDefinition
    {
        return ColumnDefinition::string($name, $length);
    }

    /**
     * Create a text column
     */
    public function text(string $name): ColumnDefinition
    {
        return ColumnDefinition::text($name);
    }

    /**
     * Create an integer column
     */
    public function integer(string $name): ColumnDefinition
    {
        return ColumnDefinition::integer($name);
    }

    /**
     * Create a big integer column
     */
    public function bigInteger(string $name): ColumnDefinition
    {
        return ColumnDefinition::bigInteger($name);
    }

    /**
     * Create a decimal column
     */
    public function decimal(string $name, int $precision = 8, int $scale = 2): ColumnDefinition
    {
        return ColumnDefinition::decimal($name, $precision, $scale);
    }

    /**
     * Create a float column
     */
    public function float(string $name): ColumnDefinition
    {
        return ColumnDefinition::float($name);
    }

    /**
     * Create a boolean column
     */
    public function boolean(string $name): ColumnDefinition
    {
        return ColumnDefinition::boolean($name);
    }

    /**
     * Create a date column
     */
    public function date(string $name): ColumnDefinition
    {
        return ColumnDefinition::date($name);
    }

    /**
     * Create a datetime column
     */
    public function datetime(string $name): ColumnDefinition
    {
        return ColumnDefinition::datetime($name);
    }

    /**
     * Create a timestamp column
     */
    public function timestamp(string $name): ColumnDefinition
    {
        return ColumnDefinition::timestamp($name);
    }

    /**
     * Create a binary column
     */
    public function binary(string $name, int $length): ColumnDefinition
    {
        return ColumnDefinition::binary($name, $length);
    }

    /**
     * Create a JSON column
     */
    public function json(string $name): ColumnDefinition
    {
        return ColumnDefinition::json($name);
    }

    /**
     * Create a time column
     */
    public function time(string $name): ColumnDefinition
    {
        return ColumnDefinition::time($name);
    }

    /**
     * Create a year column
     */
    public function year(string $name): ColumnDefinition
    {
        return ColumnDefinition::year($name);
    }

    /**
     * Create timestamps columns (created_at, updated_at)
     *
     * @return ColumnDefinition[]
     */
    public function timestamps(): array
    {
        return [
            ColumnDefinition::timestamp('created_at', false),
            ColumnDefinition::timestamp('updated_at', false),
        ];
    }

    /**
     * Create soft delete column (deleted_at)
     */
    public function softDeletes(): ColumnDefinition
    {
        return ColumnDefinition::timestamp('deleted_at', true);
    }
}
