<?php

namespace App\Filament\Pages;

use App\Models\Event;
use Filament\Forms\Set;
use App\Events\HudEvent;
use App\Models\Modality;
use Filament\Forms\Form;
use Filament\Pages\Page;
use App\Models\RoundForce;
use App\Models\Inscription;
use App\Models\ParticipantScore;
use Illuminate\Support\HtmlString;
use App\Models\Round as ModelRound;
use App\Models\RoundBuffer;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Wizard;
use Illuminate\Support\Facades\Blade;
use Filament\Forms\Components\Section;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Placeholder;
use Filament\Notifications\Actions\Action;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Concerns\InteractsWithForms;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Pages\Concerns\InteractsWithFormActions;

class Round extends Page implements HasActions, HasForms
{
    use InteractsWithFormActions;
    use InteractsWithForms;
    use HasPageShield;

    protected static ?string $navigationIcon = 'heroicon-o-megaphone';
    protected static ?string $navigationLabel = 'Juiz';
    protected static ?string $slug = 'modality';
    protected static ?string $title = 'Prova';
    protected static ?int $navigationSort = 2;
    protected static ?string $navigationGroup = 'Provas';
    protected static string $view = 'filament.pages.round';

    public array $data = [];
    public ?int $eventId;
    public ?int $modalityId = null;
    public $rounds;
    public $inscriptions;
    public $tableData = [];
    public bool $hasClassificationRounds = false;
    public string $group = '';
    public $round_status;
    public $resultGroup = [];
    public $isTeams = false;
    public $amountLaps;
    public $totalHits;
    public $finalStep;

    #[Reactive]
    public bool $showPendingRoundsModal = false; // Controla visibilidade do modal de rodadas pendentes
    public array $pendingRounds = []; // Armazena rodadas não finalizadas
    public bool $roundFinish = false;
    public array $pendingValues = []; // Valores temporários das rodadas pendentes
    public ?int $stepRound = 1;

    public function mount(): void
    {
        $this->eventId = null;
        $this->modalityId = null;
        $this->rounds = collect();
        $this->inscriptions = collect();
        $this->dispatch('round-updated');
    }

