<?php

namespace App\Modules\VisaMasterPaymentOrder\Filament\Actions;

use App\Modules\CurrencyRate\Models\CurrencyRate;
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterSettings;
use App\Modules\VisaMasterPaymentOrder\Repositories\VisaMasterPaymentOrderRepository;
use Filament\Actions\Action;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
use Filament\Schemas\Components\Fieldset;
use Filament\Schemas\Components\Utilities\Set;
use Livewire\Component;

class PayVisaMasterPaymentAction
{
    public static function make(): Action
    {
        return Action::make('pay_visa_master_payment')
            ->label(sprintf('%s %s', __('Make payment for:'), today()->translatedFormat('F')))
            ->icon('heroicon-o-credit-card')
            ->modal()
            ->schema(function () {
                $usd_to_tmt = floatval(CurrencyRate::where('currency_from', 'USD')->where('currency_to', 'TMT')->first('value')?->value);

                if (! $usd_to_tmt) {
                    return [];
                }

                $visaMasterPaymentOrderRepository = VisaMasterPaymentOrderRepository::make();

                $bankFee = $visaMasterPaymentOrderRepository->bankFee();
                $gbusFee = $visaMasterPaymentOrderRepository->gbusFee();

                $max_value = number_format($usd_to_tmt * 250, 2);

                return [
                    Fieldset::make(__('Tax'))
                        ->columns([
                            'default' => 1,
                            'md' => 2,
                            'xl' => 3,
                        ])
                        ->schema([
                            TextEntry::make('usd_to_tmt')
                                ->extraAttributes(['class' => 'uppercase tracking-wide font-bold text-xs'])
                                ->label(sprintf('1 USD = %s TMT', $usd_to_tmt)),

                            TextEntry::make('bank_fee')
                                ->extraAttributes(['class' => 'uppercase tracking-wide font-bold text-xs'])
                                ->label(sprintf('Bankyň tutumy: %s TMT', $bankFee)),

                            TextEntry::make('gbus_fee')
                                ->extraAttributes(['class' => 'uppercase tracking-wide font-bold text-xs'])
                                ->label(sprintf('GBÜS tutumy: %s TMT', $gbusFee)),
                        ]),

                    Fieldset::make()
                        ->columns([
                            'default' => 1,
                            'md' => 2,
                            'xl' => 3,
                        ])
                        ->schema([
                            TextInput::make('payment_amount')
                                ->label(sprintf('%s (%s)', __('Payment amount'), __('TMT')))
                                ->required()
                                ->numeric()
                                ->maxValue($max_value)
                                ->helperText(sprintf('Iň ýokary möçberi: %s TMT', $max_value))
                                ->live()
                                ->afterStateUpdated(function (Set $set, ?string $state) use ($usd_to_tmt, $bankFee, $gbusFee) {
                                    if (is_null($state) || $state == 0 || $state == '') {
                                        $set('usd_rate', '');

                                        return;
                                    }
                                    $state = floatval($state);

                                    $usd_rate = $state / $usd_to_tmt;
                                    $total_amount = $state + $bankFee + $gbusFee;

                                    $set('usd_rate', number_format($usd_rate, 2, '.', ''));
                                    $set('total_amount', number_format($total_amount, 2, '.', ''));
                                }),

                            TextInput::make('usd_rate')
                                ->label(__('USD ekwalendi'))
                                ->suffix('USD')
                                ->readOnly(),

                            TextInput::make('total_amount')
                                ->label(__('Total amount'))
                                ->suffix('TMT')
                                ->readOnly(),
                        ]),

                ];
            })
            ->action(function (array $data, VisaMasterPaymentOrder $record, Component $livewire): void {
                /** @var array{payment_amount: float, usd_rate: float, total_amount: float} */
                $formData = $data;

                $visaMasterPaymentOrderRepository = VisaMasterPaymentOrderRepository::make();

                $today = today();

                // Needs to be tested...
                if ($visaMasterPaymentOrderRepository->hasBeenPaidThisMonth($record, $today)) {
                    Notification::make()
                        ->title(__('This month has already been paid').'!')
                        ->body(__('This month has already been paid'))
                        ->danger()
                        ->send();

                    return;
                }

                // Needs to be tested...
                if ($visaMasterPaymentOrderRepository->isEndOfMonth($today)) {
                    Notification::make()
                        ->title(__('Payment cannot be accepted on the last day of the month').'!')
                        ->body(__('Payment cannot be accepted on the last day of the month'))
                        ->danger()
                        ->send();

                    return;
                }

                // Needs to be tested...
                if (! $record->branch || ! $record->branch->billing_visa_master_username) {
                    Notification::make()
                        ->title(__('Contact with the operator').'!')
                        ->body(__('Billing information is not available in the branch! The branch cannot accept Visa/Master payments.'))
                        ->danger()
                        ->send();

                    return;
                }

                $total_amount = $formData['payment_amount'] + $visaMasterPaymentOrderRepository->bankFee() + $visaMasterPaymentOrderRepository->gbusFee();

                $onlinePaymentRepository = $visaMasterPaymentOrderRepository->createOnlinePaymentOrder($record, $total_amount);

                if ($onlinePaymentRepository->failed()) {
                    Notification::make()
                        ->title(__('Payment error').'!')
                        ->body(sprintf('%s. %s. %s.', __('Problem connecting on HALKBANK SYSTEM'), __('Error has been captured'), __('Please try again later')))
                        ->danger()
                        ->send();

                    return;
                }

                $visaMasterPaymentOrderRepository->createPaymentRecord($record, $onlinePaymentRepository, $formData['usd_rate']);

                // Tell Livewire to open it in a new tab
                $livewire->js("window.open('{$onlinePaymentRepository->paymentLink()}', '_blank')");
            })
            ->modalSubmitActionLabel(__('Pay'));
    }
}
