<?php

declare(strict_types=1);

namespace Maestro\Core\Support;

use Illuminate\Support\Facades\Schema;
use Maestro\Core\Models\MaestroModule;
use Throwable;

final class ModuleRuntimeState
{
    public static function shouldLoadMigrations(string $slug, bool $configDefault = true): bool
    {
        if (! self::isConfigured($slug, $configDefault)) {
            return false;
        }

        // Package tests use RefreshDatabase and do not bootstrap runtime toggles first.
        if (app()->runningUnitTests()) {
            return true;
        }

        return self::isInstallEnabled($slug) || self::hasInstalledSchema($slug);
    }

    public static function shouldRunSeeder(string $slug, bool $configDefault = true): bool
    {
        return self::shouldLoadMigrations($slug, $configDefault);
    }

    public static function isInstallEnabled(string $slug): bool
    {
        if (! self::hasModuleRegistryTable()) {
            return false;
        }

        // Backward compatibility for customer-owned modules that are outside
        // CORE's dependency map: keep migration loading behavior unchanged.
        if (! self::isKnownCoreModule($slug)) {
            return true;
        }

        $query = MaestroModule::query()->where('slug', $slug);
        if (self::hasInstallEnabledColumn()) {
            return $query->where('is_install_enabled', true)->exists();
        }

        // Backward compatibility for DBs not yet migrated with `is_install_enabled`.
        return $query->where('is_enabled', true)->exists();
    }

    public static function isRuntimeEnabled(string $slug): bool
    {
        if (! self::hasModuleRegistryTable()) {
            return false;
        }

        return MaestroModule::query()
            ->where('slug', $slug)
            ->where('is_enabled', true)
            ->exists();
    }

    private static function isConfigured(string $slug, bool $configDefault): bool
    {
        return config("core.modules.{$slug}", $configDefault) === true;
    }

    private static function hasModuleRegistryTable(): bool
    {
        try {
            return Schema::hasTable('maestro_modules');
        } catch (Throwable) {
            return false;
        }
    }

    private static function hasInstallEnabledColumn(): bool
    {
        if (! self::hasModuleRegistryTable()) {
            return false;
        }

        try {
            return Schema::hasColumn('maestro_modules', 'is_install_enabled');
        } catch (Throwable) {
            return false;
        }
    }

    private static function hasInstalledSchema(string $slug): bool
    {
        $table = match ($slug) {
            'customers' => 'customers',
            'hours' => 'hour_timesheet_weeks',
            'offers' => 'offers',
            'invoices' => 'invoices',
            'items' => 'maestro_items',
            default => null,
        };

        if ($table === null) {
            return false;
        }

        try {
            return Schema::hasTable($table);
        } catch (Throwable) {
            return false;
        }
    }

    private static function isKnownCoreModule(string $slug): bool
    {
        return in_array($slug, ModuleDependencyMap::allSlugs(), true);
    }
}
