<?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\InventorySerialNumberService;
use Closure;
use Filament\Forms\Components\Field;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;

/**
 * 入库类单据明细：手工录入新序列号（支持逐个标签、逗号分隔与批量粘贴）。
 *
 * NOTE: 入库登记的是尚未入账的新序列号，不提供「在库序列号」点选（该能力仅用于出库扣减）。
 */
final class DberpDocumentLineInboundSerialNumberFormFields
{
    public const BULK_PASTE_FIELD = '_inbound_serial_bulk_paste';

    /**
     * @return list<Field>
     */
    public static function inboundSerialNumberFields(
        Closure $resolveProduct,
        string $quantityField,
        string $tagsLabel = 'dberp.fields.serial_numbers',
    ): array {
        return [
            self::bulkPasteTextarea($resolveProduct, $quantityField),
            self::serialNumbersTagsInput($resolveProduct, $quantityField, $tagsLabel),
        ];
    }

    private static function bulkPasteTextarea(Closure $resolveProduct, string $quantityField): Textarea
    {
        return DberpProductInventoryRefinementFormFields::constrainSerialField(
            Textarea::make(self::BULK_PASTE_FIELD)
                ->label(__('dberp.document_line.bulk_paste_serial_numbers'))
                ->helperText(__('dberp.document_line.bulk_paste_serial_numbers_helper'))
                ->rows(3)
                ->dehydrated(false)
                ->placeholder(__('dberp.document_line.bulk_paste_serial_numbers_placeholder'))
                ->live(debounce: 500)
                ->afterStateUpdated(function (?string $state, Set $set, Get $get) use ($resolveProduct, $quantityField): void {
                    if (blank($state)) {
                        return;
                    }

                    $product = $resolveProduct($get);

                    if (! DberpProductInventoryRefinementFormFields::productManagesSerial($product)) {
                        return;
                    }

                    $parsed = app(InventorySerialNumberService::class)->normalizeSerialNumbers($state);

                    if ($parsed === []) {
                        return;
                    }

                    $maxCount = DberpDocumentLineSerialNumberFormFields::maxSerialCountForQuantity(
                        $resolveProduct,
                        $quantityField,
                    )($get);

                    $merged = DberpDocumentLineSerialNumberFormFields::trimSerialsToMaxCount(
                        array_merge($get('serial_numbers') ?? [], $parsed),
                        $maxCount,
                    );

                    $set('serial_numbers', $merged);
                    $set(self::BULK_PASTE_FIELD, null);
                })
                ->columnSpanFull(),
            $resolveProduct,
        );
    }

    private static function serialNumbersTagsInput(
        Closure $resolveProduct,
        string $quantityField,
        string $tagsLabel,
    ): TagsInput {
        return DberpProductInventoryRefinementFormFields::constrainSerialField(
            DberpDocumentLineSerialNumberFormFields::configureTagsInput(
                TagsInput::make('serial_numbers')
                    ->label(__($tagsLabel))
                    ->helperText(__('dberp.document_line.inbound_serial_numbers_helper'))
                    ->separator(',')
                    ->splitKeys(['Enter', 'Tab'])
                    ->dehydrated(true)
                    ->dehydrateStateUsing(
                        fn (mixed $state): array => DberpDocumentLineSerialNumberFormFields::expandSerialNumberEntries(
                            is_array($state) || is_string($state) ? $state : [],
                        ),
                    )
                    ->columnSpanFull(),
                $resolveProduct,
                $quantityField,
            ),
            $resolveProduct,
        );
    }
}
