<?php

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

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('departamentos', function (Blueprint $table) {
            if (! Schema::hasColumn('departamentos', 'icone')) {
                $table->string('icone')->default('building-office-2')->after('descricao');
            }
        });

        if (! Schema::hasTable('subcategorias')) {
            Schema::create('subcategorias', function (Blueprint $table) {
                $table->id();
                $table->foreignId('departamento_id')->constrained('departamentos')->cascadeOnDelete();
                $table->string('nome');
                $table->boolean('ativo')->default(true);
                $table->timestamps();

                $table->unique(['departamento_id', 'nome']);
                $table->index(['departamento_id', 'ativo']);
            });
        }

        Schema::table('artigos', function (Blueprint $table) {
            if (! Schema::hasColumn('artigos', 'subcategoria_id')) {
                $table->foreignId('subcategoria_id')
                    ->nullable()
                    ->after('categoria_id')
                    ->constrained('subcategorias')
                    ->nullOnDelete();

                $table->index(['status', 'departamento_id', 'subcategoria_id']);
            }
        });

        $this->permitirCategoriaLegadaNula();
        $this->migrarCategoriasParaSubcategorias();
    }

    public function down(): void
    {
        Schema::table('artigos', function (Blueprint $table) {
            if (Schema::hasColumn('artigos', 'subcategoria_id')) {
                $table->dropConstrainedForeignId('subcategoria_id');
            }
        });

        Schema::dropIfExists('subcategorias');

        Schema::table('departamentos', function (Blueprint $table) {
            if (Schema::hasColumn('departamentos', 'icone')) {
                $table->dropColumn('icone');
            }
        });
    }

    private function permitirCategoriaLegadaNula(): void
    {
        if (! Schema::hasColumn('artigos', 'categoria_id')) {
            return;
        }

        try {
            Schema::table('artigos', function (Blueprint $table) {
                $table->dropForeign(['categoria_id']);
            });
        } catch (Throwable) {
            // A base pode ja ter sido ajustada em outro ambiente.
        }

        if (DB::getDriverName() === 'mysql') {
            DB::statement('ALTER TABLE artigos MODIFY categoria_id BIGINT UNSIGNED NULL');

            try {
                DB::statement('ALTER TABLE artigos ADD CONSTRAINT artigos_categoria_id_foreign FOREIGN KEY (categoria_id) REFERENCES categorias(id) ON DELETE SET NULL');
            } catch (Throwable) {
                // Mantem a migracao idempotente quando a constraint ja existe.
            }
        }
    }

    private function migrarCategoriasParaSubcategorias(): void
    {
        if (! Schema::hasTable('categorias')) {
            return;
        }

        $categorias = DB::table('categorias')
            ->select('id', 'departamento_id', 'nome', 'created_at', 'updated_at')
            ->orderBy('id')
            ->get();

        foreach ($categorias as $categoria) {
            $nome = trim((string) $categoria->nome) ?: 'Geral';

            $subcategoriaId = DB::table('subcategorias')
                ->where('departamento_id', $categoria->departamento_id)
                ->where('nome', $nome)
                ->value('id');

            if (! $subcategoriaId) {
                $subcategoriaId = DB::table('subcategorias')->insertGetId([
                    'departamento_id' => $categoria->departamento_id,
                    'nome' => Str::limit($nome, 255, ''),
                    'ativo' => true,
                    'created_at' => $categoria->created_at ?? now(),
                    'updated_at' => $categoria->updated_at ?? now(),
                ]);
            }

            DB::table('artigos')
                ->where('categoria_id', $categoria->id)
                ->whereNull('subcategoria_id')
                ->update(['subcategoria_id' => $subcategoriaId]);
        }
    }
};
