<?php

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

use App\Models\Person;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;

/**
 * People Relation Manager
 * 
 * Manages the insured persons associated with an insurance inquiry.
 * This relation manager allows administrators to add, edit, and remove
 * individuals covered under a specific insurance policy.
 */
class PeopleRelationManager extends RelationManager
{
    /**
     * The relationship name in the parent model
     */
    protected static string $relationship = 'people';

    /**
     * The title displayed in the relation manager
     */
    protected static ?string $title = 'Insured Persons';

    /**
     * The attribute used for record titles
     */
    protected static ?string $recordTitleAttribute = 'first_name';

    /**
     * Form configuration for creating/editing people
     * 
     * Defines the form fields and validation rules for insured persons.
     * Organized logically for easy data entry.
     */
    public function form(Form $form): Form
    {
        return $form
            ->schema([
                // Section 1: Personal Information
                Forms\Components\Section::make('Personal Information')
                    ->description('Basic details of the insured person')
                    ->schema([
                        Forms\Components\TextInput::make('first_name')
                            ->label('First Name')
                            ->required()
                            ->maxLength(255)
                            ->placeholder('Enter first name')
                            ->helperText('Legal first name of the insured person'),
                        
                        Forms\Components\TextInput::make('last_name')
                            ->label('Last Name')
                            ->required()
                            ->maxLength(255)
                            ->placeholder('Enter last name')
                            ->helperText('Legal last name of the insured person'),
                        
                        Forms\Components\DatePicker::make('born_at')
                            ->label('Date of Birth')
                            ->required()
                            ->native(false)
                            ->displayFormat('Y-m-d')
                            ->maxDate(now())
                            ->helperText('Date of birth (YYYY-MM-DD format)'),
                        
                        Forms\Components\Select::make('is_male')
                            ->label('Gender')
                            ->required()
                            ->options([
                                true => 'Male',
                                false => 'Female',
                            ])
                            ->native(false)
                            ->helperText('Select gender'),
                    ])
                    ->columns(2),
                
                // Section 2: Insurance Details
                Forms\Components\Section::make('Insurance Details')
                    ->description('Insurance-specific information')
                    ->schema([
                        Forms\Components\Select::make('relationship')
                            ->label('Relationship to Primary')
                            ->options([
                                'self' => 'Self (Primary)',
                                'spouse' => 'Spouse',
                                'child' => 'Child',
                                'parent' => 'Parent',
                                'sibling' => 'Sibling',
                                'other' => 'Other Relative',
                                'friend' => 'Friend',
                                'business' => 'Business Associate',
                            ])
                            ->default('self')
                            ->native(false)
                            ->helperText('Relationship to primary insured person'),
                        
                        Forms\Components\Toggle::make('is_primary')
                            ->label('Primary Insured Person')
                            ->onColor('success')
                            ->offColor('gray')
                            ->default(true)
                            ->helperText('Mark as primary insured person'),
                        
                        Forms\Components\Select::make('price_id')
                            ->label('Insurance Price Plan')
                            ->relationship('price', 'id', fn ($query) => $query->where('is_active', true))
                            ->searchable()
                            ->preload()
                            ->helperText('Select the insurance price plan for this person'),
                        
                        Forms\Components\Select::make('deductible_id')
                            ->label('Deductible Option')
                            ->relationship('deductible', 'id', fn ($query) => $query->where('is_active', true))
                            ->searchable()
                            ->preload()
                            ->helperText('Select deductible amount'),
                    ])
                    ->columns(2),
                
                // Section 3: Additional Information (Collapsible)
                Forms\Components\Section::make('Additional Information')
                    ->description('Optional details and notes')
                    ->collapsible()
                    ->schema([
                        Forms\Components\Textarea::make('notes')
                            ->label('Additional Notes')
                            ->rows(3)
                            ->maxLength(1000)
                            ->placeholder('Any additional notes about this person')
                            ->helperText('Optional notes or special requirements'),
                    ]),
            ]);
    }

