<?php

namespace App\Filament\Clusters\WeeklyOps\Resources\TaskCollections\RelationManagers;

use App\Models\Task;
use Filament\Actions\AttachAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DetachAction;
use Filament\Actions\DetachBulkAction;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Arr;

class TasksRelationManager extends RelationManager
{
    protected static string $relationship = 'tasks';

    protected static ?string $inverseRelationship = 'taskCollections';

    public function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('title')
                    ->label(__('admin.tasks.table.title'))
                    ->getStateUsing(fn (Task $record) => $this->formatTaskTitle($record->title))
                    ->searchable(['title->de', 'title->en'])
                    ->limit(60),
                TextColumn::make('emotion.name')
                    ->label(__('admin.tasks.fields.emotion'))
                    ->getStateUsing(function (Task $record) {
                        $value = optional($record->emotion)->name;
                        if (is_array($value)) {
                            $locale = app()->getLocale();

                            return $value[$locale] ?? ($value['de'] ?? ($value['en'] ?? ''));
                        }

                        return (string) ($value ?? '');
                    })
                    ->sortable(),
                TextColumn::make('difficulty')
                    ->label(__('admin.tasks.fields.difficulty.label'))
                    ->badge(),
                IconColumn::make('is_active')
                    ->label(__('admin.tasks.table.is_active'))
                    ->boolean(),
                TextColumn::make('sort_order')
                    ->label(__('admin.tasks.table.sort_order'))
                    ->sortable(),
            ])
            ->headerActions([
                AttachAction::make()
                    ->recordTitle(fn (Task $record) => $this->formatTaskTitle($record->title))
                    ->recordSelectOptionsQuery(fn (Builder $query): Builder => $query->whereNull('tenant_id'))
                    ->multiple()
                    ->after(function (array $data): void {
                        $collection = $this->getOwnerRecord();
                        $recordIds = Arr::wrap($data['recordId'] ?? []);

                        if ($recordIds === []) {
                            return;
                        }

                        $collection->reassignTasks($recordIds);
                    }),
            ])
            ->recordActions([
                DetachAction::make()
                    ->after(function (?Task $record): void {
                        if (! $record) {
                            return;
                        }

                        $collectionId = $this->getOwnerRecord()->getKey();

                        if ($record->collection_id === $collectionId) {
                            $record->update(['collection_id' => null]);
                        }
                    }),
            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    DetachBulkAction::make()
                        ->after(function (Collection $records): void {
                            $collectionId = $this->getOwnerRecord()->getKey();

                            $ids = $records
                                ->filter(fn (Task $record) => $record->collection_id === $collectionId)
                                ->pluck('id')
                                ->all();

                            if ($ids === []) {
                                return;
                            }

                            Task::query()
                                ->whereIn('id', $ids)
                                ->update(['collection_id' => null]);
                        }),
                ]),
            ]);
    }

    /**
     * @param  array<string, string>|string|null  $value
     */
    protected function formatTaskTitle(array|string|null $value): string
    {
        if (is_array($value)) {
            $locale = app()->getLocale();

            return $value[$locale]
                ?? ($value['de'] ?? ($value['en'] ?? Arr::first($value) ?? ''));
        }

        if (is_string($value)) {
            return $value;
        }

        return '';
    }
}
