<?php

declare(strict_types=1);

namespace App\Filament\Components\Form;

use App\Filament\Resources\BidResource\RelationManagers\PaymentsRelationManager;
use Filament\Forms\Components\Select;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\File;
use ReflectionClass;
use ReflectionException;

class ModelTypeSelect extends Select
{
    protected static array $modelIdCache = [];

    /**
     * Discover all models from the App\Models namespace.
     */
    protected static function discoverModels(): array
    {
        $models = [];
        $modelsPath = app_path('Models');

        if (! File::exists($modelsPath)) {
            return $models;
        }

        $files = File::allFiles($modelsPath);

        foreach ($files as $file) {
            $className = 'App\\Models\\' . pathinfo($file->getFilename(), PATHINFO_FILENAME);

            // Skip if class doesn't exist or is not instantiable
            if (! class_exists($className)) {
                continue;
            }

            try {
                $reflection = new ReflectionClass($className);

                // Skip abstract classes, interfaces, and traits
                if ($reflection->isAbstract() || $reflection->isInterface() || $reflection->isTrait()) {
                    continue;
                }

                // Check if it's a Laravel Model
                if ($reflection->isSubclassOf(Model::class)) {
                    $models[$className] = class_basename($className);
                }
            } catch (ReflectionException $e) {
                // Skip classes that can't be reflected
                continue;
            }
        }

        // Sort models alphabetically by display name
        asort($models);

        return $models;
    }

    public static function create($models = []): static
    {
        // If models array is empty, discover all models from App\Models namespace
        if (empty($models)) {
            $models = self::discoverModels();
        }

        return parent::make('model_type')
            ->hiddenOn(PaymentsRelationManager::class)
            ->label('نوع مدل')
            ->options($models)
            ->reactive()
            ->searchable()
            ->afterStateUpdated(function ($state, callable $set) {
                $set('model_id', null);
            })
            ->columnSpan(12);
    }
}
