<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // Paso 1: Agregar columnas snapshot
        Schema::table('detalle_ventas', function (Blueprint $table) {
            $table->string('producto_nombre_snapshot')->nullable()->after('producto_id');
            $table->string('variante_info_snapshot')->nullable()->after('variante_id');
        });
        
        // Paso 2: Actualizar registros existentes con snapshot de información
        // Usar DB::unprepared para evitar problemas de transacción en PostgreSQL
        try {
            DB::unprepared("
                UPDATE detalle_ventas 
                SET producto_nombre_snapshot = productos.nombre
                FROM productos 
                WHERE productos.id = detalle_ventas.producto_id 
                AND detalle_ventas.producto_id IS NOT NULL 
                AND detalle_ventas.producto_nombre_snapshot IS NULL
            ");
        } catch (\Exception $e) {
            // Si falla, intentar con la sintaxis estándar
            \Illuminate\Support\Facades\DB::table('detalle_ventas')
                ->whereNotNull('producto_id')
                ->whereNull('producto_nombre_snapshot')
                ->get()
                ->each(function ($detalle) {
                    $producto = \Illuminate\Support\Facades\DB::table('productos')
                        ->where('id', $detalle->producto_id)
                        ->first();
                    if ($producto) {
                        \Illuminate\Support\Facades\DB::table('detalle_ventas')
                            ->where('id', $detalle->id)
                            ->update(['producto_nombre_snapshot' => $producto->nombre]);
                    }
                });
        }
        
        try {
            DB::unprepared("
                UPDATE detalle_ventas 
                SET variante_info_snapshot = CONCAT(c.name, ' / ', s.name)
                FROM product_variants pv
                JOIN colors c ON c.id = pv.color_id
                JOIN sizes s ON s.id = pv.size_id
                WHERE pv.id = detalle_ventas.variante_id
                AND detalle_ventas.variante_id IS NOT NULL 
                AND detalle_ventas.variante_info_snapshot IS NULL
            ");
        } catch (\Exception $e) {
            // Si falla, intentar con la sintaxis estándar
            \Illuminate\Support\Facades\DB::table('detalle_ventas')
                ->whereNotNull('variante_id')
                ->whereNull('variante_info_snapshot')
                ->get()
                ->each(function ($detalle) {
                    $variante = \Illuminate\Support\Facades\DB::table('product_variants as pv')
                        ->join('colors as c', 'c.id', '=', 'pv.color_id')
                        ->join('sizes as s', 's.id', '=', 'pv.size_id')
                        ->where('pv.id', $detalle->variante_id)
                        ->select(\Illuminate\Support\Facades\DB::raw("CONCAT(c.name, ' / ', s.name) as info"))
                        ->first();
                    if ($variante) {
                        \Illuminate\Support\Facades\DB::table('detalle_ventas')
                            ->where('id', $detalle->id)
                            ->update(['variante_info_snapshot' => $variante->info]);
                    }
                });
        }
        
        // Paso 3: Hacer nullable las columnas producto_id y variante_id
        Schema::table('detalle_ventas', function (Blueprint $table) {
            $table->unsignedBigInteger('producto_id')->nullable()->change();
            $table->unsignedBigInteger('variante_id')->nullable()->change();
        });
        
        // Paso 4: Actualizar claves foráneas para usar SET NULL
        try {
            Schema::table('detalle_ventas', function (Blueprint $table) {
                $table->dropForeign(['producto_id']);
                $table->dropForeign(['variante_id']);
                
                $table->foreign('producto_id')
                      ->references('id')
                      ->on('productos')
                      ->onDelete('set null');
                      
                $table->foreign('variante_id')
                      ->references('id')
                      ->on('product_variants')
                      ->onDelete('set null');
            });
        } catch (\Exception $e) {
            // Las claves foráneas pueden no existir
        }
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('detalle_ventas', function (Blueprint $table) {
            // Revertir claves foráneas
            $table->dropForeign(['producto_id']);
            $table->dropForeign(['variante_id']);
            
            $table->foreign('producto_id')
                  ->references('id')
                  ->on('productos')
                  ->onDelete('restrict');
                  
            $table->foreign('variante_id')
                  ->references('id')
                  ->on('product_variants')
                  ->onDelete('restrict');
            
            // Revertir a NOT NULL (solo si no hay registros con NULL)
            $table->unsignedBigInteger('producto_id')->nullable(false)->change();
            $table->unsignedBigInteger('variante_id')->nullable(false)->change();
            
            // Eliminar campos snapshot
            $table->dropColumn(['producto_nombre_snapshot', 'variante_info_snapshot']);
        });
    }
};