    /**
     * Table configuration for listing people
     * 
     * Displays insured persons in a sortable, filterable table
     * with actions for managing individual records.
     */
    public function table(Table $table): Table
    {
        return $table
            ->columns([
                // Column 1: Name (First + Last)
                Tables\Columns\TextColumn::make('first_name')
                    ->label('First Name')
                    ->searchable()
                    ->sortable()
                    ->tooltip('First name'),
                
                Tables\Columns\TextColumn::make('last_name')
                    ->label('Last Name')
                    ->searchable()
                    ->sortable()
                    ->tooltip('Last name'),
                
                // Column 2: Date of Birth and Age
                Tables\Columns\TextColumn::make('born_at')
                    ->label('Date of Birth')
                    ->date('Y-m-d')
                    ->sortable()
                    ->tooltip('Date of birth'),
                
                Tables\Columns\TextColumn::make('calculated_age')
                    ->label('Age')
                    ->sortable()
                    ->alignCenter()
                    ->tooltip('Calculated age based on date of birth'),
                
                // Column 3: Gender
                Tables\Columns\IconColumn::make('is_male')
                    ->label('Gender')
                    ->boolean()
                    ->trueIcon('heroicon-o-user')
                    ->falseIcon('heroicon-o-user')
                    ->trueColor('blue')
                    ->falseColor('pink')
                    ->trueTooltip('Male')
                    ->falseTooltip('Female'),
                
                // Column 4: Relationship
                Tables\Columns\TextColumn::make('relationship')
                    ->label('Relationship')
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        'self' => 'primary',
                        'spouse' => 'success',
                        'child' => 'warning',
                        'parent' => 'info',
                        'sibling' => 'secondary',
                        default => 'gray',
                    })
                    ->formatStateUsing(fn (string $state): string => match ($state) {
                        'self' => 'Primary',
                        'spouse' => 'Spouse',
                        'child' => 'Child',
                        'parent' => 'Parent',
                        'sibling' => 'Sibling',
                        'other' => 'Other',
                        'friend' => 'Friend',
                        'business' => 'Business',
                        default => ucfirst($state),
                    })
                    ->tooltip('Relationship to primary insured'),
                
                // Column 5: Primary Status
                Tables\Columns\IconColumn::make('is_primary')
                    ->label('Primary')
                    ->boolean()
                    ->trueIcon('heroicon-o-star')
                    ->falseIcon('heroicon-o-user')
                    ->trueColor('warning')
                    ->falseColor('gray')
                    ->trueTooltip('Primary insured person')
                    ->falseTooltip('Additional insured person'),
                
                // Column 6: Insurance Details
                Tables\Columns\TextColumn::make('price.daily_cost')
                    ->label('Daily Rate')
                    ->money('CAD')
                    ->sortable()
                    ->alignRight()
                    ->tooltip('Daily insurance rate'),
                
                Tables\Columns\TextColumn::make('deductible.amount')
                    ->label('Deductible')
                    ->money('CAD')
                    ->sortable()
                    ->alignRight()
                    ->tooltip('Deductible amount'),
            ])
            ->filters([
                // Filter by relationship type
                Tables\Filters\SelectFilter::make('relationship')
                    ->label('Filter by Relationship')
                    ->options([
                        'self' => 'Primary',
                        'spouse' => 'Spouse',
                        'child' => 'Child',
                        'parent' => 'Parent',
                        'sibling' => 'Sibling',
                        'other' => 'Other',
                    ])
                    ->multiple()
                    ->preload(),
                
                // Filter by gender
                Tables\Filters\SelectFilter::make('is_male')
                    ->label('Filter by Gender')
                    ->options([
                        true => 'Male',
                        false => 'Female',
                    ])
                    ->multiple()
                    ->preload(),
                
                // Filter by primary status
                Tables\Filters\SelectFilter::make('is_primary')
                    ->label('Primary Status')
                    ->options([
                        true => 'Primary Insured',
                        false => 'Additional Insured',
                    ])
                    ->multiple()
                    ->preload(),
                
                // Age range filter
                Tables\Filters\Filter::make('age_range')
                    ->form([
                        Forms\Components\TextInput::make('min_age')
                            ->label('Minimum Age')
                            ->numeric()
                            ->minValue(0),
                        Forms\Components\TextInput::make('max_age')
                            ->label('Maximum Age')
                            ->numeric()
                            ->minValue(0),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when(
                                $data['min_age'] ?? null,
                                fn (Builder $query, $age): Builder => $query->whereRaw('TIMESTAMPDIFF(YEAR, born_at, CURDATE()) >= ?', [$age])
                            )
                            ->when(
                                $data['max_age'] ?? null,
                                fn (Builder $query, $age): Builder => $query->whereRaw('TIMESTAMPDIFF(YEAR, born_at, CURDATE()) <= ?', [$age])
                            );
                    })
                    ->indicateUsing(function (array $data): array {
                        $indicators = [];
                        if ($data['min_age'] ?? null) {
                            $indicators[] = 'Min age: ' . $data['min_age'];
                        }
                        if ($data['max_age'] ?? null) {
                            $indicators[] = 'Max age: ' . $data['max_age'];
                        }
                        return $indicators;
                    }),
            ])
            ->headerActions([
                // Add new person
                Tables\Actions\CreateAction::make()
                    ->label('Add Person')
                    ->icon('heroicon-o-user-plus')
                    ->tooltip('Add a new insured person'),
            ])
            ->actions([
                // Edit person
                Tables\Actions\EditAction::make()
                    ->icon('heroicon-o-pencil')
                    ->tooltip('Edit this person'),
                
                // Delete person
                Tables\Actions\DeleteAction::make()
                    ->icon('heroicon-o-trash')
                    ->tooltip('Remove this person')
                    ->modalHeading('Remove Insured Person')
                    ->modalDescription('Are you sure you want to remove this person from the insurance?')
                    ->modalSubmitActionLabel('Yes, Remove')
                    ->modalCancelActionLabel('Cancel'),
                
                // View details (if needed)
                Tables\Actions\ViewAction::make()
                    ->icon('heroicon-o-eye')
                    ->tooltip('View details'),
            ])
            ->bulkActions([
                // Bulk delete
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make()
                        ->label('Delete Selected')
                        ->requiresConfirmation()
                        ->modalHeading('Delete Selected Persons')
                        ->modalDescription('Are you sure you want to delete the selected persons? This action cannot be undone.')
                        ->modalSubmitActionLabel('Yes, Delete')
                        ->modalCancelActionLabel('Cancel'),
                    
                    // Bulk update relationship
                    Tables\Actions\BulkAction::make('updateRelationship')
                        ->label('Update Relationship')
                        ->icon('heroicon-o-users')
                        ->form([
                            Forms\Components\Select::make('relationship')
                                ->label('New Relationship')
                                ->options([
                                    'self' => 'Primary',
                                    'spouse' => 'Spouse',
                                    'child' => 'Child',
                                    'parent' => 'Parent',
                                    'sibling' => 'Sibling',
                                    'other' => 'Other',
                                ])
                                ->required(),
                        ])
                        ->action(function ($records, array $data): void {
                            foreach ($records as $record) {
                                $record->relationship = $data['relationship'];
                                $record->save();
                            }
                        })
                        ->deselectRecordsAfterCompletion(),
                    
                    // Bulk mark as primary
                    Tables\Actions\BulkAction::make('markAsPrimary')
                        ->label('Mark as Primary')
                        ->icon('heroicon-o-star')
                        ->action(function ($records): void {
                            // First, unmark all as primary
                            $this->getRelationship()->update(['is_primary' => false]);
                            
                            // Then mark selected as primary
                            foreach ($records as $record) {
                                $record->is_primary = true;
                                $record->save();
                            }
                        })
                        ->requiresConfirmation()
                        ->deselectRecordsAfterCompletion(),
                ]),
            ])
            ->emptyStateActions([
                // Action when no people exist
                Tables\Actions\CreateAction::make()
                    ->label('Add First Person')
                    ->icon('heroicon-o-plus'),
            ])
            ->emptyStateDescription('No insured persons added yet.')
            ->defaultSort('is_primary', 'desc') // Show primary first
            ->reorderable('born_at') // Allow reordering by age
            ->deferLoading() // Improve performance
            ->striped(); // Zebra striping for readability
    }

    /**
     * Get the table query with eager loading
     */
    public function tableQuery(): Builder
    {
        return parent::tableQuery()
            ->with(['price', 'deductible']) // Eager load relationships
            ->orderBy('is_primary', 'desc')
            ->orderBy('born_at', 'asc');
    }

    /**
     * Get the empty state icon
     */
    protected function getEmptyStateIcon(): string
    {
        return 'heroicon-o-user-group';
    }

    /**
     * Get the empty state heading
     */
    protected function getEmptyStateHeading(): string
    {
        return 'No Insured Persons';
    }

    /**
     * Get the empty state description
     */
    protected function getEmptyStateDescription(): string
    {
        return 'Add insured persons to this inquiry.';
    }
}