<?php

namespace App\Filament\Resources;

use Filament\Forms;
use App\Models\Coin;
use App\Models\User;
use Filament\Tables;
use App\Models\Network;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Forms\Form;
use Filament\Tables\Table;
use Filament\Resources\Resource;
use Filament\Tables\Actions\Action;
use Illuminate\Support\Facades\Hash;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Repeater;
use Illuminate\Database\Eloquent\Model;
use Filament\Forms\Components\TextInput;
use Filament\Tables\Actions\ActionGroup;
use Illuminate\Database\Eloquent\Builder;
use App\Filament\Resources\UserResource\Pages;
use App\Http\Controllers\Admin\UserController;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use App\Http\Controllers\Admin\UserSettingsController;
use App\Filament\Resources\UserResource\RelationManagers;

class UserResource extends Resource {
    protected static ?string $model = User::class;

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

    protected static ?string $navigationGroup = 'User Management';

    protected static ?int $navigationSort = 1;

    public static function form(Form $form): Form {
        return $form
            ->schema([
                Section::make('User Information')->description('Change user basic information.')
                    ->schema([
                        Forms\Components\TextInput::make('email')
                            ->email()
                            ->required()
                            ->maxLength(255),
                        Forms\Components\TextInput::make('phone')
                            ->tel()
                            ->required()
                            ->maxLength(255),
                    ])->columns(),

                Section::make('Security')->description('Change user\'s security settings.')
                    ->schema([
                        Forms\Components\TextInput::make('password')
                            ->password()
                            ->dehydrateStateUsing(fn($state) => Hash::make($state))
                            ->dehydrated(fn($state) => filled($state))
                            ->required(fn(string $context): bool => $context === 'create'),

                        Forms\Components\TextInput::make('pin')
                            ->password()
                            ->dehydrateStateUsing(fn($state) => Hash::make($state))
                            ->dehydrated(fn($state) => filled($state))
                            ->maxLength(4)
                            ->rule('digits:4')
                            ->required(fn(string $context): bool => $context === 'create'),

                        Forms\Components\Textarea::make('secret_phrase')
                            ->columnSpanFull(),
                    ])->columns(),

                Section::make('Verifications')->schema([
                    Forms\Components\DateTimePicker::make('email_verified_at'),
                    Forms\Components\DateTimePicker::make('secret_phrase_verified_at'),
                ])->columns(),

                Section::make('Others')->schema([
                    Forms\Components\TextInput::make('pay_id')
                        ->required()
                        ->maxLength(255)
                        ->readOnly(),

                    Forms\Components\Select::make('can_invest')
                        ->options(['No', 'Yes'])
                        ->label('Enable Investment')
                        ->native(false)
                        ->default(1)
                        ->required()

                ])->columns(),

            ])->columns(3);
    }

