<?php

namespace App\Filament\Association\Resources;

use App\Filament\Association\Resources\CommitteeResource\Pages;
use App\Filament\Association\Resources\CommitteeResource\RelationManagers;
use App\Models\Committee;
use App\Models\Election;
use App\Models\Event;
use App\Models\Project;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Facades\Filament;
use Illuminate\Support\Str;

class CommitteeResource extends Resource
{
    protected static ?string $model = Committee::class;

    protected static ?string $navigationGroup = 'Projects & Governance';

    protected static ?string $navigationIcon = 'heroicon-o-user-group';

    protected static ?int $navigationSort = 2;

    protected static ?string $tenantOwnershipRelationshipName = 'association';

    public static function canAccess(): bool
    {
        return Filament::getTenant()?->hasModule('committees') ?? false;
    }

    public static function form(Form $form): Form
    {
        $tenantId = Filament::getTenant()?->id;

        return $form
            ->schema([
                Forms\Components\Tabs::make('Committee Details')
                    ->tabs([
                        Forms\Components\Tabs\Tab::make('Details')
                            ->schema([
                                Forms\Components\TextInput::make('name')
                                    ->required()
                                    ->maxLength(255)
                                    ->live(onBlur: true)
                                    ->afterStateUpdated(fn (Forms\Set $set, ?string $state) => $set('slug', Str::slug($state))),
                                Forms\Components\TextInput::make('slug')
                                    ->required()
                                    ->maxLength(255)
                                    ->unique(ignoreRecord: true),
                                Forms\Components\Select::make('status')
                                    ->options(Committee::STATUSES)
                                    ->required()
                                    ->default('active'),
                                Forms\Components\Textarea::make('description')
                                    ->maxLength(1000)
                                    ->columnSpanFull(),
                                Forms\Components\RichEditor::make('mandate')
                                    ->required()
                                    ->label('Mandate / Terms of Reference')
                                    ->helperText('What the committee is tasked to achieve.')
                                    ->columnSpanFull(),
                                Forms\Components\RichEditor::make('expected_outcome')
                                    ->label('Expected Outcome / Deliverables')
                                    ->helperText('What deliverables are expected from the committee.')
                                    ->columnSpanFull(),
                            ])->columns(2),

                        Forms\Components\Tabs\Tab::make('Assignment')
                            ->schema([
                                Forms\Components\Select::make('committable_type')
                                    ->label('Context Type')
                                    ->options(function () {
                                        $tenant = Filament::getTenant();
                                        $options = ['' => 'General / Standing Committee'];

                                        if ($tenant?->hasModule('projects')) {
                                            $options[Project::class] = 'Project';
                                        }

                                        // Events are a core module, always available
                                        $options[Event::class] = 'Event';

                                        if ($tenant?->hasModule('elections')) {
                                            $options[Election::class] = 'Election';
                                        }

                                        return $options;
                                    })
                                    ->default('')
                                    ->live()
                                    ->afterStateUpdated(fn (Forms\Set $set) => $set('committable_id', null)),
                                Forms\Components\Select::make('committable_id')
                                    ->label(function (Forms\Get $get): string {
                                        $type = $get('committable_type');
                                        return match ($type) {
                                            Project::class => 'Linked Project',
                                            Event::class => 'Linked Event',
                                            Election::class => 'Linked Election',
                                            default => 'Linked Entity',
                                        };
                                    })
                                    ->options(function (Forms\Get $get) use ($tenantId) {
                                        $type = $get('committable_type');

                                        if ($type === Project::class) {
                                            return Project::where('association_id', $tenantId)
                                                ->orderByDesc('created_at')
                                                ->pluck('title', 'id');
                                        }

                                        if ($type === Event::class) {
                                            return Event::where('association_id', $tenantId)
                                                ->orderByDesc('created_at')
                                                ->pluck('title', 'id');
                                        }

                                        if ($type === Election::class) {
                                            return Election::where('association_id', $tenantId)
                                                ->orderByDesc('created_at')
                                                ->pluck('title', 'id');
                                        }

                                        return [];
                                    })
                                    ->searchable()
                                    ->preload()
                                    ->visible(fn (Forms\Get $get) => !empty($get('committable_type')))
                                    ->rule(function (Forms\Get $get) use ($tenantId) {
                                        return function (string $attribute, $value, $fail) use ($get, $tenantId) {
                                            $type = $get('committable_type');
                                            if (!$type || !$value) return;

                                            // Verify the linked entity belongs to the same association
                                            $exists = $type::where('id', $value)
                                                ->where('association_id', $tenantId)
                                                ->exists();

                                            if (!$exists) {
                                                $fail('The selected entity does not belong to this association.');
                                            }
                                        };
                                    }),
                            ])->columns(2),

                        Forms\Components\Tabs\Tab::make('Timeline')
                            ->schema([
                                Forms\Components\DatePicker::make('start_date'),
                                Forms\Components\DatePicker::make('end_date')
                                    ->after('start_date'),
                            ])->columns(2),
                    ])->columnSpanFull(),

                Forms\Components\Hidden::make('created_by')
                    ->default(auth()->id()),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('name')
                    ->searchable()
                    ->sortable()
                    ->limit(40),
                Tables\Columns\TextColumn::make('status')
                    ->badge()
                    ->formatStateUsing(fn (string $state) => Committee::STATUSES[$state] ?? ucfirst($state))
                    ->color(fn (string $state): string => match ($state) {
                        'active' => 'success',
                        'dissolved' => 'danger',
                        'on_hold' => 'warning',
                        default => 'gray',
                    }),
                Tables\Columns\TextColumn::make('active_members_count')
                    ->label('Members')
                    ->counts('activeMembers')
                    ->sortable(),
                Tables\Columns\TextColumn::make('chairperson')
                    ->label('Chairperson')
                    ->getStateUsing(fn (Committee $record) => $record->chairperson_name ?? '—'),
                Tables\Columns\TextColumn::make('context')
                    ->label('Linked To')
                    ->getStateUsing(function (Committee $record): string {
                        if (!$record->committable_type) {
                            return 'General';
                        }
                        return class_basename($record->committable_type);
                    })
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        'General' => 'gray',
                        'Project' => 'info',
                        'Event' => 'success',
                        'Election' => 'warning',
                        default => 'gray',
                    }),
                Tables\Columns\TextColumn::make('start_date')
                    ->date()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                Tables\Columns\TextColumn::make('end_date')
                    ->date()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
                Tables\Columns\TextColumn::make('created_at')
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                Tables\Filters\SelectFilter::make('status')
                    ->options(Committee::STATUSES),
                Tables\Filters\SelectFilter::make('context')
                    ->label('Context Type')
                    ->options([
                        'general' => 'General / Standing',
                        'project' => 'Project',
                        'event' => 'Event',
                        'election' => 'Election',
                    ])
                    ->query(function ($query, array $data) {
                        if ($data['value'] === 'general') {
                            $query->whereNull('committable_type');
                        } elseif ($data['value'] === 'project') {
                            $query->where('committable_type', Project::class);
                        } elseif ($data['value'] === 'event') {
                            $query->where('committable_type', Event::class);
                        } elseif ($data['value'] === 'election') {
                            $query->where('committable_type', Election::class);
                        }
                    }),
            ])
            ->actions([
                Tables\Actions\EditAction::make(),
                Tables\Actions\ActionGroup::make([
                    Tables\Actions\Action::make('dissolve')
                        ->label('Dissolve')
                        ->icon('heroicon-o-x-circle')
                        ->color('danger')
                        ->requiresConfirmation()
                        ->action(fn (Committee $record) => $record->update(['status' => Committee::STATUS_DISSOLVED]))
                        ->visible(fn (Committee $record) => $record->status === Committee::STATUS_ACTIVE),
                    Tables\Actions\Action::make('reactivate')
                        ->label('Reactivate')
                        ->icon('heroicon-o-arrow-path')
                        ->color('success')
                        ->requiresConfirmation()
                        ->action(fn (Committee $record) => $record->update(['status' => Committee::STATUS_ACTIVE]))
                        ->visible(fn (Committee $record) => $record->status !== Committee::STATUS_ACTIVE),
                ]),
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                ]),
            ])
            ->defaultSort('created_at', 'desc');
    }

    public static function getRelations(): array
    {
        return [
            RelationManagers\MembersRelationManager::class,
            RelationManagers\ReportsRelationManager::class,
        ];
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListCommittees::route('/'),
            'create' => Pages\CreateCommittee::route('/create'),
            'edit' => Pages\EditCommittee::route('/{record}/edit'),
        ];
    }
}
