<?php

declare(strict_types=1);

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

namespace App\Support;

use App\Business\Inventory\Enums\InventoryDocumentStatus;
use App\Business\Inventory\InventoryDocumentLineBarcodeQuickAddService;
use App\Business\Sales\Enums\SalesOrderStatus;
use App\Business\Sales\SalesOrderService;
use App\Models\DberpOtherStockOutOrder;
use App\Models\DberpSalesOrder;
use App\Models\DberpStocktakeOrder;
use Filament\Actions\Action;
use Illuminate\Validation\ValidationException;

/**
 * 单据明细 RelationManager 表头「条码快录」。
 *
 * NOTE: 不得用于必须绑定上游订单行的单据（采购到货、销售出库等）。
 * 未来 Excel 明细导入亦不得绕过本类单据的来源、单位与库存校验。
 */
final class DberpDocumentLineBarcodeQuickAddHeaderActions
{
    public static function salesOrderItems(callable $resolveOwner): Action
    {
        return self::makeAction(
            name: 'barcode_quick_add',
            resolveOwner: $resolveOwner,
            visible: function () use ($resolveOwner): bool {
                $owner = $resolveOwner();

                return $owner instanceof DberpSalesOrder
                    && $owner->status === SalesOrderStatus::Draft->value;
            },
            action: function (array $data) use ($resolveOwner): void {
                $order = $resolveOwner();
                if (! $order instanceof DberpSalesOrder) {
                    return;
                }

                self::runQuickAdd(
                    fn () => app(SalesOrderService::class)->quickAddItemByBarcode($order, $data),
                );
            },
            modalDescription: __('dberp.hints.barcode_quick_add_sales_order_modal'),
        );
    }

    public static function stocktakeOrderItems(callable $resolveOwner): Action
    {
        return self::makeAction(
            name: 'barcode_quick_add',
            resolveOwner: $resolveOwner,
            visible: function () use ($resolveOwner): bool {
                $owner = $resolveOwner();

                return $owner instanceof DberpStocktakeOrder
                    && $owner->status === InventoryDocumentStatus::Draft->value;
            },
            action: function (array $data) use ($resolveOwner): void {
                $order = $resolveOwner();
                if (! $order instanceof DberpStocktakeOrder) {
                    return;
                }

                self::runQuickAdd(
                    fn () => app(InventoryDocumentLineBarcodeQuickAddService::class)->quickAddStocktakeLine($order, $data),
                );
            },
            modalDescription: __('dberp.hints.barcode_quick_add_stocktake_modal'),
        );
    }

    public static function otherStockOutOrderItems(callable $resolveOwner): Action
    {
        return self::makeAction(
            name: 'barcode_quick_add',
            resolveOwner: $resolveOwner,
            visible: function () use ($resolveOwner): bool {
                $owner = $resolveOwner();

                return $owner instanceof DberpOtherStockOutOrder
                    && $owner->status === InventoryDocumentStatus::Draft->value;
            },
            action: function (array $data) use ($resolveOwner): void {
                $order = $resolveOwner();
                if (! $order instanceof DberpOtherStockOutOrder) {
                    return;
                }

                self::runQuickAdd(
                    fn () => app(InventoryDocumentLineBarcodeQuickAddService::class)->quickAddOtherStockOutLine($order, $data),
                );
            },
            modalDescription: __('dberp.hints.barcode_quick_add_other_stock_out_modal'),
        );
    }

    private static function makeAction(
        string $name,
        callable $resolveOwner,
        callable $visible,
        callable $action,
        string $modalDescription,
    ): Action {
        return Action::make($name)
            ->label(__('dberp.actions.barcode_quick_add_document_line'))
            ->modalHeading(__('dberp.actions.barcode_quick_add_document_line'))
            ->modalDescription($modalDescription)
            ->visible($visible)
            ->form(DberpDocumentLineBarcodeQuickAddFormFields::modalFields())
            ->action(function (array $data) use ($action): void {
                $action($data);
            });
    }

    /**
     * @param  callable(): string  $quickAdd
     */
    private static function runQuickAdd(callable $quickAdd): void
    {
        try {
            $outcome = $quickAdd();
            DberpDocumentLineBarcodeQuickAddSupport::notifyOutcome($outcome);
        } catch (ValidationException $exception) {
            DberpDocumentLineBarcodeQuickAddSupport::notifyValidation($exception);

            throw $exception;
        }
    }
}
