<?php

declare(strict_types=1);

namespace App\Support;

use App\Filament\Support\DberpFilamentNumberFields;
use App\Support\Enums\DberpDocumentLineBarcodeDuplicateMode;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Illuminate\Validation\ValidationException;

/**
 * 单据明细「条码快录」弹窗表单字段。
 */
final class DberpDocumentLineBarcodeQuickAddFormFields
{
    public const FIELD_BARCODE = 'barcode';

    public const FIELD_QUANTITY = 'quantity';

    public const FIELD_DUPLICATE_MODE = 'duplicate_mode';

    public const FIELD_REMARK = 'remark';

    /**
     * @return list<TextInput|Select|Textarea>
     */
    public static function modalFields(bool $withRemark = true): array
    {
        $fields = [
            TextInput::make(self::FIELD_BARCODE)
                ->label(__('dberp.fields.barcode'))
                ->required()
                ->autofocus()
                ->maxLength(64),
            DberpFilamentNumberFields::documentLineQuantityInput(
                TextInput::make(self::FIELD_QUANTITY)
                    ->label(__('dberp.fields.quantity'))
                    ->default('1.0000')
                    ->required(),
                withHelperText: false,
                minValue: 0.0001,
            ),
            Select::make(self::FIELD_DUPLICATE_MODE)
                ->label(__('dberp.fields.barcode_duplicate_handling'))
                ->options(DberpDocumentLineBarcodeDuplicateMode::options())
                ->default(DberpDocumentLineBarcodeDuplicateMode::IncreaseQuantity->value)
                ->required()
                ->native(false),
        ];

        if ($withRemark) {
            $fields[] = Textarea::make(self::FIELD_REMARK)
                ->label(__('dberp.fields.remark'))
                ->rows(2)
                ->columnSpanFull();
        }

        return $fields;
    }

    public static function normalizeQuantity(mixed $raw): string
    {
        $formatted = number_format((float) (string) ($raw ?? '1'), 4, '.', '');
        if ((float) $formatted <= 0) {
            throw ValidationException::withMessages([
                self::FIELD_QUANTITY => (string) __('dberp.errors.barcode_quick_add_quantity_must_be_positive'),
            ]);
        }

        return $formatted;
    }

    public static function duplicateModeFromData(array $data): DberpDocumentLineBarcodeDuplicateMode
    {
        return DberpDocumentLineBarcodeDuplicateMode::tryFrom(
            (string) ($data[self::FIELD_DUPLICATE_MODE] ?? DberpDocumentLineBarcodeDuplicateMode::IncreaseQuantity->value),
        ) ?? DberpDocumentLineBarcodeDuplicateMode::IncreaseQuantity;
    }
}
