<?php

namespace App\Filament\Pages;

use App\Models\Setting;
use App\Models\ZEmail;
use Artisan;
use Ddeboer\Imap\Server;
use Filament\Actions\Action;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Pages\Page;

class Settings extends Page implements HasForms
{
    use InteractsWithForms;

    public ?array $data = [];

    protected static ?string $navigationIcon = 'heroicon-o-cog-6-tooth';

    protected static string $view = 'filament.pages.settings';

    protected static ?string $navigationGroup = 'Web Master';

    public function mount(): void
    {
        $user = auth()->user();
        $auth_email = $user->email;
        $setting = Setting::where('app_admin', $auth_email)->first();

        if ($setting) {
            $imapSettings = $setting->imap_settings ?? [];
            $configurationSettings = $setting->configuration_settings ?? [];
            $adsSettings = $setting->ads_settings ?? [];

            $this->applyDefaults($imapSettings, [
                'protocol' => 'imap',
                'default_account' => 'default',
                'premium_protocol' => 'imap',
                'premium_default_account' => 'default',
            ]);

            $this->applyDefaults($configurationSettings, [
                'cron_password' => fn() => $this->generateRandomString(20),
                'date_format' => 'd M Y h:i A',
                'after_last_email_delete' => 'redirect_to_homepage',
            ]);

            $transformMap = [
                'domains' => 'domain',
                'gmailUsernames' => 'gmailUsername',
                'premium_domains' => 'premium_domain',
                'premium_gmailUsernames' => 'premium_gmailUsername',
                'forbidden_ids' => 'forbidden_id',
                'blocked_domains' => 'blocked_domain',
            ];

            foreach ($transformMap as $key => $subKey) {
                if (isset($configurationSettings[$key])) {
                    $configurationSettings[$key] = array_map(function ($value) use ($subKey) {
                        return [$subKey => $value];
                    }, $configurationSettings[$key]);
                }
            }
            $this->form->fill([
                'app_name' => $setting->app_name,
                'app_version' => $setting->app_version,
                'app_base_url' => $setting->app_base_url,
                'app_admin' => $setting->app_admin,
                'app_contact' => $setting->app_contact,
                'app_title' => $setting->app_title,
                'app_description' => $setting->app_description,
                'app_keyword' => $setting->app_keyword,
                'app_meta' => $setting->app_meta,
                'app_social' => $setting->app_social,
                'app_header' => $setting->app_header,
                'app_footer' => $setting->app_footer,
                'imap_settings' => $imapSettings,
                'configuration_settings' => $configurationSettings,
                'ads_settings' => $adsSettings,
            ]);


        } else {
            $this->form->fill([
                'app_admin' => $auth_email,
                'app_social' => [
                    null => null,
                ],
            ]);
        }
    }

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Section::make('Website Information')
                    ->description('Change Basic Website Information')
                    ->collapsible()
                    ->schema([
                        TextInput::make('app_name')->label('Website Name')->required(),
                        TextInput::make('app_version')->label('Website Version')->required(),
                        TextInput::make('app_base_url')->label('Base URL')->required(),
                        TextInput::make('app_admin')->label('Website Admin')->email()->required(),
                        TextInput::make('app_contact')->label('Contact Email')->email()->required(),
                    ]),
                Section::make('Custom Codes')
                    ->description('Add custom codes to header and footer')
                    ->collapsed()
                    ->columns(2)
                    ->schema([
                        Textarea::make('app_header')->label('Custom Header')->rows(6)->columnSpan(1),
                        Textarea::make('app_footer')->label('Custom Footer')->rows(6)->columnSpan(1),
                    ]),
                Section::make('Meta Information')
                    ->description('Change Website Meta Information')
                    ->collapsed()
                    ->schema([
                        TextInput::make('app_title')->label('Title')->required(),
                        Textarea::make('app_description')->label('Description')->rows(3),
                        TextInput::make('app_keyword')->label('Keyword'),
                        KeyValue::make('app_meta')
                            ->label('Meta (Optional)')
                            ->keyPlaceholder('Name')
                            ->valuePlaceholder('Content'),
                    ]),
                Section::make('Social Links')
                    ->description('Enter your social links')
                    ->collapsed()
                    ->schema([


                        Repeater::make('app_social')
                            ->statePath('app_social')
                            ->schema([
                                TextInput::make('icon')->label('Icon')->required()->maxLength(100),
                                TextInput::make('url')->label('URL')->url()->required()->maxLength(255),
                            ])

                    ]),