    public static function table(Table $table): Table {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('email')
                    ->sortable()
                    ->searchable(),
                Tables\Columns\TextColumn::make('email_verified_at')
                    ->dateTime()
                    ->sortable(),
                Tables\Columns\TextColumn::make('phone')
                    ->searchable(),
                Tables\Columns\TextColumn::make('pay_id')
                    ->searchable(),
                Tables\Columns\ToggleColumn::make('can_invest')
                    ->searchable(),
                Tables\Columns\TextColumn::make('created_at')
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                Tables\Columns\TextColumn::make('updated_at')
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                //
            ])
            ->actions([
                ActionGroup::make([
                    Tables\Actions\ViewAction::make(),
                    Tables\Actions\EditAction::make(),
                    Action::make('updateBalance')
                        ->icon('heroicon-o-banknotes')
                        ->form([
                            TextInput::make('user')
                                ->afterStateHydrated(fn(TextInput $component, User $record) => $component->state($record->email))
                                ->disabled(),
                            Section::make()->columns()->schema([
                                Select::make('coin_id')
                                    ->label('Coin')
                                    ->options(Coin::get()->pluck('full_name', 'id'))
                                    ->live()
                                    ->searchable()
                                    ->native(false)
                                    ->preload()
                                    ->required(),

                                Select::make('action')
                                    ->options([
                                        'credit' => 'Credit',
                                        'debit' => 'Debit'
                                    ])
                                    ->native(false)
                                    ->preload()
                                    ->required(),

                                TextInput::make('amount')
                                    ->numeric()
                                    ->required()
                                    ->hint(function (Get $get, User $record) {
                                        if ($get('coin_id')) {
                                            $balance = $record->balances()->where('coin_id', $get('coin_id'))->first();
                                            return "{$balance?->coin->name} balance is {$balance?->value}.";
                                        }
                                    })
                                    ->columnSpanFull()
                                    ->placeholder('0.000'),
                            ])
                        ])
                        ->action(function (array $data, User $record, Action $action) {
                            return UserController::updateBalance($data, $record, $action);
                        }),

                    Action::make('updateFeesAndLimit')
                        ->icon('heroicon-o-percent-badge')
                        ->form([
                            TextInput::make('user')
                                ->afterStateHydrated(fn(TextInput $component, User $record) => $component->state($record->email))
                                ->disabled(),
                            Section::make('Fees')->schema([
                                Select::make('coin_id')
                                    ->label('Coin')
                                    ->options(Network::get()->pluck('display_coin.full_name', 'display_coin.id'))
                                    ->native(false)
                                    ->preload()
                                    ->live()
                                    ->searchable()
                                    ->required()
                                    ->afterStateUpdated(function (string $state, Set $set, User $record) {
                                        $userSetting = $record->settings()->where('coin_id', $state)->first();
                                        $set('is_active', $userSetting->is_active);
                                        $set('allow_payid_send', $userSetting->allow_payid_send);
                                        $set('allow_swap', $userSetting?->allow_swap);
                                        $set('allow_send', $userSetting?->allow_send);
                                        $set('minimum_withdrawal', $userSetting?->minimum_withdrawal);
                                        $set('minimum_swap', $userSetting?->minimum_swap);
                                        $set('minimum_buy', $userSetting?->minimum_buy);
                                    }),

                                Select::make('fee')
                                    ->native(false)
                                    ->required()
                                    ->live()
                                    ->afterStateUpdated(function (Set $set, $state, User $record, Get $get) {
                                        $coin = Coin::find($get('coin_id'));
                                        $userSetting = $coin->network_coin->settings()->where('user_id', $record->id)->first();
                                        if ($userSetting) {
                                            $set('value', $userSetting->$state);
                                        }
                                    })
                                    ->options([
                                        'network_fee' => 'Network Fee',
                                        'swap_fee' => 'Swap Fee',
                                    ]),

                                TextInput::make('value')
                                    ->numeric()
                                    ->label(fn(Get $get) => convert_text($get('fee') ?? 'value'))
                                    ->suffix(
                                        function (Get $get) {
                                            return $get('coin_id')
                                                ? Coin::find($get('coin_id'))?->network_coin?->symbol
                                                : '';
                                        }
                                    )
                                    ->columnSpanFull(),
                            ])->columns(),
                        ])
                        ->action(fn (array $data, User $record) => UserSettingsController::update($data, $record)),
                    Action::make('updateSettings')
                        ->icon('heroicon-o-cog')
                        ->form([
                            TextInput::make('user')
                                ->afterStateHydrated(fn(TextInput $component, User $record) => $component->state($record->email))
                                ->disabled(),
                            Section::make('Limits')->schema([
                                Select::make('coin_id')
                                    ->label('Coin')
                                    ->options(Coin::get()->pluck('full_name', 'id'))
                                    ->native(false)
                                    ->preload()
                                    ->live()
                                    ->searchable()
                                    ->required()
                                    ->afterStateUpdated(function (string $state, Set $set, User $record) {
                                        $userSetting = $record->settings()->where('coin_id', $state)->first();
                                        $set('is_active', $userSetting->is_active);
                                        $set('allow_payid_send', $userSetting->allow_payid_send);
                                        $set('allow_swap', $userSetting?->allow_swap);
                                        $set('allow_send', $userSetting?->allow_send);
                                        $set('minimum_withdrawal', $userSetting?->minimum_withdrawal);
                                        $set('minimum_swap', $userSetting?->minimum_swap);
                                        $set('minimum_buy', $userSetting?->minimum_buy);
                                    })
                                    ->columnSpanFull(),

                                TextInput::make('minimum_withdrawal')
                                    ->label('Minimum send')
                                    ->numeric()
                                    ->required()
                                    ->hint('When minimum to "0", user won\'t be charged.')
                                    ->suffix(
                                        function (Get $get) {
                                            return $get('coin_id')
                                                ? Coin::find($get('coin_id'))->symbol
                                                : '';
                                        }
                                    ),

                                TextInput::make('minimum_swap')
                                    ->numeric()
                                    ->required()
                                    ->hint('When minimum to "0", user won\'t be charged.')
                                    ->suffix(
                                        function (Get $get) {
                                            return $get('coin_id')
                                                ? Coin::find($get('coin_id'))->symbol
                                                : '';
                                        }
                                    ),

                                TextInput::make('minimum_buy')
                                    ->numeric()
                                    ->hint('When minimum to "0", user won\'t be charged.')
                                    ->required()
                                    ->suffix(
                                        function (Get $get) {
                                            return $get('coin_id')
                                                ? Coin::find($get('coin_id'))->symbol
                                                : '';
                                        }
                                    ),
                            ])->columns(3),

                            Section::make('Status')->schema([
                                Toggle::make('allow_payid_send'),
                                Toggle::make('allow_send'),
                                Toggle::make('allow_swap'),
                                Toggle::make('is_active')
                            ])->columns(2),
                        ])
                        ->action(fn(array $data, User $record) => UserSettingsController::updateSettings($data, $record))
                ])
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                ]),
            ]);
    }

    public static function getRelations(): array {
        return [
            //
        ];
    }

    public static function getPages(): array {
        return [
            'index' => Pages\ListUsers::route('/'),
            'create' => Pages\CreateUser::route('/create'),
            'view' => Pages\ViewUser::route('/{record}'),
            'edit' => Pages\EditUser::route('/{record}/edit'),
        ];
    }
}
