<?php

namespace App\Filament\Resources\AdoptionApplications\Widgets;

use App\Models\AdoptionApplication;
use App\Models\ApplicationAnswer;
use App\Models\FormQuestionGroup;
use Filament\Widgets\Widget;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Collection as BaseCollection;

class ApplicationAnswersWidget extends Widget
{
    protected string $view = 'filament.resources.adoption-applications.widgets.application-answers-widget';

    protected int|string|array $columnSpan = 'full';

    public ?AdoptionApplication $record = null;

    /**
     * @return Collection<int, ApplicationAnswer>
     */
    public function getAnswers(): Collection
    {
        if (! $this->record) {
            return Collection::make();
        }

        return $this->record->answers()->orderBy('sort_order')->get();
    }

    /**
     * @return BaseCollection<array-key, array{group_id: int|string, group_name: string, group_icon: string, answers: Collection<int, ApplicationAnswer>}>
     */
    public function getGroupedAnswers(): BaseCollection
    {
        $answers = $this->getAnswers();

        return $answers->groupBy(function ($answer): int|string {
            /** @var ApplicationAnswer $answer */
            $snapshot = $answer->question_snapshot;

            return $snapshot['group_id'] ?? 'ungrouped';
        })->sortKeys()->map(function ($groupAnswers, $groupId) {
            /** @var Collection<int, ApplicationAnswer> $groupAnswers */
            /** @var int|string $groupId */
            $firstSnapshot = $groupAnswers->first()->question_snapshot;

            return [
                'group_id' => $groupId,
                'group_name' => $this->getGroupName($groupId, $firstSnapshot) ?? '',
                'group_icon' => $this->getGroupIcon($groupId, $firstSnapshot) ?? '',
                'answers' => $groupAnswers,
            ];
        });
    }

    /**
     * @param  array{id?: int, label?: string, type?: string, options?: list<string>|null, is_required?: bool, group_id?: int|null, group_name?: string|null, group_icon?: string|null}  $snapshot
     */
    protected function getGroupName(string|int $groupId, array $snapshot): ?string
    {
        if ($groupId === 'ungrouped') {
            return 'General Questions';
        }

        if (isset($snapshot['group_name'])) {
            return $snapshot['group_name'];
        }

        return FormQuestionGroup::find($groupId)?->name;
    }

    /**
     * @param  array{id?: int, label?: string, type?: string, options?: list<string>|null, is_required?: bool, group_id?: int|null, group_name?: string|null, group_icon?: string|null}  $snapshot
     */
    protected function getGroupIcon(string|int $groupId, array $snapshot): ?string
    {
        if ($groupId === 'ungrouped') {
            return null;
        }

        if (isset($snapshot['group_icon'])) {
            return $snapshot['group_icon'];
        }

        return FormQuestionGroup::find($groupId)?->icon;
    }
}
