<?php

namespace Wizard\Framework\Database;

use Illuminate\Database\Schema\ColumnDefinition;

class MyBlueprint extends \Illuminate\Database\Schema\Blueprint
{
    /**
     * Generates the base columns for a regular table
     */
    public function baseColumns(): void
    {
        $this->id();
        $this->reference('users', 'created_by')->nullable();
        $this->reference('users', 'updated_by')->nullable();
        $this->timestamps();
        $this->softDeletes();
    }

    /**
     * @param  mixed  $abbreviation
     */
    public function baseTextColumns($abbreviation = false): void
    {
        $this->string('name', 255);
        $this->text('description')->nullable();
        if ($abbreviation) {
            $this->string('abbreviation', 50)->nullable();
        }
    }

    public function pivotColumns(string $table1, string $table2): void
    {
        $this->comment('PIVOT:'.json_encode(['table1' => $table1, 'table2' => $table2]));
        $this->id();
        $this->reference($table1);
        $this->reference($table2);
    }

    public function settingsColumns(): void
    {
        $this->baseColumns();
        $this->baseTextColumns();
    }

    /**
     * @param  mixed  $keep_column
     */
    public function dropReference(string $table, ?string $override_column_name = null, $keep_column = false): void
    {
        // set up relevant strings
        $column_name = self::get_foreign_column_name($table, $override_column_name);
        $fk_name = self::get_foreign_key_name($this->getTable(), $table, $column_name);

        // drop the reference
        $this->dropForeign($fk_name);

        // drop the column if necessary
        if (! $keep_column) {
            $this->dropColumn($column_name);
        }
    }

    public function reference(string $table, ?string $override_column_name = null): ColumnDefinition
    {
        // set up relevant strings
        $column_name = self::get_foreign_column_name($table, $override_column_name);
        $fk_name = self::get_foreign_key_name($this->getTable(), $table, $column_name);

        // create the column
        $column = $this->unsignedBigInteger($column_name);

        // create the foreign key
        $this->foreign($column_name, $fk_name)->references('id')->on($table);

        return $column;
    }

    protected static function get_foreign_column_name(string $input, ?string $override = null): string
    {
        return ! is_null($override) ? $override : \Str::singular($input).'_id';
    }

    /*
     * Generates a foreign key name
     * 'FK_' + current table name + foreign column name
     *
     * */
    protected static function get_foreign_key_name(string $current_table, string $table, string $column_name): string
    {
        $fk_name = 'FK_';

        // add the current table name
        $fk_name .= \Str::singular($current_table);

        // add the foreign column name
        $fk_name .= '_'.$column_name;

        return $fk_name;
    }
}
