<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

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\PluginIntegration\DberpAiPageContextFilamentBridge;
use App\Support\PluginIntegration\LightApprovalDocumentGuardBridge;
use App\Support\PluginIntegration\LightApprovalFilamentBridge;
use App\Support\Print\Documents\PurchaseOrderPrintPresenter;
use App\Tools\Context\PageKind;
use Filament\Actions\Action;
use Filament\Actions\DeleteAction;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;

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 [
            ...DberpAiPageContextFilamentBridge::recordHeaderActionsFor(
                $this->getRecord(),
                PageKind::PurchaseOrderEdit,
            ),
            DberpPrintFilamentAction::forDocument(
                PurchaseOrderPrintPresenter::DOCUMENT_KEY,
                fn (DberpPurchaseOrder $record): bool => DberpPurchaseOrderResource::canView($record),
            ),
            ...($this->record instanceof DberpPurchaseOrder
                ? LightApprovalFilamentBridge::purchaseOrderEditHeaderActions($this->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)
                ->disabled(fn (DberpPurchaseOrder $record): bool => ! LightApprovalDocumentGuardBridge::canConfirm(
                    LightApprovalDocumentGuardBridge::ADAPTER_PURCHASE_ORDER,
                    $record,
                ))
                ->tooltip(fn (DberpPurchaseOrder $record): ?string => LightApprovalDocumentGuardBridge::confirmBlockReason(
                    LightApprovalDocumentGuardBridge::ADAPTER_PURCHASE_ORDER,
                    $record,
                ))
                ->action(function (): void {
                    try {
                        app(PurchaseOrderService::class)->confirm($this->record);
                        $this->record->refresh();
                        $this->fillForm();
                        Notification::make()
                            ->title(__('dberp.notifications.purchase_order_confirmed'))
                            ->success()
                            ->send();
                    } catch (ValidationException $exception) {
                        Notification::make()
                            ->title((string) __('dberp.notifications.warning'))
                            ->body(collect($exception->errors())->flatten()->first())
                            ->danger()
                            ->send();

                        throw $exception;
                    }
                }),
            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),
        ];
    }
}
