<?php

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

use App\Filament\Admin\Resources\InquiryResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Support\Carbon;

/**
 * Edit Inquiry Page
 * 
 * This page handles the editing of existing insurance inquiries in the admin panel.
 * It provides a form to update inquiry details and allows administrators
 * to modify all fields except for auto-generated ones like reference number.
 */
class EditInquiry extends EditRecord
{
    /**
     * The resource class associated with this page
     */
    protected static string $resource = InquiryResource::class;

    /**
     * Header actions available on the edit page
     * 
     * These actions provide quick access to common operations
     * while editing an inquiry.
     */
    protected function getHeaderActions(): array
    {
        return [
            // Action: View the inquiry (read-only mode)
            Actions\ViewAction::make()
                ->label('View')
                ->icon('heroicon-o-eye')
                ->color('gray')
                ->tooltip('View this inquiry in read-only mode'),
            
            // Action: Delete the inquiry
            Actions\DeleteAction::make()
                ->label('Delete')
                ->icon('heroicon-o-trash')
                ->color('danger')
                ->tooltip('Delete this inquiry permanently')
                ->modalHeading('Delete Inquiry')
                ->modalDescription('Are you sure you want to delete this inquiry? This action cannot be undone.')
                ->modalSubmitActionLabel('Yes, Delete')
                ->modalCancelActionLabel('Cancel'),
            
            // Action: Back to list
            Actions\Action::make('backToList')
                ->label('Back to List')
                ->icon('heroicon-o-arrow-left')
                ->color('secondary')
                ->url(static::getResource()::getUrl('index'))
                ->outlined(),
        ];
    }

    /**
     * Get the form actions for the edit page
     * 
     * These actions appear at the bottom of the form.
     */
    protected function getFormActions(): array
    {
        return [
            // Save changes button
            Actions\Action::make('save')
                ->label('Save Changes')
                ->icon('heroicon-o-check')
                ->color('primary')
                ->action('save'),
            
            // Save and continue editing button
            Actions\Action::make('saveAndContinueEditing')
                ->label('Save & Continue Editing')
                ->icon('heroicon-o-arrow-path')
                ->color('success')
                ->action('saveAndContinueEditing')
                ->outlined(),
            
            // Cancel button
            Actions\Action::make('cancel')
                ->label('Cancel')
                ->icon('heroicon-o-x-mark')
                ->color('gray')
                ->url(fn () => static::getResource()::getUrl('view', ['record' => $this->record]))
                ->outlined(),
        ];
    }

    /**
     * Mutate form data before filling the form
     * 
     * This method is called before the form is filled with existing data.
     * We can use it to format dates, decode encrypted fields, or
     * prepare data for display.
     */
    protected function mutateFormDataBeforeFill(array $data): array
    {
        // Format card expiration from YYMM to MM/YY for display
        if (!empty($data['card_expiration']) && strlen($data['card_expiration']) === 4) {
            $year = substr($data['card_expiration'], 0, 2);
            $month = substr($data['card_expiration'], 2, 2);
            $data['card_expiration'] = $month . '/' . $year;
        }
        
        // Format dates for better display in form
        $dateFields = ['started_at', 'ended_at', 'arrived_at', 'beneficiary_born_at'];
        foreach ($dateFields as $field) {
            if (!empty($data[$field])) {
                try {
                    $data[$field] = Carbon::parse($data[$field])->format('Y-m-d');
                } catch (\Exception $e) {
                    // Keep original value if parsing fails
                }
            }
        }
        
        // Format datetime fields
        $datetimeFields = ['inquired_at', 'reviewed_at', 'local_submitted_at'];
        foreach ($datetimeFields as $field) {
            if (!empty($data[$field])) {
                try {
                    $data[$field] = Carbon::parse($data[$field])->format('Y-m-d H:i:s');
                } catch (\Exception $e) {
                    // Keep original value if parsing fails
                }
            }
        }
        
        // Ensure number_of_people is set
        if (empty($data['number_of_people'])) {
            $data['number_of_people'] = 1;
        }
        
        // Ensure total_premium is formatted as decimal
        if (isset($data['total_premium'])) {
            $data['total_premium'] = (float) $data['total_premium'];
        }
        
        return $data;
    }

    /**
     * Mutate form data before saving
     * 
     * This method is called before the record is updated.
     * We can use it to format data for storage, encrypt sensitive fields,
     * or update timestamps.
     */
    protected function mutateFormDataBeforeSave(array $data): array
    {
        // Format card expiration from MM/YY to YYMM for storage
        if (!empty($data['card_expiration'])) {
            $clean = preg_replace('/[^0-9]/', '', $data['card_expiration']);
            if (strlen($clean) === 4) {
                $month = substr($clean, 0, 2);
                $year = substr($clean, 2, 2);
                $data['card_expiration'] = $year . $month;
            }
        }
        
        // Update reviewed_at timestamp if status is being changed to approved/rejected
        $currentStatus = $this->record->status;
        $newStatus = $data['status'] ?? $currentStatus;
        
        if (($newStatus === 'approved' || $newStatus === 'rejected') && 
            ($currentStatus !== 'approved' && $currentStatus !== 'rejected')) {
            $data['reviewed_at'] = now();
        }
        
        // Ensure dates are properly formatted for storage
        $dateFields = ['started_at', 'ended_at', 'arrived_at', 'beneficiary_born_at'];
        foreach ($dateFields as $field) {
            if (!empty($data[$field])) {
                try {
                    $data[$field] = Carbon::parse($data[$field])->format('Y-m-d H:i:s');
                } catch (\Exception $e) {
                    // If parsing fails, use the original value
                }
            }
        }
        
        // Ensure total_premium is stored as decimal
        if (isset($data['total_premium'])) {
            $data['total_premium'] = (float) $data['total_premium'];
        }
        
        // Update local_submitted_at if not set
        if (empty($data['local_submitted_at'])) {
            $data['local_submitted_at'] = now();
        }
        
        return $data;
    }

