<?php

namespace App\Filament\Association\Resources\FinancialAssignmentResource\Pages;

use App\Filament\Association\Resources\FinancialAssignmentResource;
use App\Models\FinancialAssignment;
use App\Models\FinancialItem;
use App\Models\User;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Filament\Forms;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\DB;

class ListFinancialAssignments extends ListRecords
{
    protected static string $resource = FinancialAssignmentResource::class;

    protected function getHeaderActions(): array
    {
        return [
            Actions\Action::make('assign_to_all')
                ->label('Assign to All Members')
                ->icon('heroicon-o-users')
                ->color('success')
                ->modalHeading('Assign Financial Item to All Members')
                ->modalDescription('Quickly assign a financial item to all members in your association.')
                ->modalWidth('2xl')
                ->form([
                    Forms\Components\Section::make()
                        ->schema([
                            Forms\Components\Select::make('financial_item_id')
                                ->label('Select Financial Item')
                                ->options(function () {
                                    return FinancialItem::where('association_id', filament()->getTenant()->id)
                                        ->where('is_active', true)
                                        ->orderBy('title')
                                        ->get()
                                        ->mapWithKeys(function ($item) {
                                            $type = ucfirst($item->type);
                                            $amount = '₦' . number_format($item->amount, 2);
                                            return [$item->id => "{$item->title} ({$type} - {$amount})"];
                                        });
                                })
                                ->searchable()
                                ->required()
                                ->live()
                                ->afterStateUpdated(function ($state, Forms\Set $set) {
                                    if ($state) {
                                        $item = FinancialItem::find($state);
                                        if ($item) {
                                            $set('amount', $item->amount);
                                            $set('due_date', $item->due_date);

                                            // Preview members
                                            $memberCount = User::whereHas('associations', function ($query) {
                                                $query->where('associations.id', filament()->getTenant()->id);
                                            })->count();
                                            $set('member_preview', $memberCount);
                                        }
                                    }
                                })
                                ->helperText('Choose which dues, fee, or levy to assign')
                                ->columnSpanFull(),

                            Forms\Components\Placeholder::make('member_preview')
                                ->label('Members to Assign')
                                ->content(function (Forms\Get $get): string {
                                    $count = $get('member_preview') ?? 0;
                                    if ($count > 0) {
                                        return "✅ This will be assigned to **{$count} member(s)**";
                                    }
                                    return 'Select a financial item to see member count';
                                })
                                ->columnSpanFull(),

                            Forms\Components\Grid::make(2)
                                ->schema([
                                    Forms\Components\TextInput::make('amount')
                                        ->label('Amount per Member')
                                        ->prefix('₦')
                                        ->numeric()
                                        ->required()
                                        ->helperText('Auto-filled from item, can be customized'),

                                    Forms\Components\DatePicker::make('due_date')
                                        ->label('Due Date')
                                        ->displayFormat('M d, Y')
                                        ->native(false)
                                        ->helperText('Optional: Set a due date'),
                                ]),

                            Forms\Components\Checkbox::make('skip_existing')
                                ->label('Skip members who already have this assignment')
                                ->helperText('Prevents duplicate assignments for the same financial item')
                                ->default(true)
                                ->live()
                                ->columnSpanFull(),

                            Forms\Components\Placeholder::make('info')
                                ->content(function (Forms\Get $get): string {
                                    $skipExisting = $get('skip_existing');
                                    if ($skipExisting) {
                                        return '💡 **Smart Assignment**: Only members without this assignment will receive it.';
                                    }
                                    return '⚠️ **All Members**: This will create assignments even for members who already have one for this item.';
                                })
                                ->columnSpanFull(),
                        ]),
                ])
                ->action(function (array $data): void {
                    $financialItem = FinancialItem::find($data['financial_item_id']);

                    if (!$financialItem) {
                        Notification::make()
                            ->title('Error')
                            ->danger()
                            ->body('Financial item not found.')
                            ->send();
                        return;
                    }

                    // Get all members in the association
                    $members = User::whereHas('associations', function ($query) {
                        $query->where('associations.id', filament()->getTenant()->id);
                    })->get();

                    if ($members->isEmpty()) {
                        Notification::make()
                            ->title('No Members Found')
                            ->warning()
                            ->body('There are no members in your association to assign this item to.')
                            ->send();
                        return;
                    }

                    $assignedCount = 0;
                    $skippedCount = 0;

                    DB::beginTransaction();
                    try {
                        foreach ($members as $member) {
                            // Check if assignment already exists
                            if ($data['skip_existing']) {
                                $exists = FinancialAssignment::where('user_id', $member->id)
                                    ->where('financial_item_id', $financialItem->id)
                                    ->where('association_id', filament()->getTenant()->id)
                                    ->exists();

                                if ($exists) {
                                    $skippedCount++;
                                    continue;
                                }
                            }

                            // Create assignment
                            FinancialAssignment::create([
                                'financial_item_id' => $financialItem->id,
                                'user_id' => $member->id,
                                'association_id' => filament()->getTenant()->id,
                                'amount' => $data['amount'],
                                'due_date' => $data['due_date'] ?? null,
                                'amount_paid' => 0,
                                'status' => 'pending',
                            ]);

                            $assignedCount++;
                        }

                        DB::commit();

                        $message = "Successfully assigned **{$financialItem->title}** to **{$assignedCount} member(s)**";
                        if ($skippedCount > 0) {
                            $message .= " (Skipped {$skippedCount} existing assignment(s))";
                        }

                        Notification::make()
                            ->title('Bulk Assignment Complete')
                            ->success()
                            ->body($message)
                            ->send();

                    } catch (\Exception $e) {
                        DB::rollBack();

                        Notification::make()
                            ->title('Assignment Failed')
                            ->danger()
                            ->body('An error occurred: ' . $e->getMessage())
                            ->send();
                    }
                })
                ->modalSubmitActionLabel('Assign to All Members')
                ->successNotificationTitle('Assignments Created')
                ->extraModalFooterActions([
                    Actions\Action::make('cancel')
                        ->label('Cancel')
                        ->color('gray')
                        ->action(fn () => null),
                ]),

            Actions\CreateAction::make()
                ->label('Assign to Single Member')
                ->icon('heroicon-o-user-plus'),
        ];
    }

