<?php

declare(strict_types=1);

namespace App\Filament\Resources\Partners\RelationManagers;

use App\Enums\WithdrawalType;
use App\Models\PartnerWithdrawal;
use App\Services\PartnerInvestmentService;
use Carbon\Carbon;
use Filament\Actions\Action as TableAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;

class WithdrawalsRelationManager extends RelationManager
{
    protected static string $relationship = 'withdrawals';

    protected static ?string $title = 'Retiros';

    protected static ?string $recordTitleAttribute = 'id';

    public function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('id')
                    ->label('#')
                    ->sortable(),

                TextColumn::make('amount')
                    ->label('Monto')
                    ->money('COP', locale: 'es_CO')
                    ->sortable()
                    ->color('danger'),

                TextColumn::make('type')
                    ->label('Tipo')
                    ->badge()
                    ->formatStateUsing(fn ($state) => $state instanceof WithdrawalType
                        ? $state->getLabel()
                        : (is_string($state) ? (WithdrawalType::tryFrom($state)?->getLabel() ?? $state) : '-')
                    )
                    ->color(fn ($state) => $state instanceof WithdrawalType
                        ? $state->getColor()
                        : 'gray'
                    ),

                TextColumn::make('approval_status')
                    ->label('Aprobacion')
                    ->badge()
                    ->formatStateUsing(fn ($state) => match ($state) {
                        'pending' => 'Pendiente',
                        'approved' => 'Aprobado',
                        'rejected' => 'Rechazado',
                        default => $state ?? '-',
                    })
                    ->color(fn ($state) => match ($state) {
                        'pending' => 'warning',
                        'approved' => 'success',
                        'rejected' => 'danger',
                        default => 'gray',
                    }),

                TextColumn::make('operation_date')
                    ->label('Fecha')
                    ->date('d/m/Y')
                    ->sortable(),

                TextColumn::make('method')
                    ->label('Metodo')
                    ->formatStateUsing(fn ($state) => match ($state) {
                        'cash' => 'Efectivo',
                        'transfer' => 'Transferencia',
                        'card' => 'Tarjeta',
                        'mobile_money' => 'Billetera digital',
                        'other' => 'Otro',
                        default => $state ?? '-',
                    })
                    ->toggleable(),

                TextColumn::make('user.name')
                    ->label('Registrado por')
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('approval_status')
                    ->label('Estado')
                    ->options([
                        'pending' => 'Pendiente',
                        'approved' => 'Aprobado',
                        'rejected' => 'Rechazado',
                    ]),

                SelectFilter::make('type')
                    ->label('Tipo')
                    ->options([
                        'profit_withdrawal' => 'Retiro de utilidades',
                        'capital_return' => 'Devolucion de capital',
                        'dividend_payment' => 'Pago de dividendos',
                    ]),
            ])
            ->headerActions([
                TableAction::make('register_withdrawal')
                    ->label('Solicitar retiro')
                    ->icon('heroicon-o-arrow-up-tray')
                    ->color('warning')
                    ->form([
                        TextInput::make('amount')
                            ->label('Monto')
                            ->required()
                            ->numeric()
                            ->minValue(0.01)
                            ->prefix('$'),

                        Select::make('type')
                            ->label('Tipo de retiro')
                            ->options([
                                'profit_withdrawal' => 'Retiro de utilidades',
                                'capital_return' => 'Devolucion de capital',
                                'dividend_payment' => 'Pago de dividendos',
                            ])
                            ->required(),

                        Select::make('method')
                            ->label('Metodo de pago')
                            ->options([
                                'cash' => 'Efectivo',
                                'transfer' => 'Transferencia bancaria',
                                'card' => 'Tarjeta',
                                'mobile_money' => 'Billetera digital',
                                'other' => 'Otro',
                            ]),

                        DatePicker::make('operation_date')
                            ->label('Fecha de operacion')
                            ->required()
                            ->default(now()),

                        TextInput::make('reference')
                            ->label('Referencia'),

                        Textarea::make('notes')
                            ->label('Notas')
                            ->rows(2),
                    ])
                    ->action(function (array $data) {
                        $service = app(PartnerInvestmentService::class);

                        try {
                            $service->registerWithdrawal(
                                partner: $this->ownerRecord,
                                amount: (string) $data['amount'],
                                type: WithdrawalType::from($data['type']),
                                operationDate: Carbon::parse($data['operation_date']),
                                method: $data['method'] ?? null,
                                reference: $data['reference'] ?? null,
                                notes: $data['notes'] ?? null,
                            );

                            Notification::make()
                                ->success()
                                ->title('Retiro solicitado')
                                ->body('La solicitud de retiro ha sido registrada y esta pendiente de aprobacion.')
                                ->send();
                        } catch (\Exception $e) {
                            Notification::make()
                                ->danger()
                                ->title('Error al solicitar retiro')
                                ->body($e->getMessage())
                                ->send();
                        }
                    }),
            ])
            ->actions([
                TableAction::make('approve')
                    ->label('Aprobar')
                    ->icon('heroicon-o-check-circle')
                    ->color('success')
                    ->visible(fn (PartnerWithdrawal $record) => $record->isPending())
                    ->requiresConfirmation()
                    ->modalHeading('Aprobar retiro')
                    ->modalDescription(fn (PartnerWithdrawal $record) => "Aprobar retiro por \${$record->amount}?")
                    ->form([
                        Textarea::make('approval_notes')
                            ->label('Observaciones')
                            ->rows(2),
                    ])
                    ->action(function (PartnerWithdrawal $record, array $data) {
                        $service = app(PartnerInvestmentService::class);

                        try {
                            $service->approveWithdrawal($record, $data['approval_notes'] ?? null);

                            Notification::make()
                                ->success()
                                ->title('Retiro aprobado')
                                ->body('El egreso ha sido registrado automaticamente.')
                                ->send();
                        } catch (\Exception $e) {
                            Notification::make()
                                ->danger()
                                ->title('Error')
                                ->body($e->getMessage())
                                ->send();
                        }
                    }),

                TableAction::make('reject')
                    ->label('Rechazar')
                    ->icon('heroicon-o-x-circle')
                    ->color('danger')
                    ->visible(fn (PartnerWithdrawal $record) => $record->isPending())
                    ->requiresConfirmation()
                    ->form([
                        Textarea::make('reason')
                            ->label('Motivo de rechazo')
                            ->required()
                            ->rows(2),
                    ])
                    ->action(function (PartnerWithdrawal $record, array $data) {
                        $service = app(PartnerInvestmentService::class);

                        try {
                            $service->rejectWithdrawal($record, $data['reason']);

                            Notification::make()
                                ->success()
                                ->title('Retiro rechazado')
                                ->send();
                        } catch (\Exception $e) {
                            Notification::make()
                                ->danger()
                                ->title('Error')
                                ->body($e->getMessage())
                                ->send();
                        }
                    }),
            ])
            ->defaultSort('operation_date', 'desc')
            ->emptyStateHeading('Sin retiros')
            ->emptyStateDescription('Este socio aun no tiene retiros registrados.')
            ->emptyStateIcon('heroicon-o-arrow-up-tray');
    }
}
