<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpPurchaseOrders\Pages;

use App\Business\Inventory\Enums\InventoryDocumentStatus;
use App\Business\MasterData\DberpDocumentAddressSnapshotService;
use App\Business\Purchase\Enums\PurchaseOrderStatus;
use App\Business\Purchase\PurchaseOrderService;
use App\Filament\Resources\DberpPaymentOrders\DberpPaymentOrderResource;
use App\Filament\Resources\DberpPurchaseOrders\DberpPurchaseOrderResource;
use App\Filament\Resources\DberpPurchaseReceipts\DberpPurchaseReceiptResource;
use App\Filament\Resources\Pages\EditRecord;
use App\Filament\Support\DberpPrintFilamentAction;
use App\Models\DberpPurchaseOrder;
use App\Services\DberpPermissionService;
use App\Support\Print\Documents\PurchaseOrderPrintPresenter;
use Filament\Actions\Action;
use Filament\Actions\DeleteAction;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Auth;

class EditDberpPurchaseOrder extends EditRecord
{
    protected static string $resource = DberpPurchaseOrderResource::class;

    protected function mutateFormDataBeforeSave(array $data): array
    {
        return app(DberpDocumentAddressSnapshotService::class)
            ->fillSupplierSnapshotWhenNeeded($data, $this->getRecord());
    }

    protected function getHeaderActions(): array
    {
        $permissionService = app(DberpPermissionService::class);

        return [
            DberpPrintFilamentAction::forDocument(
                PurchaseOrderPrintPresenter::DOCUMENT_KEY,
                fn (DberpPurchaseOrder $record): bool => DberpPurchaseOrderResource::canView($record),
            ),
            Action::make('register_payment')
                ->label(__('dberp.actions.register_payment'))
                ->visible(fn (DberpPurchaseOrder $record): bool => $permissionService->allows(Auth::user(), DberpPermissionService::CREATE_PAYMENT_ORDER)
                    && DberpPaymentOrderResource::canCreate()
                    && ! in_array($record->status, [
                        PurchaseOrderStatus::Draft->value,
                        PurchaseOrderStatus::Voided->value,
                    ], true))
                ->url(fn (DberpPurchaseOrder $record): string => DberpPaymentOrderResource::getUrl('create', [
                    'purchase_order_id' => $record->getKey(),
                    'supplier_id' => $record->supplier_id,
                ])),
            Action::make('register_arrival')
                ->label(__('dberp.actions.register_arrival'))
                ->visible(fn (DberpPurchaseOrder $record): bool => in_array($record->status, [
                    PurchaseOrderStatus::Confirmed->value,
                    PurchaseOrderStatus::PartiallyReceived->value,
                ], true) && (float) $record->remaining_arrival_quantity > 0.00005)
                ->url(fn (): string => DberpPurchaseReceiptResource::getUrl('create', ['purchase_order_id' => $this->record->getKey()])),
            Action::make('confirm')
                ->label(__('dberp.actions.confirm'))
                ->formWrapper(false)
                ->requiresConfirmation()
                ->modalDescription(__('dberp.hints.purchase_confirm'))
                ->visible(fn (DberpPurchaseOrder $record): bool => $record->status === PurchaseOrderStatus::Draft->value)
                ->action(function (): void {
                    app(PurchaseOrderService::class)->confirm($this->record);
                    $this->record->refresh();
                    $this->fillForm();
                    Notification::make()
                        ->title(__('dberp.notifications.purchase_order_confirmed'))
                        ->success()
                        ->send();
                }),
            Action::make('close')
                ->label(__('dberp.actions.close'))
                ->formWrapper(false)
                ->requiresConfirmation()
                ->modalDescription(__('dberp.hints.purchase_close'))
                ->visible(fn (DberpPurchaseOrder $record): bool => in_array($record->status, [
                    PurchaseOrderStatus::Confirmed->value,
                    PurchaseOrderStatus::PartiallyReceived->value,
                    PurchaseOrderStatus::FullyReceived->value,
                ], true))
                ->action(function (): void {
                    app(PurchaseOrderService::class)->close($this->record);
                    $this->record->refresh();
                    $this->fillForm();
                    Notification::make()
                        ->title(__('dberp.notifications.purchase_order_closed'))
                        ->success()
                        ->send();
                }),
            Action::make('void')
                ->label(__('dberp.actions.void'))
                ->formWrapper(false)
                ->requiresConfirmation()
                ->modalHeading(fn (): string => (string) __('dberp.hints.purchase_order_void_heading'))
                ->modalDescription(__('dberp.hints.purchase_order_void'))
                ->visible(fn (DberpPurchaseOrder $record): bool => in_array($record->status, [PurchaseOrderStatus::Draft->value, PurchaseOrderStatus::Confirmed->value], true))
                ->disabled(fn (DberpPurchaseOrder $record): bool => $record->status === PurchaseOrderStatus::Confirmed->value && (
                    $record->receipts()->where('status', InventoryDocumentStatus::Effective->value)->exists()
                    || $record->returns()->where('status', InventoryDocumentStatus::Effective->value)->exists()
                ))
                ->tooltip(fn (DberpPurchaseOrder $record): ?string => $record->status === PurchaseOrderStatus::Confirmed->value && (
                    $record->receipts()->where('status', InventoryDocumentStatus::Effective->value)->exists()
                    || $record->returns()->where('status', InventoryDocumentStatus::Effective->value)->exists()
                ) ? (string) __('dberp.hints.purchase_order_void_blocked_downstream') : null)
                ->action(function (): void {
                    app(PurchaseOrderService::class)->void($this->record);
                    $this->record->refresh();
                    $this->fillForm();
                    Notification::make()
                        ->title(__('dberp.notifications.purchase_order_voided'))
                        ->success()
                        ->send();
                }),
            DeleteAction::make()
                ->visible(fn (DberpPurchaseOrder $record): bool => $record->status === PurchaseOrderStatus::Draft->value),
        ];
    }
}
