<?php

namespace App\Helpers\Database;

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class SpecialDBHelper
{
    /**
     * Activa módulos: migra tablas faltantes y corre seeders.
     */
    public static function spreadModulesDB(array $modules_configuration) : void
    {
        // Get the File paths (Migrations and Seeders) for each module
        $db_files_location = self::dbFilesLocation();
        $force = App::environment('production');

        // Build DB for Modules
        foreach ($db_files_location as $module => $path_of) {

            // Solo procedemos si el modulo se encuentra activado
            $module_active = $modules_configuration["has_{$module}"] ?? false;
                if (!$module_active) continue;

            // Extract File paths
            $module_migrations = array_values($path_of['migrations'] ?? []);
            $module_seeders    = array_values($path_of['seeders'] ?? []);

            // Migrate un-migrated Module Tables
            self::migratePendingFiles($module_migrations, $force);

            // Execute Module Seeders
            self::runSeeders($module_seeders, $force);
        }
    }

  //* Support Functions
    // Artisan
        /**
         * Migra cada uno de los archivo pendientes del modulo en cuestión.
         */
        private static function migratePendingFiles(array $migration_paths, bool $force = false): void
        {
            if (empty($migration_paths)) return;

            // Obtener aquellos archivos que realmente existen
            $normalized = [];
            foreach ($migration_paths as $rel_path) {
                $migration_path = 'database/migrations/' . $rel_path . '.php';

                $full = base_path($migration_path);
                    if (!file_exists($full)) continue;

                $normalized[] = $migration_path;
            }

            // Ordenar por orden cronológico (nombre)
            usort($normalized, fn($a, $b) => strcmp(basename($a), basename($b)));

            foreach ($normalized as $rel_path) {
                // Obtener el nombre del archivo SIN extensión
                $basename      = basename($rel_path);
                $migration_name = pathinfo($basename, PATHINFO_FILENAME);

                // Si la tabla ya fue migrada, no se vuelve a migrar
                if (self::checkMigration($migration_name))
                    continue;

                // Migrar tabla
                Log::info("Se migro: {$rel_path}");
                Artisan::call('migrate', [
                    '--path'  => $rel_path,
                    '--force' => $force,
                ]);
            }
        }

        /**
         * Ejecuta una lista de seeders
         */
        private static function runSeeders(array $seeders, bool $force = false): void
        {
            if (empty($seeders)) return;

            foreach ($seeders as $seeder) {
                $seeder_path = str_starts_with($seeder, 'Database\\Seeders\\')
                    ? $seeder
                    : 'Database\\Seeders\\' . $seeder;

                // Validación ligera: ¿la clase existe/cargó con Composer?
                if (!class_exists($seeder_path)) continue;

                Artisan::call('db:seed', [
                    '--class' => $seeder_path,
                    '--force' => $force,
                ]);
            }
        }

    // Local
        /**
         * Verifica si una migración ya fue aplicada (valor exacto en columna 'migration').
         * En la tabla 'migrations' se guarda el nombre sin .php
        */
        private static function checkMigration(string $migration_name): bool
        {
            return DB::table('migrations')
                ->where('migration', $migration_name)->exists();
        }

        /**
         * Define aquí las rutas de migraciones/seeders por módulo.
         * Ajusta libremente.
         *
         * Nota. Las funciones de este helper están diseñados bajo la idea de que todas las
         * migrations y seeders a introducir aquí, se encuentran compartiendo la misma rita base inicial:
         *      - Migrations: "database/migrations/"
         *      - Seeders: "Database\\Seeders\\"
         */
        private static function dbFilesLocation(): array
        {
            return [
                // Audits Module
                "audits" => [
                    "migrations" => [
                        "Modules/Audits/2025_06_16_121753_create_audits_table"
                    ],
                    "seeders" => []
                ],

                // Restaurant Module
                "restaurant" => [
                    "migrations" => [
                        "Restaurant/2024_04_15_000008_create_product_categories_table",
                        "Restaurant/2024_04_15_000017_create_orders_table",
                        "Restaurant/2024_04_15_000018_create_comandas_table",
                        "Restaurant/2024_04_15_000021_create_tables_table",
                        "Restaurant/2024_04_15_000024_create_products_table",
                    ],
                    "seeders" => [
                        "Modules\\RestaurantSeeder",
                    ]
                ],

                // Booking Engine

                "booking_engine"=> [
                    "migrations" => [
                        "Modules/BookingEngine/2026_06_17_160118_add_ical_token_to_rooms_table",
                    ],
                    "seeders" => [
                        "Modules\\BookingEngineSeeder"
                    ]
                ],

                // OTAs Module
                "otas_connection" => [
                    "migrations" => [
                        "Modules/OtaConnections/2025_07_17_155020_create_ota_connections_table",
                        "Modules/OtaConnections/2025_09_17_110924_add_external_configuration_to_room_types",
                        "Modules/OtaConnections/2025_09_17_110928_add_external_configuration_to_rooms",
                        "Modules/OtaConnections/2025_09_17_111647_create_ota_allotment_events_table",
                        "Modules/OtaConnections/2025_09_17_120257_create_ota_external_reservations_table",
                    ],
                    "seeders" => [
                        "Modules\\OTAConnectionSeeder"
                    ]
                ],
            ];

        }
}