                Section::make('Public Mailbox Imap')
                    ->description('Enter your imap server')
                    ->collapsed()
                    ->schema([
                        TextInput::make('imap_settings.host')->label('Hostname')->required(),
                        TextInput::make('imap_settings.port')->label('Port')->required(),
                        Select::make('imap_settings.encryption')->options([
                            'none' => 'None',
                            'ssl' => 'SSL',
                            'tls' => 'TLS'
                        ]),
                        Checkbox::make('imap_settings.validate_cert')->label('Validate Encryption Certificate')->default(false),
                        TextInput::make('imap_settings.username')->label('Username')->required(),
                        TextInput::make('imap_settings.password')->label('Password')->required(),
                        TextInput::make('imap_settings.default_account')->label('Default Account')->placeholder('default'),
                        TextInput::make('imap_settings.protocol')->label('Protocol')->placeholder('imap'),
                        Checkbox::make('imap_settings.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('imap_settings.premium_host')->label('Hostname')->required(),
                        TextInput::make('imap_settings.premium_port')->label('Port')->required(),
                        Select::make('imap_settings.premium_encryption')->options([
                            'none' => 'None',
                            'ssl' => 'SSL',
                            'tls' => 'TLS'
                        ]),
                        Checkbox::make('imap_settings.premium_validate_cert')->label('Validate Encryption Certificate')->default(false),
                        TextInput::make('imap_settings.premium_username')->label('Username')->required(),
                        TextInput::make('imap_settings.premium_password')->label('Password')->required(),
                        TextInput::make('imap_settings.premium_default_account')->label('Default Account')->placeholder('default'),
                        TextInput::make('imap_settings.premium_protocol')->label('Protocol')->placeholder('imap'),
                        Checkbox::make('imap_settings.premium_cc_check')->label('Check CC Field')->default(false)->helperText('If enabled, we will check the CC field as well while fetching mails.'),
                    ]),

                Section::make('Configuration')
                    ->description('Enter your configuration')
                    ->collapsed()
                    ->schema([
                        Section::make('General Configuration')
                            ->columns(2)
                            ->schema([
                            Checkbox::make('configuration_settings.enable_masking_external_link')
                                ->label('Enable URL Masking of External URL')
                                ->default(false)
                                ->columnSpan(1)
                                ->helperText('If you enable this, then we will use href.li to remove your site footprint being passed-on to external link.'),
                            Checkbox::make('configuration_settings.disable_mailbox_slug')
                                ->label('Disable Mailbox Slug')
                                ->default(false)
                                ->columnSpan(1)
                                ->helperText('If you enable this, then we will disable mailbox slug.'),
                            Checkbox::make('configuration_settings.enable_create_from_url')
                                ->label('Enable Mail ID Creation from URL')
                                ->default(true)
                                ->columnSpan(1)
                                ->helperText('If you enable this, then users will be able to create email ID from URL.'),
                            Checkbox::make('configuration_settings.enable_ad_block_detector')
                                ->label('Enable Ad Block Detector')
                                ->default(true)
                                ->columnSpan(1)
                                ->helperText('If you enable this, then we block all the users from using when that have Ad Blocker enabled.'),
                            KeyValue::make('configuration_settings.font_family')
                                ->label('Font Family')
                                ->columnSpan(2)
                                ->helperText('Use Google Fonts with exact name.')
                        ]),

                        Select::make('configuration_settings.default_language')->options([
                           'ar' => 'Arabic',
                           'de' => 'German',
                           'en' => 'English',
                           'fr' => 'French',
                           'hi' => 'Hindi',
                           'pl' => 'Polish',
                           'ru' => 'Russian',
                           'es' => 'Spanish',
                           'vi' => 'Viet',
                           'tr' => 'Turkish',
                           'no' => 'Norwegian',
                           'id' => 'Indonesian',
                        ]),

                        Section::make('Domains & Gmail Usernames')
                            ->collapsed()
                            ->columns(2)
                            ->schema([
                            Repeater::make('configuration_settings.domains')
                                ->statePath('configuration_settings.domains')
                                ->columnSpan(1)
                                ->schema([
                                    TextInput::make('domain')->label('Domain')->required()->maxLength(30),
                                ]),
                            Repeater::make('configuration_settings.gmailUsernames')
                                ->statePath('configuration_settings.gmailUsernames')
                                ->columnSpan(1)
                                ->schema([
                                    TextInput::make('gmailUsername')->label('Gmail Username')->required()->maxLength(30),
                                ]),
                        ]),

                        Section::make('Premium Domains & Gmail Usernames')
                            ->collapsed()
                            ->columns(2)
                            ->schema([
                                Repeater::make('configuration_settings.premium_domains')
                                    ->statePath('configuration_settings.premium_domains')
                                    ->columnSpan(1)
                                    ->schema([
                                        TextInput::make('premium_domain')->label('Premium Domain')->required()->maxLength(30),
                                    ]),
                                Repeater::make('configuration_settings.premium_gmailUsernames')
                                    ->statePath('configuration_settings.premium_gmailUsernames')
                                    ->columnSpan(1)
                                    ->schema([
                                        TextInput::make('premium_gmailUsername')->label('Premium Gmail Username')->required()->maxLength(30),
                                    ]),
                            ]),

                        Section::make('Mailbox Configuration')
                            ->collapsed()
                            ->schema([
                                Checkbox::make('configuration_settings.add_mail_in_title')->label('Add Mail In Title')->default(false)->required()->helperText('If you enable this, then we will automatically add the created temp mail to the page title.'),
                                Checkbox::make('configuration_settings.disable_used_email')->label('Disable Used Email')->default(false)->required()->helperText('If you enable this, same email address cannot be created by user from different IP for one week.'),
                                TextInput::make('configuration_settings.fetch_seconds')->label('Fetch Seconds')->numeric()->required(),
                                TextInput::make('configuration_settings.email_limit')->label('Email Limit')->numeric()->required()->helperText('Limit on number of email ids that can be created per IP address in 24 hours. Recommended - 5.'),
                                TextInput::make('configuration_settings.fetch_messages_limit')->label('Fetch Messages Limit')->numeric()->required()->helperText('Limit of messages retrieved at a time. Keep it to as low as possible. Default - 15.'),
                                TextInput::make('configuration_settings.cron_password')->label('Cron Password')->required(),
                                TextInput::make('configuration_settings.date_format')->label('Date Format')->placeholder('d M Y h:i A')->required(),
                                Section::make('Custom Username Lengths')
                                    ->description('Username length for custom input')
                                    ->columns(2)
                                    ->schema([
                                        TextInput::make('configuration_settings.custom_username_length_min')->numeric()->minValue(3)->label('Custom Username Min Length')->required(),
                                        TextInput::make('configuration_settings.custom_username_length_max')->numeric()->minValue(3)->label('Custom Username Max Length')->required(),
                                    ]),
                                Section::make('Random Username Lengths')
                                    ->description('Username length for random username')
                                    ->columns(2)
                                    ->schema([
                                        TextInput::make('configuration_settings.random_username_length_min')->numeric()->minValue(0)->label('Random Username Min Length')->required(),
                                        TextInput::make('configuration_settings.random_username_length_max')->numeric()->minValue(0)->label('Random Username Max Length')->required(),
                                    ]),
                                Select::make('configuration_settings.after_last_email_delete')->options([
                                    'redirect_to_homepage' => 'Redirect to homepage',
                                    'create_new_email' => 'Create new Email',
                                ])->required(),
                            ]),
                        Section::make('Forbidden Username & Blocked Domains')
                            ->columns(2)
                            ->collapsed()
                            ->schema([
                                Repeater::make('configuration_settings.forbidden_ids')
                                    ->statePath('configuration_settings.forbidden_ids')
                                    ->columnSpan(1)
                                    ->schema([
                                        TextInput::make('forbidden_id')->label('Forbidden IDs')->required()->maxLength(30),
                                    ]),
                                Repeater::make('configuration_settings.blocked_domains')
                                    ->statePath('configuration_settings.blocked_domains')
                                    ->columnSpan(1)
                                    ->schema([
                                        TextInput::make('blocked_domain')->label('Blocked Domain')->required()->maxLength(30),
                                    ]),
                            ]),

                    ]),

                Section::make('Ad Spaces')
                    ->description('You can setup your Ad Codes here for various Ad Spaces')
                    ->collapsed()
                    ->schema([
                        Textarea::make('ads_settings.one')->label('Ad Space 1')->rows(4),
                        Textarea::make('ads_settings.two')->label('Ad Space 2')->rows(4),
                        Textarea::make('ads_settings.three')->label('Ad Space 3')->rows(4),
                        Textarea::make('ads_settings.four')->label('Ad Space 4')->rows(4),
                        Textarea::make('ads_settings.five')->label('Ad Space 5')->rows(4),
                    ]),

            ])
            ->statePath('data');
    }

    protected function getFormActions(): array
    {
        return [
            Action::make('save')
                ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
                ->submit('save'),
            Action::make('flushCache')
                ->label(__('Flush Cache'))
                ->color('danger')
                ->icon('heroicon-m-no-symbol')
                ->action('flushCache')
                ->requiresConfirmation(),
        ];
    }

    public function flushCache(): void
    {
        try {
            Artisan::call('cache:clear');
            Notification::make()
                ->title('Cache flushed successfully')
                ->success()
                ->send();
        } catch (\Exception $e) {
            Notification::make()
                ->title('Error : '.$e->getMessage())
                ->danger()
                ->send();
        }
    }

    public function save(): void
    {
        try {

            $data = $this->form->getState();
            if (!$this->testIMAP($data['imap_settings'])) {
                return;
            } else {
                Notification::make()
                    ->title('IMAP Connection Successful')
                    ->success()
                    ->send();
            }
            foreach ([
                'protocol' => 'imap',
                'default_account' => 'default',
                 'premium_protocol' => 'imap',
                 'premium_default_account' => 'default',
                ] as $key => $default) {
                $data['imap_settings'][$key] ??= $default;
            }

            $pluckMap = [
                'domains' => 'domain',
                'premium_domains' => 'premium_domain',
                'premium_gmailUsernames' => 'premium_gmailUsername',
                'gmailUsernames' => 'gmailUsername',
                'forbidden_ids' => 'forbidden_id',
                'blocked_domains' => 'blocked_domain'
            ];

            foreach ($pluckMap as $key => $subKey) {
                if (isset($data['configuration_settings'][$key])) {
                    $data['configuration_settings'][$key] = collect($data['configuration_settings'][$key])
                        ->pluck($subKey)
                        ->toArray();
                }
            }

            $setting = Setting::where('id', 1)->first();

            $user = auth()->user();
            $auth_email = $user->email;

            if ($setting) {
                $app_admin = $setting->app_admin;
                if ($app_admin == $auth_email) {
                    $update_res = $setting->update($data);
                    if($update_res) {
                        Notification::make()
                            ->title('Saved successfully')
                            ->success()
                            ->send();
                    }
                }  else {
                    Notification::make()
                        ->title('Please Login With Administrator Credentials')
                        ->danger()
                        ->send();
                }
            } else {
                $data = [
                    'id' => 1,
                    'app_name' => $data['app_name'],
                    'app_version' => $data['app_version'],
                    'app_base_url' => $data['app_base_url'],
                    'app_admin' => $auth_email,
                    'app_contact' => $data['app_contact'],
                    'app_title' => $data['app_title'],
                    'app_description' => $data['app_description'],
                    'app_keyword' => $data['app_keyword'],
                    'app_social' => $data['app_social'],
                    'imap_settings' => $data['imap_settings'],
                    'configuration_settings' => $data['configuration_settings'],
                    'ads_settings' => $data['ads_settings'],
                ];
                $create_res = Setting::create(array_merge($data));

                if($create_res) {
                    Notification::make()
                        ->title('Saved successfully')
                        ->success()
                        ->send();
                }
            }
        } catch (\Exception $exception) {
            Notification::make()
                ->title('Something went wrong '.$exception->getMessage())
                ->danger()
                ->send();
        }
    }

    private function generateRandomString($length = 10): string
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }

    private function applyDefaults(array &$target, array $defaults): void {
        foreach ($defaults as $key => $value) {
            $target[$key] ??= is_callable($value) ? $value() : $value;
        }
    }

    private function testIMAP($imap): bool
    {
        try {
            ZEmail::connectMailBox($imap);
            return true;
        } catch (\Exception $exception) {
            Notification::make()
                ->title('Imap Error : '.$exception->getMessage())
                ->danger()
                ->send();
            return false;
        }
    }
}
