<?php

namespace App\Filament\Resources;

use App\Enums\BookingStatus;
use App\Enums\PaymentStatus;
use App\Filament\Resources\BookingResource\Pages;
use App\Filament\Resources\BookingResource\RelationManagers;
use App\Models\Booking;
use App\Models\User;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Facades\DB;

class BookingResource extends Resource
{
    protected static ?int $navigationSort = 4;
    protected static ?string $model = Booking::class;

    public static function getNavigationGroup(): ?string
    {
        return __('Content Management');
    }

    protected static ?string $navigationIcon = 'heroicon-o-calendar';

    public static function getNavigationBadge(): ?string
    {
        return static::getModel()::count();
    }
    public static function getLabel(): ?string
    {
        return __('Booking');
    }

    public static function getPluralLabel(): ?string
    {
        return __('Bookings');
    }

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\Select::make('user_id')
                    ->label(__('User'))
                    ->relationship('user', 'first_name')
                    ->disabledOn('edit')
                    ->required(),
                Forms\Components\TextInput::make('total_amount')
                    ->label(__('Total Amount'))
                    ->disabledOn('edit')
                    ->required()
                    ->numeric(),
                Forms\Components\TextInput::make('commission_amount')
                    ->label(__('Commission Amount'))
                    ->disabledOn('edit')
                    ->required()
                    ->numeric(),
                Forms\Components\TextInput::make('net_amount')
                    ->label(__('Net Amount'))
                    ->required()
                    ->disabledOn('edit')
                    ->numeric(),
                Forms\Components\TextInput::make('payment_method')
                    ->label(__('Payment Method'))
                    ->disabledOn('edit')
                    ->required()
                    ->maxLength(255),
                Forms\Components\Select::make('payment_status')
                    ->disabledOn('edit')
                    ->label(__('Payment Status'))
                    ->options(PaymentStatus::options())
                    ->required(),
                Forms\Components\Select::make('status')
                    ->disabledOn('edit')
                    ->label(__('Status'))
                    ->options(BookingStatus::options())
                    ->required(),
                Forms\Components\TextInput::make('payment_id')
                    ->label(__('app.filament.fields.payment_id'))
                    ->disabled(),
                Forms\Components\Section::make(__('app.filament.fields.payment_response'))
                    ->collapsible()
                    ->collapsed()
                    ->hidden()
                    ->schema([
                        Forms\Components\KeyValue::make('payment_response')
                            ->label('')
                            ->disabled()
                            ->formatStateUsing(function ($state) {
                                if (is_string($state)) {
                                    $state = json_decode($state, true);
                                }

                                $flattened = [];
                                $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($state ?? []));
                                foreach ($iterator as $leafValue) {
                                    $keys = [];
                                    foreach (range(0, $iterator->getDepth()) as $depth) {
                                        $keys[] = $iterator->getSubIterator($depth)->key();
                                    }
                                    $flattened[implode('.', $keys)] = $leafValue;
                                }
                                return $flattened;
                            }),
                    ]),
                Forms\Components\Textarea::make('notes')
                    ->label(__('Notes')),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('id')
                    ->numeric()
                    ->label(__("ID")),
                Tables\Columns\TextColumn::make('user.first_name')
                    ->url(fn($record) => \App\Filament\Resources\UserResource::getUrl('view', ["record" => $record->user_id]))
                    ->openUrlInNewTab()
                    ->label(__('User'))
                    ->searchable()->sortable(),
                Tables\Columns\TextColumn::make('items_count')
                    ->label(__('Items Count'))
                    ->counts('items')
                    ->url(fn($record) => \App\Filament\Resources\BookingItemResource::getUrl('index', ['tableFilters[booking_id][values][0]' => $record->id]))
                    ->openUrlInNewTab()
                    ->numeric()
                    ->sortable(),
                Tables\Columns\TextColumn::make('commission_amount')
                    ->label(__('Commission'))
                    ->money('SAR')->sortable(),
                Tables\Columns\TextColumn::make('net_amount')
                    ->label(__('Net Amount'))
                    ->money('SAR')->sortable(),
                Tables\Columns\TextColumn::make('total_amount')
                    ->label(__('Total Amount'))
                    ->money('SAR')->sortable(),
                // Tables\Columns\TextColumn::make('payment_method')
                //     ->label(__('Payment Method'))
                //     ->searchable(),
                Tables\Columns\TextColumn::make('status')
                    ->label(__('Status'))
                    ->formatStateUsing(fn(Booking $record) => $record->status->label())
                    ->searchable(),
                Tables\Columns\TextColumn::make('payment_status')
                    ->label(__('Payment Status'))
                    ->formatStateUsing(fn(Booking $record) => $record->payment_status->label())
                    ->searchable(),
                Tables\Columns\TextColumn::make('created_at')
                    ->label(__('Created At'))
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                Tables\Columns\TextColumn::make('updated_at')
                    ->label(__('Updated At'))
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                // \Filament\Tables\Filters\TrashedFilter::make(),
                SelectFilter::make('user_id')
                    ->relationship(
                        'user',
                        'first_name',
                        // fn(Builder $query, ?string $search): Builder => $query
                        //     ->where('first_name', 'like', "%{$search}%")
                        //     ->orWhere('last_name', 'like', "%{$search}%")
                        //     ->orWhere('email', 'like', "%{$search}%")
                        //     ->orWhere('phone', 'like', "%{$search}%")
                    )
                    ->getSearchResultsUsing(function (string $search): array {
                        // You can use a simpler query if you only search a few fields
                        $users = User::query()
                            ->where(DB::raw("CONCAT(first_name, ' ', last_name)"), 'like', "%{$search}%")
                            ->orWhere('email', 'like', "%{$search}%")
                            ->orWhere('phone', 'like', "%{$search}%")
                            ->limit(10) // It's good practice to limit the results for performance
                            ->withTrashed()
                            ->get();

                        // We must return a key-value array of [id => ...text...]
                        return $users->mapWithKeys(fn(User $user) => [$user->id => $user->fullName])->all();
                    })
                    ->searchable()
                    // ->preload()
                    ->label(__('User')),
                SelectFilter::make('status')
                    ->label(__('Status'))
                    ->options(BookingStatus::options()),
                SelectFilter::make('payment_status')
                    ->label(__('Payment Status'))
                    ->options(PaymentStatus::options()),
                Filter::make('created_at')
                    ->form([
                        Forms\Components\DatePicker::make('created_from')->label(__('Created From')),
                        Forms\Components\DatePicker::make('created_until')->label(__('Created To')),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when(
                                $data['created_from'],
                                fn(Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date),
                            )
                            ->when(
                                $data['created_until'],
                                fn(Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date),
                            );
                    }),
            ])
            ->actions([
                Tables\Actions\ViewAction::make(),
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                ]),
            ]);
    }

    public static function getRelations(): array
    {
        return [
            RelationManagers\BookingItemsRelationManager::class,
            RelationManagers\ActivitiesRelationManager::class,
        ];
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListBookings::route('/'),
            'view' => Pages\ViewBooking::route('/{record}'),
            'edit' => Pages\EditBooking::route('/{record}/edit'),
        ];
    }

    public static function getEloquentQuery(): Builder
    {
        return parent::getEloquentQuery()->withTrashed();
    }
}
