<?php

declare(strict_types=1);

namespace App\Filament\Widgets\Supervisor;

use App\Models\User;
use App\Services\CollectorVisibilityResolver;
use App\Services\Metrics\CollectionMetricsService;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;

/**
 * Tabla de rendimiento de collectors del día.
 *
 * Muestra el desempeño de cada collector en tiempo real.
 */
class CollectorPerformanceTodayTable extends BaseWidget
{
    protected static ?string $heading = 'Rendimiento de Collectors Hoy';

    protected static ?int $sort = 2;

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

    /**
     * Solo visible para Supervisores.
     */
    public static function canView(): bool
    {
        $user = Auth::user();

        return $user && $user->hasRole('supervisor') && ! $user->isSuperAdmin();
    }

    public function table(Table $table): Table
    {
        $user = Auth::user();
        $companyId = $user->company_id;

        $service = app(CollectionMetricsService::class);
        $performance = $service->getCollectorPerformanceToday($companyId);
        $collectorIds = $performance->pluck('collector_id')->toArray();

        // Visibilidad supervisor→cobrador (#71): un supervisor asignado solo ve a
        // su equipo; con sees_all_collectors ve a todos los de la empresa.
        $visibility = app(CollectorVisibilityResolver::class)->resolve($user);
        if ($visibility['mode'] === CollectorVisibilityResolver::MODE_ASSIGNED) {
            $collectorIds = array_values(array_intersect($collectorIds, $visibility['collector_ids']));
        } elseif ($visibility['mode'] === CollectorVisibilityResolver::MODE_UNASSIGNED) {
            $collectorIds = [];
        }

        return $table
            ->query(
                User::query()
                    ->where('company_id', $companyId)
                    ->whereIn('id', $collectorIds)
            )
            ->columns([
                TextColumn::make('name')
                    ->label('Collector')
                    ->searchable()
                    ->sortable(),

                TextColumn::make('collected_today')
                    ->label('Cobrado Hoy')
                    ->getStateUsing(function (User $record) use ($performance) {
                        $data = $performance->firstWhere('collector_id', $record->id);

                        return $data['collected_today'] ?? 0;
                    })
                    ->money('COP')
                    ->sortable(query: function (Builder $query, string $direction) use ($performance) {
                        // Custom sorting based on collected amount
                        $sortedIds = $performance
                            ->sortBy('collected_today', SORT_REGULAR, $direction === 'desc')
                            ->pluck('collector_id')
                            ->toArray();

                        if (! empty($sortedIds)) {
                            $query->orderByRaw('FIELD(id, '.implode(',', $sortedIds).')');
                        }

                        return $query;
                    })
                    ->color(fn ($state) => $state > 0 ? 'success' : 'gray'),

                TextColumn::make('payments_count')
                    ->label('Pagos')
                    ->getStateUsing(function (User $record) use ($performance) {
                        $data = $performance->firstWhere('collector_id', $record->id);

                        return $data['payments_count'] ?? 0;
                    })
                    ->badge()
                    ->color(fn (int $state): string => match (true) {
                        $state >= 10 => 'success',
                        $state >= 5 => 'info',
                        $state > 0 => 'warning',
                        default => 'gray',
                    }),

                TextColumn::make('status')
                    ->label('Estado')
                    ->getStateUsing(function (User $record) use ($performance) {
                        $data = $performance->firstWhere('collector_id', $record->id);

                        return match ($data['status'] ?? 'no_goal') {
                            'exceeded' => 'Meta superada',
                            'on_track' => 'En camino',
                            'behind' => 'Atrasado',
                            'critical' => 'Crítico',
                            'no_goal' => $data['payments_count'] > 0 ? 'Activo' : 'Sin actividad',
                            default => 'N/A',
                        };
                    })
                    ->badge()
                    ->color(function (User $record) use ($performance) {
                        $data = $performance->firstWhere('collector_id', $record->id);

                        return match ($data['status'] ?? 'no_goal') {
                            'exceeded' => 'success',
                            'on_track' => 'info',
                            'behind' => 'warning',
                            'critical' => 'danger',
                            'no_goal' => ($data['payments_count'] ?? 0) > 0 ? 'success' : 'gray',
                            default => 'gray',
                        };
                    }),

                TextColumn::make('goal_percentage')
                    ->label('% Meta')
                    ->getStateUsing(function (User $record) use ($performance) {
                        $data = $performance->firstWhere('collector_id', $record->id);
                        $percentage = $data['goal_percentage'] ?? 0;

                        return $data['goal'] ? "{$percentage}%" : 'Sin meta';
                    })
                    ->color(function (User $record) use ($performance) {
                        $data = $performance->firstWhere('collector_id', $record->id);
                        if (! $data['goal']) {
                            return 'gray';
                        }
                        $percentage = $data['goal_percentage'] ?? 0;

                        return match (true) {
                            $percentage >= 100 => 'success',
                            $percentage >= 70 => 'info',
                            $percentage >= 50 => 'warning',
                            default => 'danger',
                        };
                    }),
            ])
            ->defaultSort('collected_today', 'desc')
            ->paginated(false)
            ->poll('60s');
    }
}
