<?php

namespace App\Filament\Widgets;

use App\Filament\Resources\InitiativeResource;
use App\Models\InitiativeResult;
use BezhanSalleh\FilamentShield\Traits\HasWidgetShield;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Widgets\Concerns\InteractsWithPageFilters;
use Filament\Widgets\TableWidget as BaseWidget;

class InitiativeResultsStatusTable extends BaseWidget
{
    use HasWidgetShield, InteractsWithPageFilters;

    protected static ?string $heading = null;

    protected static ?int $sort = 7;

    protected static bool $isLazy = false;

    protected static ?string $pollingInterval = null;

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

    public function getHeading(): string
    {
        return __('pages.projects_dashboard').' - '.__('widgets.initiative_results_status');
    }

    public function getTableHeading(): string
    {
        return __('pages.projects_dashboard').' - '.__('widgets.initiative_results_status');
    }

    public function table(Table $table): Table
    {
        return $table
            ->query($this->getBaseQuery())
            ->columns([
                Tables\Columns\TextColumn::make('initiative.name')
                    ->label(__('widgets.initiative'))
                    ->sortable()
                    ->searchable()
                    ->wrap()
                    ->url(fn (InitiativeResult $record): string => InitiativeResource::getUrl('view', ['record' => $record->initiative]))
                    ->color('primary')
                    ->weight('medium'),

                Tables\Columns\TextColumn::make('expected_total')
                    ->label(__('widgets.target_single'))
                    ->getStateUsing(function (InitiativeResult $record) {
                        return $this->sumExpected($record);
                    })
                    ->formatStateUsing(fn ($state) => number_format($state, 2))
                    ->alignEnd()
                    ->sortable(),

                Tables\Columns\TextColumn::make('actual_total')
                    ->label(__('widgets.actual_single'))
                    ->getStateUsing(function (InitiativeResult $record) {
                        return $this->sumActual($record);
                    })
                    ->formatStateUsing(fn ($state) => number_format($state, 2))
                    ->alignEnd()
                    ->sortable(),

                Tables\Columns\TextColumn::make('achievement')
                    ->label(__('widgets.achievement_percentage'))
                    ->getStateUsing(function (InitiativeResult $record) {
                        $expected = $this->sumExpected($record);
                        if ($expected <= 0) {
                            return 0;
                        }
                        $actual = $this->sumActual($record);

                        return round(min(100, ($actual / $expected) * 100), 1);
                    })
                    ->formatStateUsing(fn ($state) => number_format($state, 1).'%')
                    ->badge()
                    ->color(fn ($state) => $state >= 80 ? 'success' : ($state >= 50 ? 'warning' : 'danger'))
                    ->alignCenter()
                    ->sortable(),

                Tables\Columns\TextColumn::make('performance_card_results')
                    ->label(__('widgets.related_performance_results'))
                    ->getStateUsing(function (InitiativeResult $record) {
                        return $record->performanceCardResults
                            ->pluck('result')
                            ->filter()
                            ->values()
                            ->implode(', ');
                    })
                    ->tooltip(fn (InitiativeResult $record) => $record->performanceCardResults->pluck('name')->filter()->implode("\n"))
                    ->wrap()
                    ->toggleable(),

                Tables\Columns\TextColumn::make('expected_q1')
                    ->label('Q1 T')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
                Tables\Columns\TextColumn::make('actual_q1')
                    ->label('Q1 A')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
                Tables\Columns\TextColumn::make('expected_q2')
                    ->label('Q2 T')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
                Tables\Columns\TextColumn::make('actual_q2')
                    ->label('Q2 A')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
                Tables\Columns\TextColumn::make('expected_q3')
                    ->label('Q3 T')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
                Tables\Columns\TextColumn::make('actual_q3')
                    ->label('Q3 A')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
                Tables\Columns\TextColumn::make('expected_q4')
                    ->label('Q4 T')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
                Tables\Columns\TextColumn::make('actual_q4')
                    ->label('Q4 A')
                    ->alignEnd()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(fn ($state) => $state !== null ? number_format($state, 2) : '-'),
            ])
            ->striped()
            ->paginated([10, 25, 50])
            ->defaultPaginationPageOption(25);
    }

    protected function getBaseQuery()
    {
        $departmentId = $this->filters['department_id'] ?? null;
        $walletId = $this->filters['performance_wallet_id'] ?? null;
        $initiativeId = $this->filters['initiative_id'] ?? null;

        $query = InitiativeResult::query()->with([
            'initiative.performanceWallet.performanceCard',
            'performanceCardResults',
        ]);

        if ($initiativeId) {
            $query->where('initiative_id', $initiativeId);
        } elseif ($walletId) {
            $query->whereHas('initiative', function ($q) use ($walletId) {
                $q->where('performance_wallet_id', $walletId);
            });
        } elseif ($departmentId) {
            $query->whereHas('initiative.performanceWallet.performanceCard', function ($q) use ($departmentId) {
                $q->where('department_id', $departmentId);
            });
        }

        return $query;
    }

    private function sumExpected(InitiativeResult $record): float
    {
        return collect([
            $record->expected_q1,
            $record->expected_q2,
            $record->expected_q3,
            $record->expected_q4,
        ])->filter(fn ($v) => $v !== null)->sum();
    }

    private function sumActual(InitiativeResult $record): float
    {
        return collect([
            $record->actual_q1,
            $record->actual_q2,
            $record->actual_q3,
            $record->actual_q4,
        ])->filter(fn ($v) => $v !== null)->sum();
    }
}
