<?php

namespace App\Filament\Resources\ProjectCharterResource\RelationManagers;

use App\Models\ProjectCharterDeliverable;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Support\Enums\MaxWidth;
use Filament\Tables;
use Filament\Tables\Grouping\Group;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\HtmlString;

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

    protected static ?string $recordTitleAttribute = 'name';

    public static function getTitle(Model $ownerRecord, string $pageClass): string
    {
        return __('project_charter.tasks');
    }

    public static function getModelLabel(): string
    {
        return __('project_charter.task');
    }

    public static function getPluralModelLabel(): string
    {
        return __('project_charter.tasks');
    }

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\Grid::make(2)
                    ->schema([
                        Forms\Components\TextInput::make('name')
                            ->label(__('project_charter.task_name'))
                            ->required()
                            ->maxLength(255)
                            ->columnSpanFull(),

                        Forms\Components\Textarea::make('description')
                            ->label(__('project_charter.task_description'))
                            ->rows(3)
                            ->columnSpanFull(),

                        Forms\Components\Select::make('project_charter_deliverable_id')
                            ->label(__('project_charter.deliverable'))
                            ->options(function (RelationManager $livewire): array {
                                // Get deliverables for the current project charter
                                $projectCharter = $livewire->getOwnerRecord();

                                return $projectCharter->deliverables()
                                    ->pluck('name', 'id')
                                    ->toArray();
                            })
                            ->required()
                            ->searchable()
                            ->reactive()
                            ->afterStateUpdated(function (callable $set, $state) {
                                // Clear the dates when deliverable changes
                                // so user must re-select them within new constraints
                                $set('start_date', null);
                                $set('end_date', null);
                            }),

                        Forms\Components\DatePicker::make('start_date')
                            ->label(__('project_charter.start_date'))
                            ->nullable()
                            ->reactive()
                            ->afterOrEqual(function (Get $get, RelationManager $livewire) {
                                // Task start_date should be >= ProjectCharter start_date
                                return $livewire->getOwnerRecord()->start_date;
                            })
                            ->beforeOrEqual(function (Get $get, RelationManager $livewire) {
                                $deliverableId = $get('project_charter_deliverable_id');
                                if ($deliverableId) {
                                    $deliverable = ProjectCharterDeliverable::find($deliverableId);

                                    // Task start_date should be <= deliverable expected_delivery_date
                                    return $deliverable?->expected_delivery_date;
                                }

                                // Fallback to ProjectCharter expected_end_date
                                return $livewire->getOwnerRecord()->expected_end_date;
                            }),

                        Forms\Components\DatePicker::make('end_date')
                            ->label(__('project_charter.expected_end_date'))
                            ->nullable()
                            ->after('start_date')
                            ->reactive()
                            ->afterOrEqual(function (Get $get, RelationManager $livewire) {
                                // Task end_date should be >= ProjectCharter start_date
                                return $livewire->getOwnerRecord()->start_date;
                            })
                            ->beforeOrEqual(function (Get $get, RelationManager $livewire) {
                                $deliverableId = $get('project_charter_deliverable_id');
                                if ($deliverableId) {
                                    $deliverable = ProjectCharterDeliverable::find($deliverableId);

                                    // Task end_date should be <= deliverable expected_delivery_date
                                    return $deliverable?->expected_delivery_date;
                                }

                                // Fallback to ProjectCharter expected_end_date
                                return $livewire->getOwnerRecord()->expected_end_date;
                            }),

                        Forms\Components\TextInput::make('estimated_cost')
                            ->label(__('project_charter.estimated_cost'))
                            ->numeric()
                            ->step(0.01)
                            ->prefix(new HtmlString('<span class="icon-saudi_riyal"></span>'))
                            ->nullable(),

                        Forms\Components\TextInput::make('actual_cost')
                            ->label(__('project_charter.total_cost'))
                            ->numeric()
                            ->step(0.01)
                            ->prefix(new HtmlString('<span class="icon-saudi_riyal"></span>'))
                            ->nullable(),

                        Forms\Components\TextInput::make('progress_percentage')
                            ->label(__('project_charter.progress_percentage'))
                            ->numeric()
                            ->step(1)
                            ->minValue(0)
                            ->maxValue(100)
                            ->default(0)
                            ->suffix('%')
                            ->columnSpanFull(),

                        Forms\Components\SpatieMediaLibraryFileUpload::make('task_files')
                            ->label(__('project_charter.task_files'))
                            ->collection('task_files')
                            ->multiple()
                            ->downloadable()
                            ->visibility('private')
                            ->acceptedFileTypes([
                                'application/pdf',
                                'application/msword',
                                'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
                                'application/vnd.ms-excel',
                                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                                'image/jpeg',
                                'image/png',
                                'image/gif',
                                'text/plain',
                            ])
                            ->maxSize(10240) // 10MB
                            ->helperText(__('project_charter.task_files_helper'))
                            ->columnSpanFull(),
                    ]),
            ]);
    }

    public function table(Table $table): Table
    {
        return $table
            ->recordTitleAttribute('name')
            // ->groups([
            //     'deliverable.name',
            // ])
            ->defaultGroup(
                Group::make('deliverable.name')
                    ->titlePrefixedWithLabel(false)
                    ->getTitleFromRecordUsing(fn ($record): string => __('project_charter.task_for_deliverable').': '.$record->deliverable->name)
                    ->getDescriptionFromRecordUsing(fn ($record): string => __('project_charter.progress').': '.$record->deliverable->progress_percentage.'%')
                    ->collapsible(),
            )
            ->columns([
                Tables\Columns\TextColumn::make('name')
                    ->label(__('project_charter.task_name'))
                    ->searchable()
                    ->sortable(),

                Tables\Columns\TextColumn::make('status')
                    ->label(__('project_charter.status'))
                    ->badge()
                    ->color(fn ($record) => $record->status_color)
                    ->formatStateUsing(function ($state) {
                        return match ($state) {
                            'not_started' => __('project_charter.task_status_not_started'),
                            'in_progress' => __('project_charter.task_status_in_progress'),
                            'late' => __('project_charter.task_status_late'),
                            'done' => __('project_charter.task_status_done'),
                            default => $state,
                        };
                    })
                    ->sortable(),

                Tables\Columns\TextColumn::make('start_date')
                    ->label(__('project_charter.start_date'))
                    ->date()
                    ->sortable()
                    ->toggleable(),

                Tables\Columns\TextColumn::make('end_date')
                    ->label(__('project_charter.expected_end_date'))
                    ->date()
                    ->sortable()
                    ->color(function ($record) {
                        if ($record->is_overdue) {
                            return 'danger';
                        }

                        return null;
                    }),

                Tables\Columns\TextColumn::make('estimated_cost')
                    ->label(__('project_charter.estimated_cost'))
                    ->numeric(2)
                    ->prefix(new HtmlString('<span class="icon-saudi_riyal"></span>'))
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),

                Tables\Columns\TextColumn::make('actual_cost')
                    ->label(__('project_charter.total_cost'))
                    ->numeric(2)
                    ->prefix(new HtmlString('<span class="icon-saudi_riyal"></span>'))
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),

                Tables\Columns\TextColumn::make('progress_percentage')
                    ->label(__('project_charter.progress'))
                    ->formatStateUsing(fn ($state) => $state.'%')
                    ->badge()
                    ->color(fn ($state) => match (true) {
                        $state >= 100 => 'success',
                        $state >= 75 => 'warning',
                        $state >= 50 => 'info',
                        $state > 0 => 'gray',
                        default => 'secondary',
                    })
                    // ->summarize(Sum::make())
                    ->sortable(),

                Tables\Columns\TextColumn::make('estimated_progress_percentage')
                    ->label(__('project_charter.estimated_progress'))
                    ->formatStateUsing(function ($record) {
                        if (! $record->start_date || ! $record->end_date) {
                            return 'N/A';
                        }

                        return $record->estimated_progress_percentage.'%';
                    })
                    ->badge()
                    ->color(fn ($record) => $record->estimated_progress_color)
                    ->sortable(),

                Tables\Columns\TextColumn::make('progress_deviation')
                    ->label(__('project_charter.progress_deviation'))
                    ->formatStateUsing(function ($record) {
                        if (! $record->start_date || ! $record->end_date) {
                            return 'N/A';
                        }

                        return $record->progress_deviation.'%';
                    })
                    ->badge()
                    ->color(fn ($record) => $record->progress_deviation_color)
                    ->sortable(),

                Tables\Columns\TextColumn::make('files_count')
                    ->label(__('project_charter.files'))
                    ->state(fn ($record) => $record->files_count)
                    ->badge()
                    ->color(fn ($state) => $state > 0 ? 'success' : 'gray')
                    ->icon(fn ($state) => $state > 0 ? 'heroicon-o-document' : 'heroicon-o-document-text')
                    ->sortable(false),

                Tables\Columns\TextColumn::make('created_at')
                    ->label(__('project_charter.created_at'))
                    ->date()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                Tables\Filters\SelectFilter::make('project_charter_deliverable_id')
                    ->label(__('project_charter.deliverable'))
                    ->relationship('deliverable', 'name'),

                Tables\Filters\Filter::make('overdue')
                    ->label(__('project_charter.overdue_tasks'))
                    ->query(fn (Builder $query): Builder => $query->whereDate('end_date', '<', now())->where('progress_percentage', '<', 100)),

                Tables\Filters\Filter::make('completed')
                    ->label(__('project_charter.completed_tasks'))
                    ->query(fn (Builder $query): Builder => $query->where('progress_percentage', '>=', 100)),

                Tables\Filters\Filter::make('in_progress')
                    ->label(__('project_charter.in_progress_tasks'))
                    ->query(fn (Builder $query): Builder => $query->where('progress_percentage', '>', 0)->where('progress_percentage', '<', 100)),
            ])
            ->headerActions([
                Tables\Actions\CreateAction::make(),
                Tables\Actions\Action::make('view_chart')
                    ->label(__('widgets.view_chart'))
                    ->icon('heroicon-o-chart-bar')
                    ->color('success')
                    ->slideOver()
                    ->modalWidth(MaxWidth::FiveExtraLarge)
                    ->modalHeading('')
                    ->modalSubmitAction(false)
                    ->modalCancelAction(false)
                    ->modalContent(fn () => view('filament.custom.admin-project-tasks-gantt-modal', [
                        'ownerRecord' => $this->getOwnerRecord(),
                    ])),
            ])
            ->actions([
                Tables\Actions\ActionGroup::make([
                    Tables\Actions\EditAction::make(),
                    Tables\Actions\DeleteAction::make()
                        ->before(function (Tables\Actions\DeleteAction $action, Model $record) {
                            if (! $record->canBeDeleted()) {
                                \Filament\Notifications\Notification::make()
                                    ->title(__('project_charter.cannot_delete_task'))
                                    ->body(__('project_charter.cannot_delete_last_task_message'))
                                    ->danger()
                                    ->send();
                                $action->cancel();
                            }
                        }),
                ]),
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make()
                        ->before(function (Tables\Actions\DeleteBulkAction $action, \Illuminate\Support\Collection $records) {
                            // Check if any of the records to be deleted would violate the business rule
                            foreach ($records as $record) {
                                if (! $record->canBeDeleted()) {
                                    \Filament\Notifications\Notification::make()
                                        ->title(__('project_charter.cannot_delete_tasks'))
                                        ->body(__('project_charter.cannot_delete_tasks_message'))
                                        ->danger()
                                        ->send();
                                    $action->cancel();

                                    return;
                                }
                            }
                        }),
                ]),
            ])
            ->defaultSort('end_date', 'asc');
    }

    public function isReadOnly(): bool
    {
        return false;
    }

    protected function canCreate(): bool
    {
        return true;
    }

    protected function canEdit(\Illuminate\Database\Eloquent\Model $record): bool
    {
        return true;
    }

    protected function canDelete(\Illuminate\Database\Eloquent\Model $record): bool
    {
        return true;
    }
}
