<?php

namespace App\Filament\Resources\AdoptionApplications\Schemas;

use App\Filament\Resources\Pets\PetResource;
use App\Models\AdoptionApplication;
use App\Models\Pet;
use App\Models\Setting;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;

class AdoptionApplicationForm
{
    public static function configure(Schema $schema): Schema
    {
        return $schema
            ->components([
                Select::make('pet_id')
                    ->label('Pet')
                    ->relationship('pet', 'name')
                    ->searchable()
                    ->preload()
                    ->live()
                    ->options(function ($record, Get $get) {
                        $currentApplicationId = $record?->id;
                        $secondPetId = $get('second_pet_id');

                        return Pet::query()
                            ->where(function ($query) {
                                $query->whereIn('status', ['available', 'pending', 'coming_soon']);
                                if (Setting::get('require_application_for_manual_adoption', false)) {
                                    $query->orWhere(fn ($q) => $q
                                        ->where('status', 'adopted')
                                        ->whereDoesntHave('adoptionApplications'));
                                }
                            })
                            ->when($secondPetId, fn ($q) => $q->where('id', '!=', $secondPetId))
                            ->orderBy('name')
                            ->get()
                            ->mapWithKeys(function (Pet $pet) use ($currentApplicationId) {
                                $activeApplicationsCount = AdoptionApplication::query()
                                    ->where(function ($query) use ($pet) {
                                        $query->where('pet_id', $pet->id)
                                            ->orWhere('second_pet_id', $pet->id);
                                    })
                                    ->whereNotIn('status', ['cancelled', 'rejected', 'archived'])
                                    ->when($currentApplicationId, fn ($q) => $q->where('id', '!=', $currentApplicationId))
                                    ->count();

                                $label = "{$pet->name} ({$pet->status})";

                                if ($activeApplicationsCount > 0) {
                                    $applicationText = $activeApplicationsCount === 1
                                        ? '1 other application'
                                        : "{$activeApplicationsCount} other applications";
                                    $label .= " - {$applicationText}";
                                }

                                return [$pet->id => $label];
                            });
                    })
                    ->required()
                    ->suffixAction(
                        Action::make('viewPet')
                            ->icon(Heroicon::OutlinedArrowTopRightOnSquare)
                            ->tooltip('Open pet profile')
                            ->url(fn (Get $get): ?string => $get('pet_id')
                                ? PetResource::getUrl('edit', ['record' => $get('pet_id')])
                                : null)
                            ->openUrlInNewTab()
                            ->visible(fn (Get $get): bool => filled($get('pet_id'))),
                    )
                    ->helperText('Only available, pending, and coming soon pets can be selected. Applications count excludes this application.'),

                Select::make('second_pet_id')
                    ->label('Second Pet (Optional)')
                    ->relationship('secondPet', 'name')
                    ->searchable()
                    ->preload()
                    ->live()
                    ->options(function ($record, Get $get) {
                        $currentApplicationId = $record?->id;
                        $firstPetId = $get('pet_id');

                        return Pet::query()
                            ->where(function ($query) {
                                $query->whereIn('status', ['available', 'pending', 'coming_soon']);
                                if (Setting::get('require_application_for_manual_adoption', false)) {
                                    $query->orWhere(fn ($q) => $q
                                        ->where('status', 'adopted')
                                        ->whereDoesntHave('adoptionApplications'));
                                }
                            })
                            ->when($firstPetId, fn ($q) => $q->where('id', '!=', $firstPetId))
                            ->orderBy('name')
                            ->get()
                            ->mapWithKeys(function (Pet $pet) use ($currentApplicationId) {
                                $activeApplicationsCount = AdoptionApplication::query()
                                    ->where(function ($query) use ($pet) {
                                        $query->where('pet_id', $pet->id)
                                            ->orWhere('second_pet_id', $pet->id);
                                    })
                                    ->whereNotIn('status', ['cancelled', 'rejected', 'archived'])
                                    ->when($currentApplicationId, fn ($q) => $q->where('id', '!=', $currentApplicationId))
                                    ->count();

                                $label = "{$pet->name} ({$pet->status})";

                                if ($activeApplicationsCount > 0) {
                                    $applicationText = $activeApplicationsCount === 1
                                        ? '1 other application'
                                        : "{$activeApplicationsCount} other applications";
                                    $label .= " - {$applicationText}";
                                }

                                return [$pet->id => $label];
                            });
                    })
                    ->suffixAction(
                        Action::make('viewSecondPet')
                            ->icon(Heroicon::OutlinedArrowTopRightOnSquare)
                            ->tooltip('Open pet profile')
                            ->url(fn (Get $get): ?string => $get('second_pet_id')
                                ? PetResource::getUrl('edit', ['record' => $get('second_pet_id')])
                                : null)
                            ->openUrlInNewTab()
                            ->visible(fn (Get $get): bool => filled($get('second_pet_id'))),
                    )
                    ->helperText('Select a second pet for this adoption application. Only available, pending, and coming soon pets can be selected.'),
            ]);
    }
}