    public function getFormSchema(): array
    {
        return [
            Section::make([
                Select::make('eventId')
                    ->label('Selecione o evento')
                    ->options(Event::orderBy('created_at', 'desc')->pluck('name', 'id'))
                    ->reactive()
                    ->live()
                    ->afterStateUpdated(function ($state) {
                        $this->updatedEventId($state, changeGroup: true);
                        $this->dispatch('reset-wizard');

                        $currentStep = $this->findFirstIncompleteRound();
                        $this->dispatch('set-wizard', step: $currentStep);
                    })
                    ->required(),

                Select::make('modalityId')
                    ->label('Selecione a modalidade')
                    ->selectablePlaceholder(false)
                    ->options(function () {
                        return $this->eventId
                            ? Event::find($this->eventId)->modalities->sortByDesc('created_at')->pluck('name', 'id')
                            : [];
                    })
                    ->reactive()
                    ->live()
                    ->visible(fn() => filled($this->eventId))
                    ->afterStateUpdated(function ($state, Set $set) {
                        $this->updatedModalityId($state, true);
                        $this->loadRounds();

                        $this->dispatch('reset-wizard');
                        $currentStep = $this->findFirstIncompleteRound();
                        $this->dispatch('set-wizard', step: $currentStep);
                    })
                    ->required(),

                Select::make('group')
                    ->label('Grupo')
                    ->selectablePlaceholder(false)
                    ->options(function () {
                        // Começa com a opção padrão de classificação
                        $options = [
                            'classification' => 'Rodada classificatória'
                        ];

                        // Se tiver eventId e modalityId, busca as forças disponíveis
                        if ($this->eventId && $this->modalityId) {
                            $forces = RoundForce::where([
                                'event_id' => $this->eventId,
                                'modality_id' => $this->modalityId
                            ])
                                ->distinct()
                                ->where('force', '<>', 'N/C')
                                ->pluck('force')
                                ->map(function ($force) {
                                    return ['force' => $force, 'label' => "Força {$force}"];
                                })
                                ->pluck('label', 'force')
                                ->toArray();

                            // Combina as opções
                            $options = array_merge($options, $forces);
                        }

                        return $options;
                    })
                    ->default('classification')
                    ->live()
                    ->reactive()
                    ->visible($this->hasClassificationRounds)
                    ->afterStateUpdated(function ($state) {
                        // Limpa os dados atuais
                        $this->rounds = collect();
                        $this->inscriptions = collect();

                        // Atualiza o grupo
                        $this->group = $state;

                        // Se tivermos uma modalidade selecionada, recarrega tudo
                        if ($this->modalityId) {
                            $this->updatedModalityId($this->modalityId);
                        }

                        $this->loadRounds();

                        // Reseta o wizard
                        $this->dispatch('reset-wizard');
                        $currentStep = $this->findFirstIncompleteRound();
                        $this->dispatch('set-wizard', step: $currentStep);
                    }),
            ])
                ->columns($this->hasClassificationRounds ? 3 : 2),

            Wizard::make($this->getWizardSteps())
                ->startOnStep(fn() => filled($this->modalityId) ? $this->findFirstIncompleteRound() + 1 : 1)
                ->visible($this->rounds->isNotEmpty() && !$this->roundFinish)
                ->submitAction(new HtmlString(Blade::render(<<<BLADE
                    <x-filament::button
                        type="submit"
                        size="sm"
                        wire:click="save"
                        >
                        Finalizar
                    </x-filament::button>
                BLADE)))
                ->persistStepInQueryString('s')
                ->view('forms.components.wizard'),

            Placeholder::make('Evento finalizado')
                ->hiddenLabel()
                ->visible($this->roundFinish)
                ->columnSpanFull()
                ->content(
                    new HtmlString('<div class="flex items-center justify-center p-4">
                       <div class="w-full max-w-2xl bg-red-50 border border-red-300 rounded-lg p-4 flex items-center gap-3">
                           <div class="flex-shrink-0 text-red-500">
                               <x-heroicon-o-exclamation-circle class="w-5 h-5" />
                           </div>
                           <p class="text-sm font-medium text-red-800">
                               Esta modalidade já foi finalizado. Não é possível realizar mais alterações.
                           </p>
                       </div>
                    </div>')
                ),
        ];
    }

    public function initializeHud(){
        event(new
                HudEvent(
                    modalityId: $this->modalityId,
                    eventId: $this->eventId,
                    currentStep: $this->stepRound,
                    finalStep: $this->finalStep
                )
            );

        // Atualiza também o localStorage via evento Livewire para fallback sem WebSockets
        $this->dispatch('modality-data', [
            'modalityId' => $this->modalityId,
            'eventId' => $this->eventId,
            'currentStep' => $this->stepRound,
            'finalStep' => $this->finalStep,
            'group' => $this->group ?: null, // Converte string vazia para null
        ]);
    }

    public function addNewRound()
    {
        $this->validate([
            'amountLaps' => 'required|numeric|min:1|max:100'
        ]);

        $modality = Modality::where('id', $this->modalityId)->first();
        $laps = $modality->round_initial + $this->amountLaps;
        $modality->update(['round_initial' => $laps]);

        $this->loadRounds();
        $this->dispatch('close-modal', id: 'add-laps-modal');
    }

    public function openModalAddRound()
    {
        $this->dispatch('open-modal', id: 'add-laps-modal');
    }

    public function closeModalAddRound()
    {
        $this->loadRounds();
        $this->dispatch('close-modal', id: 'add-laps-modal');
    }

    public function openModalFinalize()
    {
        $this->dispatch('open-modal', id: 'finalize-modal');
    }

    public function closeModalFinalize()
    {
        $this->loadRounds();
        $this->dispatch('close-modal', id: 'finalize-modal');
    }

    public function finalizeModality()
    {
        $rounds = ModelRound::where('modality_id', $this->modalityId)->get();

        foreach($rounds as $round){
            $round->update(['round_status' => 'finish']);
        }

        Modality::where('id', $this->modalityId)->update(['status_modality' => true]);

        $this->dispatch('close-modal', id: 'finalize-modal');
        $this->dispatch('close-modal', id: 'finalize-one-participant-modal');
        $this->dispatch('refreshSteps');
        $this->loadRounds();

        Notification::make()
            ->title('Operação realizada com sucesso!')
            ->success()
            ->body('O registro foi salvo corretamente no banco de dados.')
            ->actions([
                Action::make('view')
                    ->label('Ver Resultado Geral')
                    ->url('/admin/results'),
            ])
            ->send();
    }

    private function findFirstIncompleteRound(): int
    {
        if (!$this->modalityId || !$this->eventId) {
            return 1;
        }

        $lastFinishedRound = ModelRound::where([
            'modality_id' => $this->modalityId,
            'event_id' => $this->eventId,
            'group' => $this->group,
            'round_status' => 'finish'
        ])
            ->orderBy('number', 'desc')
            ->first();

        \Log::debug('Last finished round', ['round' => $lastFinishedRound?->number ?? 'none']);

        return $lastFinishedRound ? $lastFinishedRound->number : 0;
    }

    public function getWizardSteps(): array
    {
        $steps = [];

        if ($this->rounds->isEmpty()) {
            return $steps;
        }

        // Gera campos para cada participante da rodada
        foreach ($this->rounds as $indexRound => $round) {
            $participantsSchema = [];
            $firstLabel = true;
            $filterRoundPrevious = [];

            // Ordena as inscrições pelo inscription_number
            $sortedInscriptions = $round['inscriptions']->sortBy('inscription_number');

            foreach ($sortedInscriptions as $inscription) {
                foreach ($inscription->participants as $participant) {
                    $filterRoundPrevious['inscription'] = $inscription->id;
                    $filterRoundPrevious['participant'] = $participant->id;
                    $filterRoundPrevious['event'] = $this->eventId;
                    $filterRoundPrevious['modality'] = $this->modalityId;
                    $filterRoundPrevious['group'] = $this->group;
                    $filterRoundPrevious['number'] = $inscription->inscription_number;

                    $participantsSchema[] = ToggleButtons::make("data.{$round['number']}.{$inscription->id}.{$participant->id}")
                        ->label($inscription->name . '|' . $participant->name)
                        ->options([
                            '1' => 'Boa',
                            '0' => 'Branca',
                        ])
                        ->icons([
                            '1' => 'heroicon-o-hand-thumb-up',
                            '0' => 'heroicon-o-hand-thumb-down',
                        ])
                        ->colors([
                            '1' => 'success',
                            '0' => 'danger',
                        ])
                        ->reactive()
                        // Bufferiza e escreve em round_buffers para visibilidade sem gravar em rounds
                        ->afterStateUpdated(function ($state) use ($round, $inscription, $participant) {
                            // Buffer para gravação em lote no afterValidation
                            $this->pendingValues[$round['number']][$inscription->id][$participant->id] = $state;

                            // Atualiza o estado em memória para manter UI consistente
                            $this->data[$round['number']][$inscription->id][$participant->id] = $state;

                            // Escreve/mescla no buffer JSON sem alterar rounds
                            DB::transaction(function () use ($state, $round, $inscription, $participant) {
                                $buffer = RoundBuffer::firstOrNew([
                                    'event_id' => $this->eventId,
                                    'modality_id' => $this->modalityId,
                                    'group' => $this->group,
                                    'number' => $round['number'],
                                ]);
                                $payload = $buffer->payload ?? [];
                                $payload[$inscription->id] = $payload[$inscription->id] ?? [];
                                $payload[$inscription->id][$participant->id] = $state;
                                $buffer->payload = $payload;
                                $buffer->save();
                            });

                            // Dispara atualização da HUD imediatamente após o clique
                            $this->initializeHud();
                        })
                        ->default(function () use ($round, $inscription, $participant) {
                            if (isset($this->data[$round['number']][$inscription->id][$participant->id])) {
                                return $this->data[$round['number']][$inscription->id][$participant->id];
                            }
                            return null;
                        })
                        ->view('forms.components.toggle-wizard', compact('firstLabel', 'indexRound', 'filterRoundPrevious'));
                    $firstLabel = false;
                }
            }

            // Cria step para a rodada atual
            $steps[] = Wizard\Step::make("Volta {$round['number']}")
                ->columnSpanFull()
                ->afterValidation(function () use ($round) {
                    $steps = $this->form->getState();
                    $roundInscriptions = $steps['data'][$round['number']] ?? [];
                    // Mescla com buffer (prioriza buffer)
                    $buffer = RoundBuffer::firstWhere([
                        'event_id' => $this->eventId,
                        'modality_id' => $this->modalityId,
                        'group' => $this->group,
                        'number' => $round['number'],
                    ]);
                    $bufferPayload = $buffer?->payload ?? [];
                    $merged = $roundInscriptions;
                    foreach ($bufferPayload as $inscriptionId => $participants) {
                        foreach ($participants as $participantId => $value) {
                            $merged[$inscriptionId][$participantId] = $value;
                        }
                    }
                    $rows = [];
                    foreach ($merged as $inscriptionId => $inscription) {
                        foreach ($inscription as $participantId => $value) {
                            $rows[] = [
                                'inscription_id' => $inscriptionId,
                                'participant_id' => $participantId,
                                'event_id' => $this->eventId,
                                'modality_id' => $this->modalityId,
                                'number' => $round['number'],
                                'group' => $this->group,
                                'value' => $value,
                                'round_status' => is_null($value) ? null : 'finish',
                            ];
                        }
                    }

                    DB::transaction(function () use ($rows) {
                        if (!empty($rows)) {
                            ModelRound::upsert(
                                $rows,
                                ['inscription_id','participant_id','event_id','modality_id','number','group'],
                                ['value','round_status']
                            );
                        }
                    });

                    // Limpa buffer da rodada finalizada
                    if ($buffer) {
                        $buffer->delete();
                    }
                    unset($this->pendingValues[$round['number']]);
                    $this->loadRounds();
                    $this->initializeHud();
                })
                ->schema($participantsSchema);
        }
        return $steps;
    }

    // Atualiza as rodadas quando o evento for alterado
    public function updatedEventId($eventId, $changeGroup = false): void
    {
        $this->eventId = $eventId;
        $this->rounds = collect();

        // Seleciona primeiro modalityId disponível
        $firstModality = Event::find($eventId)?->modalities->where('status_modality', 0)->first();
        if ($firstModality) {
            $this->modalityId = $firstModality->id;
            $this->updatedModalityId($firstModality->id, $changeGroup);
        }
    }

    // Atualiza a modalidade e configura as rodadas iniciais
    public function updatedModalityId($modalityId, $changeGroup = false, $callLoadRounds = true): void
    {
        $modality = Modality::find($modalityId);

        $this->isTeams = $modality->rules->participant_rule !== 'Individual';
        $this->hasClassificationRounds = boolval($modality->active_additional_rules ?? false);

        if ($this->hasClassificationRounds && empty($this->group)) {
            $this->group = 'classification';
            $this->handleGroupChange(['state' => 'classification']);
        }

        // Busca os participantes base com eager loading
        $inscriptions = Inscription::with(['participants', 'rounds' => function ($query) use ($modality) {
            $query->where('value', 1)
                ->where('modality_id', $modality->id)
                ->where('group', 'classification')
                ->groupBy('inscription_id', 'participant_id', 'event_id', 'modality_id', 'group')
                ->select('inscription_id', 'participant_id', 'event_id', 'modality_id', 'group', \DB::raw('MAX(value) as value'));
        }])
        ->where('modality_id', $modality->id)
        ->where('event_id', $this->eventId)
        ->where('inscription_status', 1)
        ->orWhere(function ($query) use ($modality) {
            $query->where('modality_id', $modality->id)
                ->where('event_id', $this->eventId)
                ->where('inscription_status', 0)
                ->where('round_lifeless', '>=', $this->stepRound);
        })
        ->orderBy('name')
        ->get();

        // Se não for classification nem vazio, filtra pelos participantes que satisfazem a regra
        if ($this->group !== 'classification' && $this->group !== '') {
            $inscriptions = Inscription::with(['participants', 'rounds'])
                ->where('modality_id', $modality->id)
                ->where('event_id', $this->eventId)
                ->where('inscription_status', 1)
                ->whereHas('roundForces', function ($query) use ($modality) {
                    $query->where([
                        'modality_id' => $modality->id,
                        'event_id' => $this->eventId,
                        'force' => $this->group,
                    ]);
                })
                ->orderBy('name')
                ->get();

            if ($inscriptions->isEmpty()) {
                $this->without_participants = true;
            }
        }

        // Cria as rodadas se houver participantes
        if ($inscriptions->isEmpty()) {
            $rounds = [];
        } else {
            $rounds = [];
            for ($i = 1; $i <= $modality->round_initial; $i++) {
                $rounds[] = [
                    'number' => $i,
                    'inscriptions' => $inscriptions
                ];
            }
        }

        // Evita pré-criação de rounds sem valor; registros serão gravados apenas quando houver interação

        $this->rounds = collect($this->loadRoundsData($modality, $inscriptions));
        $this->inscriptions = $inscriptions;

        // Carregar os dados existentes
        if (!empty($rounds)) {
            foreach ($rounds as $round) {
                foreach ($round['inscriptions'] as $inscription) {
                    foreach ($inscription->participants as $participant) {
                        $existingRound = ModelRound::where([
                            'inscription_id' => $inscription->id,
                            'participant_id' => $participant->id,
                            'event_id' => $this->eventId,
                            'modality_id' => $this->modalityId,
                            'number' => $round['number'],
                            'group' => $this->group,
                        ])->first();

                        if ($existingRound) {
                            $this->data[$round['number']][$inscription->id][$participant->id] = (string) $existingRound->value;
                        }
                    }
                }
            }
        }

        if ($changeGroup) {
            if ($this->hasClassificationRounds) {
                $this->group = 'classification';
            } else {
                $this->group = '';
            }
        }

        // Atualiza o wizard
        $this->dispatch('refreshSteps');
        if ($callLoadRounds) {
            $this->loadRounds();
        }
    }

    private function loadRoundsData($modality, $inscriptions)
    {
        $rounds = [];
        for ($i = 1; $i <= $modality->round_initial; $i++) {
            $rounds[] = [
                'number' => $i,
                'inscriptions' => $inscriptions
            ];
        }
        return $rounds;
    }

    // Salva os resultados da modalidade
    public function save()
    {
        $round = $this->rounds->last();
        $steps = $this->form->getState();
        $roundInscriptions = $steps['data'][$round['number']];

        foreach ($roundInscriptions as $inscriptionId => $inscription) {
            foreach ($inscription as $participant => $value) {
                $roundStatus = (is_null($value)) ? null : 'finish';
                ModelRound::updateOrCreate([
                    'inscription_id' => $inscriptionId,
                    'participant_id' => $participant,
                    'event_id' => $this->eventId,
                    'modality_id' => $this->modalityId,
                    'number' => $round['number'],
                    'group' => $this->group,
                ], [
                    'value' => $value,
                    'round_status' => $roundStatus,
                ]);
            }
        }

        $this->checkPendingRounds();

        // Abre modal se houver rodadas pendentes
        if (!empty($this->pendingRounds)) {

            $this->showPendingRoundsModal = true;
            $this->dispatch('open-modal', id: 'pending-rounds');
            return;
        }

        Inscription::query()->where([
            'modality_id' => $this->modalityId,
            'event_id' => $this->eventId,
            'inscription_status' => false,
            'lifeless' => true,
            'reborn' => true,
        ])->update(['inscription_status' => true]);

        $this->dispatch('refreshSteps');
        $this->loadRounds(NotFinish: false);
        $this->initializeHud();

        Modality::where('id', $this->modalityId)->update(['status_modality' => true]);
        session(['currentRound' => 1]);

        Notification::make()
            ->title('Operação realizada com sucesso!')
            ->success()
            ->body('O registro foi salvo corretamente no banco de dados.')
            ->actions([
                Action::make('view')
                    ->label('Ver Resultado Geral')
                    ->url('/admin/results'),
            ])
            ->send();
    }

    protected function getRedirectUrl(): string
    {
        return $this->getResource()::getUrl('index');
    }

    public function getListeners(): array
    {
        return [
            'refreshSteps' => '$refresh',
            'group-changed' => 'handleGroupChange',
        ];
    }

    public function getEmptyModality()
    {
        $originalModality = Modality::with('inscriptions')->find($this->modalityId);
        $originalModality->rounds()->update(['value' => null, 'round_status' => null]);

        $this->dispatch('reset-wizard');
        $this->loadRounds();
    }

    //Carrega as informações necessárias para a exibição na tabela das rodadas
    public function loadRounds($NotFinish = true)
    {
        $this->roundFinish = false;
        $modality = Modality::find($this->modalityId);
        $this->finalStep = $modality->round_initial;

        if ($NotFinish && ($this->group == 'classification' || $this->group == '')) {
            $this->checkParticipantsLives($modality);
        }

        $this->updatedModalityId($this->modalityId, callLoadRounds: false);



        // Verifica se todas rodadas foram finalizadas
        $rounds = ModelRound::where('modality_id', $this->modalityId)
            ->where('event_id', $this->eventId)
            ->where('group', $this->group)
            ->where('number', $modality->round_initial)
            ->exists();

        $roundsInOpen = ModelRound::where('modality_id', $this->modalityId)
            ->where('event_id', $this->eventId)
            ->where('group', $this->group)
            ->whereNull('round_status')
            ->exists();

        $this->tableData = [];

        $this->roundFinish = $rounds && !$roundsInOpen;

        if (!$this->roundFinish) {
            // Busca todas as rodadas de uma vez para evitar N+1
            $allRounds = ModelRound::query()
                ->where('modality_id', $this->modalityId)
                ->where('event_id', $this->eventId)
                ->where('group', $this->group)
                ->orderBy('number')
                ->get(['inscription_id','participant_id','number','value','round_status']);

            $byPair = $allRounds->groupBy(fn($r) => $r->inscription_id.'|'.$r->participant_id);

            $forces = collect();
            if ($this->group === 'classification') {
                $forces = RoundForce::query()
                    ->where('modality_id', $this->modalityId)
                    ->where('event_id', $this->eventId)
                    ->get()
                    ->keyBy('inscription_id');
            }

            // Buffers por número de volta
            $buffers = RoundBuffer::query()
                ->where('modality_id', $this->modalityId)
                ->where('event_id', $this->eventId)
                ->where('group', $this->group)
                ->get()
                ->keyBy('number');

            foreach ($this->inscriptions as $inscription) {
                foreach ($inscription->participants as $participant) {
                    $key = $inscription->id.'|'.$participant->id;
                    $roundsForPair = $byPair->get($key, collect());

                    $roundsValues = $roundsForPair->pluck('value', 'number')->toArray();
                    // overlay dos buffers
                    foreach ($buffers as $num => $buffer) {
                        $payload = $buffer->payload ?? [];
                        if (isset($payload[$inscription->id][$participant->id])) {
                            $roundsValues[$num] = $payload[$inscription->id][$participant->id];
                        }
                    }
                    $totalHits = collect($roundsValues)->filter(fn($v) => $v === 1)->count();
                    $round_status = $roundsForPair->last()->round_status ?? '';
                    $roundForce = ($this->group === 'classification' && $forces->has($inscription->id)) ? $forces->get($inscription->id) : null;

                    $this->tableData[$inscription->id][$participant->id] = [
                        'name' => $participant->name,
                        'rounds' => $roundsValues,
                        'total_hits' => $totalHits,
                        'round_status' => $round_status,
                        'modality' => $this->modalityId,
                        'group' => ($this->group === 'classification' && $roundForce) ? $roundForce->force : 'N/C',
                        'inscription_group_name' => $inscription->name,
                        'inscription_number' => $inscription->inscription_number,
                    ];

                    // Preenche os defaults do formulário com valores persistidos
                    // para garantir que, após um refresh, os toggles reflitam o banco.
                    foreach ($roundsValues as $num => $val) {
                        // Evita sobrescrever buffer pendente em memória, priorizando valores mais recentes
                        if (!isset($this->data[$num][$inscription->id][$participant->id])) {
                            $this->data[$num][$inscription->id][$participant->id] = $val;
                        }
                    }

                    // Mantém regra atual de atualização de placar
                    $this->updateParticipantScore($inscription->id, $totalHits);
                }
            }
        }


    }

    //Atualiza a quantidade de acertos do participante na modalidade do evento
    public function updateParticipantScore(int $inscriptionId, int $totalHits): void
    {
        ParticipantScore::updateOrCreate([
            'inscription_id' => $inscriptionId,
            'event_id' => $this->eventId,
            'modality_id' => $this->modalityId,
            'group' => $this->group
        ], ['total_hits' => $totalHits]);
    }

    public function nextStep($stepIndex): void
    {
        $step = $stepIndex + 2;
        $this->stepRound = $step;

        // Carrega as rodadas e atualiza o estado atual
        $this->loadRounds();
        $this->initializeHud();

        // Verifica se há apenas um participante ativo
        $this->checkSingleParticipant();
    }

    public function previousStep($stepIndex): void
    {
        $this->stepRound = $stepIndex;
        $this->loadRounds();
        $this->initializeHud();
    }

    // Manipula a mudança de grupo e atualiza os dados
    public function handleGroupChange($data): void
    {
        // Executa a mesma lógica do afterStateUpdate do group
        $this->rounds = collect();
        $this->inscriptions = collect();
        $this->group = $data['state'];

        if ($this->modalityId) {
            $this->updatedModalityId($this->modalityId);
        }
        $this->loadRounds();
    }

    // Verifica se existem rodadas pendentes
    private function checkPendingRounds(): void
    {
        $this->pendingRounds = [];

        // Verifica rodadas não finalizadas para cada participante
        foreach ($this->inscriptions as $inscription) {
            foreach ($inscription->participants as $participant) {
                for ($i = 1; $i <= count($this->rounds); $i++) {
                    $round = ModelRound::whereNotNull('round_status')
                        ->whereHas('inscription', function ($query) {
                            $query->where('inscription_status', true);
                        })
                        ->where([
                            'inscription_id' => $inscription->id,
                            'participant_id' => $participant->id,
                            'event_id' => $this->eventId,
                            'modality_id' => $this->modalityId,
                            'number' => $i,
                            'group' => $this->group,
                        ])
                        ->first();

                    if (!$round) {
                        $this->pendingRounds[] = [
                            'inscription_id' => $inscription->id,
                            'participant_id' => $participant->id,
                            'round_number' => $i,
                            'participant_name' => $participant->name,
                            'inscription_name' => $inscription->name,
                            'value' => null
                        ];
                    }
                }
            }
        }
    }

    // Salva as rodadas pendentes e finaliza o processo
    public function savePendingRounds($checkPendingRounds = true): void
    {
        foreach ($this->pendingValues as $round => $inscriptions) {
            foreach ($inscriptions as $inscription => $participations) {
                foreach ($participations as $participation => $value) {
                    $roundStatus = (is_null($value)) ? null : 'finish';
                    ModelRound::updateOrCreate([
                        'inscription_id' => $inscription,
                        'participant_id' => $participation,
                        'event_id' => $this->eventId,
                        'modality_id' => $this->modalityId,
                        'number' => $round,
                        'group' => $this->group,
                    ], [
                        'value' => $value,
                        'round_status' => $roundStatus
                    ]);
                }
            }
        }

        // Verifica rodadas pendentes novamente se solicitado
        if ($checkPendingRounds) {
            $this->checkPendingRounds();

            if (!empty($this->pendingRounds)) {
                $this->dispatch('open-modal', id: 'confirmation-modal');
                return;
            }
        }

        // Marca todas rodadas como finalizadas
        ModelRound::where([
            'event_id' => $this->eventId,
            'modality_id' => $this->modalityId,
            'group' => $this->group,
        ])->update(['round_status' => 'finish']);

        Inscription::query()->where([
            'modality_id' => $this->modalityId,
            'event_id' => $this->eventId,
            'inscription_status' => false,
            'lifeless' => true,
            'reborn' => true,
        ])->update(['inscription_value' => 1]);

        $this->dispatch('close-modal', id: 'pending-rounds');
        $this->dispatch('refreshSteps');
        $this->loadRounds();
        $this->initializeHud();

        Modality::where('id', $this->modalityId)->update(['status_modality' => true]);
        session(['currentRound' => 1]);

        Notification::make()
            ->title('Operação realizada com sucesso!')
            ->success()
            ->body('O registro foi salvo corretamente no banco de dados.')
            ->actions([
                Action::make('view')
                    ->label('Ver Resultado Geral')
                    ->url('/admin/results'),
            ])
            ->send();
    }

    // Cancela o processo de finalização
    public function cancelFinalization(): void
    {
        $this->dispatch('close-modal', id: 'confirmation-modal');
    }

    // Finaliza todas as rodadas
    public function finalizeRounds(): void
    {
        $this->dispatch('close-modal', id: 'confirmation-modal');
        $this->cancelFinalization();
        $this->savePendingRounds(checkPendingRounds: false);
    }

    // Cria o formulário para rodadas pendentes
    public function getPendingRoundsForm($index, $round): Form
    {
        return Form::make($this)
            ->schema([
                ToggleButtons::make("pendingValues.{$round['round_number']}.{$round['inscription_id']}.{$round['participant_id']}")
                    ->hiddenLabel()
                    ->inline()
                    ->options([
                        '1' => 'Boa',
                        '0' => 'Branca',
                    ])
                    ->colors([
                        '1' => 'success',
                        '0' => 'danger',
                    ])
                    ->icons([
                        '1' => 'heroicon-o-hand-thumb-up',
                        '0' => 'heroicon-o-hand-thumb-down',
                    ])
                    ->afterStateUpdated(fn($state) => $this->pendingRounds[$index]['value'] = 1)
            ]);
    }

    private function checkParticipantsLives(Modality $modality)
    {
        $rule = $modality->rules;
        $live = $rule->rule_life;

        if ($rule->active_zero_life && $this->stepRound >= $rule->zero_life_lap) {

            // Passo 1: Identificar participantes que falharam APÓS o zero_life_lap
            $failedAfterZeroLife = ModelRound::where('event_id', $this->eventId)
                ->where('modality_id', $modality->id)
                ->where('value', 0)
                ->where('number', '>=', $rule->zero_life_lap)
                ->groupBy('inscription_id')
                ->pluck('inscription_id');

            // Passo 2: Eliminar participantes que falharam APÓS o zero_life_lap
            // (somente se ainda não estiverem eliminados)
            Inscription::whereIn('id', $failedAfterZeroLife)
                ->where('round_lifeless', 0) // Apenas não eliminados
                ->update([
                    'inscription_status' => false,
                    'lifeless' => true,
                    'round_lifeless' => $this->stepRound,
                ]);

            ModelRound::whereIn('inscription_id', $failedAfterZeroLife)
                ->where('event_id', $this->eventId)
                ->where('modality_id', $this->modalityId)
                ->update([
                    'round_status' => 'eliminated',
                ]);
            // Passo 3: Restaurar APENAS participantes eliminados DURANTE/APÓS o zero_life_lap
            // e que NÃO falharam após essa etapa
            Inscription::where('modality_id', $modality->id)
                ->where('event_id', $this->eventId)
                ->where('lifeless', true)
                ->where('round_lifeless', '>=', $rule->zero_life_lap) // Critério chave!
                ->whereNotIn('id', $failedAfterZeroLife)
                ->update([
                    'inscription_status' => true,
                    'lifeless' => false,
                    'round_lifeless' => 0,
                ]);



        } else {
            // Lógica original para contagem normal de vidas (sem zerar vidas)
            $roundsFailed = ModelRound::where([
                'event_id' => $this->eventId,
                'modality_id' => $modality->id,
                'value' => 0,
            ])
            ->where('number', '<=', $this->stepRound)
            ->groupBy('inscription_id')
            ->selectRaw('inscription_id, COUNT(*) as failed_count')
            ->get();

            $idsEliminar = $roundsFailed->where('failed_count', '>=', $live)->pluck('inscription_id');
            $idsRestaurar = $roundsFailed->where('failed_count', '<', $live)->pluck('inscription_id');
            // Eliminar participantes
            Inscription::whereIn('id', $idsEliminar)
                ->where('round_lifeless', 0)
                ->update([
                    'inscription_status' => false,
                    'lifeless' => true,
                    'round_lifeless' => $this->stepRound,
                ]);

            ModelRound::whereIn('inscription_id', $idsEliminar)
                ->where('event_id', $this->eventId)
                ->where('modality_id', $this->modalityId)
                ->update([
                    'round_status' => 'eliminated',
                ]);
            // Restaurar participantes (apenas se já estavam eliminados)
            Inscription::whereIn('id', $idsRestaurar)
                ->where('lifeless', true)
                ->update([
                    'inscription_status' => true,
                    'lifeless' => false,
                    'round_lifeless' => 0,
                ]);

        }
    }

    private function checkSingleParticipant(): void
    {
        $activeParticipants = Inscription::where('modality_id', $this->modalityId)
            ->where('event_id', $this->eventId)
            ->where('inscription_status', true)
            ->count();

        if ($activeParticipants === 1) {
            $this->dispatch('open-modal', id: 'finalize-one-participant-modal');
        }
    }
}
