<?php

namespace App\Filament\Pages;

use App\Models\Setting;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Mail;

class Configurations extends Page implements HasForms
{
    use InteractsWithForms;

    protected string $view = 'filament.pages.configurations';

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-cog-6-tooth';

    protected static ?string $navigationLabel = 'Configurations';

    protected static string|\UnitEnum|null $navigationGroup = 'Settings';

    protected static ?int $navigationSort = 90;

    public ?array $data = [];

    /** Fields whose values are stored encrypted. */
    private const SECRETS = [
        'smtp_password', 'mpesa_consumer_secret', 'mpesa_passkey',
        'paystack_secret_key', 'flutterwave_secret_key', 'flutterwave_encryption_key',
    ];

    /** All keys managed by this page. */
    private const KEYS = [
        'mail_mailer', 'mail_from_address', 'mail_from_name',
        'smtp_host', 'smtp_port', 'smtp_username', 'smtp_password', 'smtp_encryption',
        'mpesa_enabled', 'mpesa_env', 'mpesa_consumer_key', 'mpesa_consumer_secret', 'mpesa_shortcode', 'mpesa_passkey',
        'paystack_enabled', 'paystack_public_key', 'paystack_secret_key',
        'flutterwave_enabled', 'flutterwave_public_key', 'flutterwave_secret_key', 'flutterwave_encryption_key',
    ];

    public function mount(): void
    {
        $state = [];
        foreach (self::KEYS as $key) {
            $state[$key] = Setting::get($key);
        }
        $state['mail_mailer'] ??= 'log';
        $state['smtp_port'] ??= '587';
        $state['smtp_encryption'] ??= 'tls';
        $state['mpesa_env'] ??= 'sandbox';

        $this->form->fill($state);
    }

    public function form(Schema $schema): Schema
    {
        $base = rtrim(config('app.url'), '/');

        return $schema
            ->statePath('data')
            ->components([
                Section::make('Email')
                    ->description('Connect any email provider over SMTP (Gmail, Google Workspace, Mailgun, SendGrid, Postmark, Brevo, Amazon SES, or your cPanel mailbox). Save, then use "Send test email" above.')
                    ->icon('heroicon-o-envelope')
                    ->schema([
                        Select::make('mail_mailer')
                            ->label('Email delivery')
                            ->live()
                            ->options([
                                'log' => 'Off (log only, no emails sent)',
                                'smtp' => 'SMTP (any provider)',
                            ])
                            ->required(),
                        TextInput::make('mail_from_address')->label('From address')->email()->placeholder('hello@moneywise.co.ke'),
                        TextInput::make('mail_from_name')->label('From name')->placeholder('Money-Wise'),
                        Section::make('SMTP details')
                            ->visible(fn (Get $get) => $get('mail_mailer') === 'smtp')
                            ->columns(2)
                            ->schema([
                                TextInput::make('smtp_host')->label('Host')->placeholder('smtp.gmail.com')->required(fn (Get $get) => $get('mail_mailer') === 'smtp'),
                                TextInput::make('smtp_port')->label('Port')->numeric()->placeholder('587'),
                                TextInput::make('smtp_username')->label('Username')->placeholder('you@yourdomain.com'),
                                TextInput::make('smtp_password')->label('Password / API key')->password()->revealable(),
                                Select::make('smtp_encryption')->label('Encryption')->options(['tls' => 'TLS (port 587)', 'ssl' => 'SSL (port 465)', 'none' => 'None']),
                            ]),
                    ])
                    ->columns(2),

                Section::make('Payments: M-Pesa (Safaricom Daraja)')
                    ->description('STK push for KES payments. Add the callback URL below in your Daraja app.')
                    ->icon('heroicon-o-device-phone-mobile')
                    ->collapsed()
                    ->columns(2)
                    ->schema([
                        Toggle::make('mpesa_enabled')->label('Enable M-Pesa')->columnSpanFull(),
                        Select::make('mpesa_env')->label('Environment')->options(['sandbox' => 'Sandbox', 'production' => 'Production']),
                        TextInput::make('mpesa_shortcode')->label('Business shortcode / Till'),
                        TextInput::make('mpesa_consumer_key')->label('Consumer key'),
                        TextInput::make('mpesa_consumer_secret')->label('Consumer secret')->password()->revealable(),
                        TextInput::make('mpesa_passkey')->label('Passkey')->password()->revealable(),
                        Placeholder::make('mpesa_webhook')->label('STK callback URL (add in Daraja)')->content($base.'/webhooks/mpesa')->columnSpanFull(),
                    ]),

                Section::make('Payments: Paystack')
                    ->description('Cards, bank and mobile money. Add the webhook URL below in your Paystack dashboard.')
                    ->icon('heroicon-o-credit-card')
                    ->collapsed()
                    ->columns(2)
                    ->schema([
                        Toggle::make('paystack_enabled')->label('Enable Paystack')->columnSpanFull(),
                        TextInput::make('paystack_public_key')->label('Public key')->placeholder('pk_live_...'),
                        TextInput::make('paystack_secret_key')->label('Secret key')->password()->revealable()->placeholder('sk_live_...'),
                        Placeholder::make('paystack_webhook')->label('Webhook URL (add in Paystack)')->content($base.'/webhooks/paystack')->columnSpanFull(),
                    ]),

                Section::make('Payments: Flutterwave')
                    ->description('Cards and mobile money across Africa. Add the webhook URL below in your Flutterwave dashboard.')
                    ->icon('heroicon-o-banknotes')
                    ->collapsed()
                    ->columns(2)
                    ->schema([
                        Toggle::make('flutterwave_enabled')->label('Enable Flutterwave')->columnSpanFull(),
                        TextInput::make('flutterwave_public_key')->label('Public key')->placeholder('FLWPUBK-...'),
                        TextInput::make('flutterwave_secret_key')->label('Secret key')->password()->revealable()->placeholder('FLWSECK-...'),
                        TextInput::make('flutterwave_encryption_key')->label('Encryption key')->password()->revealable(),
                        Placeholder::make('flutterwave_webhook')->label('Webhook URL (add in Flutterwave)')->content($base.'/webhooks/flutterwave')->columnSpanFull(),
                    ]),
            ]);
    }

    public function save(): void
    {
        $data = $this->form->getState();

        foreach (self::KEYS as $key) {
            Setting::put($key, $data[$key] ?? null, in_array($key, self::SECRETS, true));
        }

        Notification::make()->title('Configuration saved')->success()->send();
    }

    protected function getHeaderActions(): array
    {
        return [
            Action::make('sendTest')
                ->label('Send test email')
                ->icon('heroicon-o-paper-airplane')
                ->color('gray')
                ->requiresConfirmation()
                ->modalDescription(fn () => 'Send a test email to '.auth()->user()->email.' using the saved settings.')
                ->action(function () {
                    if (Setting::get('mail_mailer', 'log') === 'log') {
                        Notification::make()->title('Email is off')->body('Set email delivery to SMTP and Save first.')->warning()->send();

                        return;
                    }

                    try {
                        Mail::raw('This is a test email from your Money-Wise admin. If you can read this, your email settings are working.', function ($m) {
                            $m->to(auth()->user()->email)->subject('Money-Wise test email');
                        });
                        Notification::make()->title('Test email sent to '.auth()->user()->email)->success()->send();
                    } catch (\Throwable $e) {
                        Notification::make()->title('Could not send')->body($e->getMessage())->danger()->send();
                    }
                }),
        ];
    }
}
