<?php

namespace App\Filament\Resources\AdoptionApplications\Widgets;

use App\Filament\Resources\Pets\PetResource;
use App\Models\AdoptionApplication;
use App\Models\Pet;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Select;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Support\Icons\Heroicon;
use Filament\Widgets\Widget;

class PetDetailsWidget extends Widget implements HasActions, HasForms
{
    use InteractsWithActions;
    use InteractsWithForms;

    protected string $view = 'filament.resources.adoption-applications.widgets.pet-details-widget';

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

    public ?AdoptionApplication $record = null;

    /**
     * @return ?Pet
     */
    public function getPet()
    {
        return $this->record?->pet()->with(['species', 'breed'])->first();
    }

    /**
     * @return ?Pet
     */
    public function getSecondPet()
    {
        return $this->record?->secondPet()->with(['species', 'breed'])->first();
    }

    public function selectPetAction(): Action
    {
        return Action::make('selectPet')
            ->label('Select Pet')
            ->icon(Heroicon::OutlinedPlus)
            ->color('primary')
            ->disabled(fn () => ! $this->record->canModifyPetLink())
            ->form([
                Select::make('pet_id')
                    ->label('Pet')
                    ->required()
                    ->searchable()
                    ->preload()
                    ->options(function () {
                        $currentApplicationId = $this->record->id;
                        $isLegacyMigration = $this->record->isFromLegacyMigration();
                        $isApprovedOrArchived = in_array($this->record->status, ['approved', 'archived']);

                        // For legacy migration applications that are approved/archived, only show adopted pets
                        $allowedStatuses = ($isLegacyMigration && $isApprovedOrArchived)
                            ? ['adopted']
                            : ['available', 'pending', 'coming_soon'];

                        $secondPetId = $this->record->second_pet_id;

                        return Pet::query()
                            ->whereIn('status', $allowedStatuses)
                            ->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];
                            });
                    })
                    ->helperText(function () {
                        $isLegacyMigration = $this->record->isFromLegacyMigration();
                        $isApprovedOrArchived = in_array($this->record->status, ['approved', 'archived']);

                        if ($isLegacyMigration && $isApprovedOrArchived) {
                            return 'Legacy migration: Only adopted pets can be selected. Pet status will be preserved.';
                        }

                        return 'Only available, pending, and coming soon pets can be selected. Applications count excludes this application.';
                    }),
            ])
            ->action(function (array $data) {
                $this->record->update(['pet_id' => $data['pet_id']]);

                Notification::make()
                    ->success()
                    ->title('Pet linked successfully')
                    ->send();

                $this->dispatch('$refresh');
            });
    }

    public function viewPetAction(): Action
    {
        return Action::make('viewPet')
            ->label('Open Pet Profile')
            ->icon(Heroicon::OutlinedArrowTopRightOnSquare)
            ->color('gray')
            ->outlined()
            ->visible(fn (): bool => filled($this->record->pet_id))
            ->url(fn (): ?string => filled($this->record->pet_id)
                ? PetResource::getUrl('edit', ['record' => $this->record->pet_id])
                : null)
            ->openUrlInNewTab();
    }

    public function viewSecondPetAction(): Action
    {
        return Action::make('viewSecondPet')
            ->label('Open Pet Profile')
            ->icon(Heroicon::OutlinedArrowTopRightOnSquare)
            ->color('gray')
            ->outlined()
            ->visible(fn (): bool => filled($this->record->second_pet_id))
            ->url(fn (): ?string => filled($this->record->second_pet_id)
                ? PetResource::getUrl('edit', ['record' => $this->record->second_pet_id])
                : null)
            ->openUrlInNewTab();
    }

    public function removePetAction(): Action
    {
        return Action::make('removePet')
            ->label('Unlink Pet')
            ->icon(Heroicon::OutlinedXMark)
            ->color('danger')
            ->outlined()
            ->disabled(fn () => ! $this->record->canModifyPetLink())
            ->requiresConfirmation()
            ->modalHeading('Remove Pet from Application?')
            ->modalDescription('Are you sure you want to remove this pet from the application?')
            ->action(function () {
                $this->record->update(['pet_id' => null]);

                Notification::make()
                    ->success()
                    ->title('Pet removed successfully')
                    ->send();

                $this->dispatch('$refresh');
            });
    }

    public function selectSecondPetAction(): Action
    {
        return Action::make('selectSecondPet')
            ->label('Select Second Pet')
            ->icon(Heroicon::OutlinedPlus)
            ->color('primary')
            ->disabled(fn () => ! $this->record->canModifyPetLink())
            ->form([
                Select::make('second_pet_id')
                    ->label('Second Pet')
                    ->required()
                    ->searchable()
                    ->preload()
                    ->options(function () {
                        $currentApplicationId = $this->record->id;
                        $firstPetId = $this->record->pet_id;
                        $isLegacyMigration = $this->record->isFromLegacyMigration();
                        $isApprovedOrArchived = in_array($this->record->status, ['approved', 'archived']);

                        $allowedStatuses = ($isLegacyMigration && $isApprovedOrArchived)
                            ? ['adopted']
                            : ['available', 'pending', 'coming_soon'];

                        return Pet::query()
                            ->whereIn('status', $allowedStatuses)
                            ->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];
                            });
                    })
                    ->helperText(function () {
                        $isLegacyMigration = $this->record->isFromLegacyMigration();
                        $isApprovedOrArchived = in_array($this->record->status, ['approved', 'archived']);

                        if ($isLegacyMigration && $isApprovedOrArchived) {
                            return 'Legacy migration: Only adopted pets can be selected.';
                        }

                        return 'Select a second pet for this adoption application. Only available, pending, and coming soon pets can be selected.';
                    }),
            ])
            ->action(function (array $data) {
                $this->record->update(['second_pet_id' => $data['second_pet_id']]);

                Notification::make()
                    ->success()
                    ->title('Second pet linked successfully')
                    ->send();

                $this->dispatch('$refresh');
            });
    }

    public function removeSecondPetAction(): Action
    {
        return Action::make('removeSecondPet')
            ->label('Unlink Second Pet')
            ->icon(Heroicon::OutlinedXMark)
            ->color('danger')
            ->outlined()
            ->disabled(fn () => ! $this->record->canModifyPetLink())
            ->requiresConfirmation()
            ->modalHeading('Remove Second Pet from Application?')
            ->modalDescription('Are you sure you want to remove the second pet from the application?')
            ->action(function () {
                $this->record->update(['second_pet_id' => null]);

                Notification::make()
                    ->success()
                    ->title('Second pet removed successfully')
                    ->send();

                $this->dispatch('$refresh');
            });
    }
}