    /**
     * Handle record update with additional logic
     * 
     * This method is called when the form is submitted and validated.
     * We can add additional logic here, such as updating related records
     * or triggering events.
     */
    protected function handleRecordUpdate($record, array $data): void
    {
        // Update the main record
        parent::handleRecordUpdate($record, $data);
        
        // Additional logic after update can go here
        // For example, recalculate total premium if people changed
        // Or send notification emails
        
        // Recalculate total premium if number of people changed
        if (isset($data['number_of_people']) && $record->number_of_people != $data['number_of_people']) {
            // Trigger premium recalculation (method to be implemented in model)
            $record->calculateTotalPremium();
        }
    }

    /**
     * Get the redirect URL after update
     * 
     * Determines where the user is redirected after successfully updating an inquiry.
     * Defaults to the view page, but can be changed based on which button was clicked.
     */
    protected function getRedirectUrl(): string
    {
        // If "Save & Continue Editing" was clicked, redirect back to edit page
        if ($this->getSavedNotification() === 'saveAndContinueEditing') {
            return static::getResource()::getUrl('edit', ['record' => $this->record]);
        }
        
        // Otherwise, redirect to the view page
        return static::getResource()::getUrl('view', ['record' => $this->record]);
    }

    /**
     * Get the update notification message
     */
    protected function getSavedNotificationMessage(): ?string
    {
        $reference = $this->record->reference_number ?? 'inquiry';
        return "Insurance inquiry #{$reference} has been updated successfully.";
    }

    /**
     * Get the update notification title
     */
    protected function getSavedNotificationTitle(): ?string
    {
        return 'Inquiry Updated';
    }

    /**
     * Get the page heading
     */
    public function getHeading(): string
    {
        $reference = $this->record->reference_number ?? 'N/A';
        return "Edit Inquiry #{$reference}";
    }

    /**
     * Get the page subheading
     */
    public function getSubheading(): ?string
    {
        $type = $this->record->is_entry ? 'Entry to Canada' : 'Exit from Canada';
        $status = ucfirst(str_replace('_', ' ', $this->record->status));
        return "{$type} Insurance • Current Status: {$status}";
    }

    /**
     * Get the breadcrumbs for the page
     */
    public function getBreadcrumbs(): array
    {
        return [
            route('filament.admin.pages.dashboard') => 'Dashboard',
            InquiryResource::getUrl('index') => 'Inquiries',
            InquiryResource::getUrl('view', ['record' => $this->record]) => 'View Inquiry',
            '' => 'Edit',
        ];
    }

    /**
     * Initialize form with current record data
     * 
     * Override to set up any additional form state.
     */
    protected function initializeForm(): void
    {
        parent::initializeForm();
        
        // Additional form initialization can go here
        // For example, set up listeners for field changes
    }

    /**
     * Get the form schema for the edit page
     * 
     * We can override this to provide a different form layout for editing
     * compared to creating or viewing.
     */
    protected function getFormSchema(): array
    {
        // Use the same form schema as the resource
        // Some fields might be disabled or read-only in edit mode
        $schema = parent::getFormSchema();
        
        // Make reference_number read-only in edit mode
        foreach ($schema as $component) {
            if ($component instanceof \Filament\Forms\Components\Section) {
                $component->schema(function ($components) {
                    foreach ($components as $component) {
                        if ($component instanceof \Filament\Forms\Components\TextInput && 
                            $component->getName() === 'reference_number') {
                            $component->disabled();
                        }
                    }
                    return $components;
                });
            }
        }
        
        return $schema;
    }

    /**
     * Get the saved notification type
     * 
     * Used to determine which action was performed.
     */
    protected function getSavedNotification(): string
    {
        return $this->savedNotification ?? 'save';
    }

    /**
     * Set the saved notification type
     * 
     * Called by form actions to indicate which button was clicked.
     */
    public function setSavedNotification(string $type): void
    {
        $this->savedNotification = $type;
    }

    /**
     * Action: Save the record
     */
    public function save(): void
    {
        $this->setSavedNotification('save');
        parent::save();
    }

    /**
     * Action: Save and continue editing
     */
    public function saveAndContinueEditing(): void
    {
        $this->setSavedNotification('saveAndContinueEditing');
        parent::save();
    }
}