<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        $teams = config('permission.teams');
        $tableNames = config('permission.table_names');
        $columnNames = config('permission.column_names');
        $pivotRole = $columnNames['role_pivot_key'] ?? 'role_id';
        $pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id';
        $teamKey = $columnNames['team_foreign_key'];

        /*
        |--------------------------------------------------------------------------
        | PERMISSIONS
        |--------------------------------------------------------------------------
        */

        Schema::create($tableNames['permissions'], function (Blueprint $table) {

            $table->id();
            $table->string('name');
            $table->string('guard_name');
            $table->timestamps();

            $table->unique(['name', 'guard_name']);

        });


        /*
        |--------------------------------------------------------------------------
        | ROLES
        |--------------------------------------------------------------------------
        */

        Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $teamKey) {

            $table->id();

            if ($teams) {

                $table->unsignedBigInteger($teamKey)
                    ->nullable();

                $table->index($teamKey);

            }

            $table->string('name');

            $table->string('guard_name');

            $table->timestamps();

            if ($teams) {

                $table->unique([$teamKey, 'name', 'guard_name']);

            } else {

                $table->unique(['name', 'guard_name']);

            }

        });


        /*
        |--------------------------------------------------------------------------
        | MODEL HAS PERMISSIONS
        |--------------------------------------------------------------------------
        */

        Schema::create($tableNames['model_has_permissions'], function (Blueprint $table)
        use ($tableNames, $columnNames, $pivotPermission, $teams, $teamKey)
        {

            $table->unsignedBigInteger($pivotPermission);

            $table->string('model_type');

            $table->unsignedBigInteger($columnNames['model_morph_key']);

            if ($teams) {

                $table->unsignedBigInteger($teamKey)
                    ->nullable();

                $table->index($teamKey);

            }

            $table->foreign($pivotPermission)
                ->references('id')
                ->on($tableNames['permissions'])
                ->cascadeOnDelete();

            // primary SEM team_key
            $table->primary([
                $pivotPermission,
                $columnNames['model_morph_key'],
                'model_type'
            ]);

        });


        /*
        |--------------------------------------------------------------------------
        | MODEL HAS ROLES
        |--------------------------------------------------------------------------
        */

        Schema::create($tableNames['model_has_roles'], function (Blueprint $table)
        use ($tableNames, $columnNames, $pivotRole, $teams, $teamKey)
        {

            $table->unsignedBigInteger($pivotRole);

            $table->string('model_type');

            $table->unsignedBigInteger($columnNames['model_morph_key']);

            if ($teams) {

                $table->unsignedBigInteger($teamKey)
                    ->nullable();

                $table->index($teamKey);

            }

            $table->foreign($pivotRole)
                ->references('id')
                ->on($tableNames['roles'])
                ->cascadeOnDelete();

            // primary SEM team_key
            $table->primary([
                $pivotRole,
                $columnNames['model_morph_key'],
                'model_type'
            ]);

        });


        /*
        |--------------------------------------------------------------------------
        | ROLE HAS PERMISSIONS
        |--------------------------------------------------------------------------
        */

        Schema::create($tableNames['role_has_permissions'], function (Blueprint $table)
        use ($tableNames, $pivotRole, $pivotPermission)
        {

            $table->unsignedBigInteger($pivotPermission);

            $table->unsignedBigInteger($pivotRole);

            $table->foreign($pivotPermission)
                ->references('id')
                ->on($tableNames['permissions'])
                ->cascadeOnDelete();

            $table->foreign($pivotRole)
                ->references('id')
                ->on($tableNames['roles'])
                ->cascadeOnDelete();

            $table->primary([
                $pivotPermission,
                $pivotRole
            ]);

        });


        app('cache')
            ->store(config('permission.cache.store') != 'default'
                ? config('permission.cache.store')
                : null)
            ->forget(config('permission.cache.key'));

    }


    public function down(): void
    {

        $tableNames = config('permission.table_names');

        Schema::dropIfExists($tableNames['role_has_permissions']);
        Schema::dropIfExists($tableNames['model_has_roles']);
        Schema::dropIfExists($tableNames['model_has_permissions']);
        Schema::dropIfExists($tableNames['roles']);
        Schema::dropIfExists($tableNames['permissions']);

    }
};