    protected function getHeaderActionsPosition(): string
    {
        return 'bottom';
    }

    public function getTabs(): array
    {
        return [
            'all' => \Filament\Resources\Components\Tab::make('All Assignments'),

            'pending' => \Filament\Resources\Components\Tab::make('Pending')
                ->modifyQueryUsing(fn ($query) => $query->where('status', 'pending'))
                ->badge(fn () => FinancialAssignment::where('status', 'pending')
                    ->where('association_id', filament()->getTenant()->id)
                    ->count()
                ),

            'overdue' => \Filament\Resources\Components\Tab::make('Overdue')
                ->modifyQueryUsing(fn ($query) => $query->where('status', 'pending')
                    ->where('due_date', '<', now()))
                ->badge(fn () => FinancialAssignment::where('status', 'pending')
                    ->where('due_date', '<', now())
                    ->where('association_id', filament()->getTenant()->id)
                    ->count()
                )
                ->badgeColor('danger'),

            'paid' => \Filament\Resources\Components\Tab::make('Paid')
                ->modifyQueryUsing(fn ($query) => $query->where('status', 'paid'))
                ->badge(fn () => FinancialAssignment::where('status', 'paid')
                    ->where('association_id', filament()->getTenant()->id)
                    ->count()
                )
                ->badgeColor('success'),

            'waived' => \Filament\Resources\Components\Tab::make('Waived')
                ->modifyQueryUsing(fn ($query) => $query->where('status', 'waived'))
                ->badge(fn () => FinancialAssignment::where('status', 'waived')
                    ->where('association_id', filament()->getTenant()->id)
                    ->count()
                )
                ->badgeColor('gray'),
        ];
    }
}
