<?php

namespace App\Filament\Admin\Resources\ProjectCharters\RelationManagers;

use App\Models\ProjectCharterDeliverable;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ForceDeleteAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Grouping\Group;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\HtmlString;

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

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                TextInput::make('name')
                    ->label(__('project_charter.task_name'))
                    ->required()
                    ->maxLength(255),

                Textarea::make('description')
                    ->label(__('project_charter.task_description'))
                    ->columnSpanFull(),

                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);
                    }),

                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;
                    }),

                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;
                    }),

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

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

                SpatieMediaLibraryFileUpload::make('task_files')
                    ->label(__('project_charter.task_files'))
                    ->collection('task_files')
                    ->multiple()
                    ->downloadable()
                    ->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')
            ->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([
                TextColumn::make('name')
                    ->label(__('project_charter.task_name'))
                    ->searchable()
                    ->sortable(),

                // TODO: status, estimated_progress_percentage, deivation

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

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

                        return null;
                    }),

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

                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(),

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

                TextColumn::make('created_at')
                    ->label(__('project_charter.created_at'))
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                TrashedFilter::make(),
            ])
            ->headerActions([
                CreateAction::make(),
            ])
            ->recordActions([
                EditAction::make(),
                DeleteAction::make(),
                ForceDeleteAction::make(),
                RestoreAction::make(),
            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make(),
                    ForceDeleteBulkAction::make(),
                    RestoreBulkAction::make(),
                ]),
            ])
            ->modifyQueryUsing(fn (Builder $query) => $query
                ->withoutGlobalScopes([
                    SoftDeletingScope::class,
                ]));
    }

    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 isReadOnly(): bool
    {
        return false;
    }
}
