<?php

namespace App\Filament\Pages;

use App\Models\ZEmail;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Inerba\DbConfig\AbstractPageSettings;
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;

class ImapSettings extends AbstractPageSettings
{
    /**
     * @var array<string, mixed> | null
     */
    public ?array $data = [];

    protected static ?string $title = 'Imap Settings';

    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedEnvelope; // Uncomment if you want to set a custom navigation icon

    // protected ?string $subheading = ''; // Uncomment if you want to set a custom subheading

    // protected static ?string $slug = 'imap-settings'; // Uncomment if you want to set a custom slug

    protected string $view = 'filament.pages.imap-settings';

    protected function settingName(): string
    {
        return 'imap';
    }

    /**
     * Provide default values.
     *
     * @return array<string, mixed>
     */
    public function getDefaultData(): array
    {
        return [
            'public.default_account' => 'default',
            'public.protocol' => 'imap',
            'premium.default_email' => 'default',
            'premium.protocol' => 'imap',
        ];
    }

    public function getHeaderActions(): array
    {
        return [
            Action::make('test_connection')
                ->label('Test Connection')
                ->color('gray')
                ->icon('heroicon-o-paper-airplane')
                ->action(fn () => $this->testIMAPConnection()),

            ...parent::getHeaderActions(),
        ];
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make('Public Mailbox Imap')
                    ->description('Enter your imap server')
                    ->collapsible()
                    ->schema([
                        TextInput::make('public.host')->label('Hostname')->required(),
                        TextInput::make('public.port')->label('Port')->required(),
                        Select::make('public.encryption')->options([
                            'none' => 'None',
                            'ssl' => 'SSL',
                            'tls' => 'TLS',
                        ]),
                        Checkbox::make('public.validate_cert')->label('Validate Encryption Certificate')->default(false),
                        TextInput::make('public.username')->label('Username')->required(),
                        TextInput::make('public.password')->label('Password')->required(),
                        TextInput::make('public.default_account')->label('Default Account')->placeholder('default'),
                        TextInput::make('public.protocol')->label('Protocol')->placeholder('imap'),
                        Checkbox::make('public.cc_check')->label('Check CC Field')->default(false)->helperText('If enabled, we will check the CC field as well while fetching mails.'),
                    ]),

                Section::make('Premium Mailbox Imap')
                    ->description('Enter your imap server')
                    ->collapsed()
                    ->schema([
                        TextInput::make('premium.host')->label('Hostname')->required(),
                        TextInput::make('premium.port')->label('Port')->required(),
                        Select::make('premium.encryption')->options([
                            'none' => 'None',
                            'ssl' => 'SSL',
                            'tls' => 'TLS',
                        ]),
                        Checkbox::make('premium.validate_cert')->label('Validate Encryption Certificate')->default(false),
                        TextInput::make('premium.username')->label('Username')->required(),
                        TextInput::make('premium.password')->label('Password')->required(),
                        TextInput::make('premium.default_account')->label('Default Account')->placeholder('default'),
                        TextInput::make('premium.protocol')->label('Protocol')->placeholder('imap'),
                        Checkbox::make('premium.cc_check')->label('Check CC Field')->default(false)->helperText('If enabled, we will check the CC field as well while fetching mails.'),
                    ]),
            ])
            ->statePath('data');
    }

    private function testIMAPConnection(): void
    {
        $settings = $this->data;
        $results = [];
        $hasSuccess = false;
        $hasFailure = false;

        // Define IMAP configuration sections - easy to extend
        $imapSections = ['public', 'premium'];

        foreach ($imapSections as $sectionName) {
            $sectionConfig = $this->getImapSectionConfig($settings, $sectionName);
            $result = $this->testSingleImapConnection($sectionName, $sectionConfig);
            $results[] = $result;

            if ($result['success']) {
                $hasSuccess = true;
            } else {
                $hasFailure = true;
            }
        }

        // Send appropriate notification based on results
        $this->sendImapTestNotification($results, $hasSuccess, $hasFailure);
    }

    /**
     * Get IMAP section configuration for a specific parent key.
     */
    private function getImapSectionConfig(array $settings, string $sectionName): array
    {
        $config = [];
        $fields = ['host', 'port', 'username', 'password', 'encryption', 'validate_cert', 'protocol'];

        foreach ($fields as $field) {
            $key = $sectionName . '.' . $field;

            // Try different data structure approaches
            $value = null;

            // 1. Direct key access (flat structure with dots)
            if (isset($settings[$key])) {
                $value = $settings[$key];
            }
            // 2. Nested structure access
            elseif (isset($settings[$sectionName][$field])) {
                $value = $settings[$sectionName][$field];
            }
            // 3. Alternative nested structure
            elseif (isset($settings[$sectionName]) && is_array($settings[$sectionName])) {
                $nested = $settings[$sectionName];
                if (isset($nested[$field])) {
                    $value = $nested[$field];
                }
            }

            $config[$field] = $value;
        }

        return $config;
    }

    /**
     * Test a single IMAP connection configuration.
     */
    private function testSingleImapConnection(string $sectionName, array $config): array
    {
        $requiredFields = ['host', 'port', 'username', 'password'];

        // Check for missing required fields
        $missingFields = collect($requiredFields)->filter(fn ($field): bool => empty($config[$field]));

        if ($missingFields->isNotEmpty()) {
            return [
                'section' => ucfirst($sectionName),
                'success' => false,
                'message' => "Missing required fields: " . $missingFields->join(', '),
                'details' => null
            ];
        }

        try {
            // First check if IMAP extension is available
            if (! function_exists('imap_open')) {
                return [
                    'section' => ucfirst($sectionName),
                    'success' => false,
                    'message' => 'IMAP extension is not loaded in your web server. Please check your Herd PHP configuration or restart your server.',
                    'details' => null
                ];
            }

            // Build IMAP configuration array in the format ZEmail expects
            $imapConfig = [
                'host' => $config['host'],
                'port' => (int) $config['port'],
                'username' => $config['username'],
                'password' => $config['password'],
                'encryption' => $config['encryption'] ?? 'none',
                'validate_cert' => $config['validate_cert'] ?? false,
                'protocol' => $config['protocol'] ?? 'imap'
            ];

            // Test connection using the existing ZEmail::connectMailBox method
            ZEmail::connectMailBox($imapConfig);

            return [
                'section' => ucfirst($sectionName),
                'success' => true,
                'message' => 'Connection successful',
                'details' => [
                    'host' => $config['host'],
                    'port' => $config['port'],
                    'encryption' => $config['encryption'] ?? 'none',
                    'protocol' => $config['protocol'] ?? 'imap'
                ]
            ];

        } catch (\Exception $e) {
            $errorMessage = $e->getMessage();

            // Provide more helpful error messages
            if (str_contains($errorMessage, 'IMAP extension must be enabled')) {
                $errorMessage = 'IMAP extension is not properly loaded in the web server. Try restarting Herd or check your PHP configuration.';
            }

            return [
                'section' => ucfirst($sectionName),
                'success' => false,
                'message' => $errorMessage,
                'details' => [
                    'host' => $config['host'] ?? null,
                    'port' => $config['port'] ?? null,
                    'encryption' => $config['encryption'] ?? 'none',
                    'protocol' => $config['protocol'] ?? 'imap'
                ]
            ];
        }
    }


    /**
     * Send appropriate notification based on test results.
     */
    private function sendImapTestNotification(array $results, bool $hasSuccess, bool $hasFailure): void
    {
        $totalTests = count($results);
        $successCount = count(array_filter($results, fn ($r): bool => $r['success']));

        if ($hasSuccess && ! $hasFailure) {
            // All successful
            Notification::make()
                ->title("All IMAP connections successful! ({$successCount}/{$totalTests})")
                ->success()
                ->body($this->formatSuccessNotification($results))
                ->send();
        } elseif (! $hasSuccess && $hasFailure) {
            // All failed
            Notification::make()
                ->title("All IMAP connections failed (0/{$totalTests})")
                ->danger()
                ->body($this->formatFailureNotification($results))
                ->send();
        } else {
            // Mixed results
            Notification::make()
                ->title("IMAP connection test completed ({$successCount}/{$totalTests} successful)")
                ->warning()
                ->body($this->formatMixedNotification($results))
                ->send();
        }
    }

    /**
     * Format success notification details.
     */
    private function formatSuccessNotification(array $results): string
    {
        $details = [];
        foreach ($results as $result) {
            if ($result['success'] && isset($result['details']['messages'])) {
                $details[] = "{$result['section']}: {$result['details']['messages']} messages";
            }
        }
        return implode(' | ', $details);
    }

    /**
     * Format failure notification details.
     */
    private function formatFailureNotification(array $results): string
    {
        $details = [];
        foreach ($results as $result) {
            $details[] = "{$result['section']}: {$result['message']}";
        }
        return implode(' | ', $details);
    }

    /**
     * Format mixed results notification details.
     */
    private function formatMixedNotification(array $results): string
    {
        $details = [];
        foreach ($results as $result) {
            $status = $result['success'] ? '✅' : '❌';
            $details[] = "{$status} {$result['section']}";
        }
        return implode(' | ', $details);
    }
}
