<?php

namespace App\Http\Requests;

use Closure;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;

class UpdateImportCondition extends FormRequest
{
    /**
     * Maximum length of a stored rule value.
     *
     * Rule values are persisted to import_condition_rules.value, a VARCHAR(255)
     * column (see mercury-data-models tenant migration create_import_conditions_table).
     * "is one of" rules json_encode the selected values into this single column, so a
     * long selection overflows the column and produces a raw DB error on save.
     */
    private const MAX_VALUE_LENGTH = 255;
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return Auth::check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'active' => [
                'nullable',
                'present',
                'boolean',
            ],
            'do_not_import' => [
                'nullable',
                'boolean',
            ],
            'do_not_publish' => [
                'nullable',
                'present',
                'boolean',
            ],
            'rules' => 'array',
            'rules.*.field' => [
                'required'
            ],
            'rules.*.condition' => [
                'required'
            ],
            'rules.*.value' => [
                'nullable',
                $this->ruleValueLengthRule(),
            ],
        ];
    }

    /**
     * Validate that a rule value fits the storage column once encoded.
     *
     * Array values (from "is one of" / "is not one of" selections) are json_encoded
     * before storage, mirroring ImportConditionRepository::normalizeRuleValue(), so the
     * length check runs against the encoded string rather than the element count.
     */
    private function ruleValueLengthRule(): Closure
    {
        return function (string $attribute, mixed $value, Closure $fail): void {
            $encoded = is_array($value) ? json_encode($value) : (string) $value;

            if (mb_strlen($encoded) > self::MAX_VALUE_LENGTH) {
                $fail(
                    'The selected values list is too long to save. Reduce the number of selected '
                    . 'values, or split them across two separate import conditions.'
                );
            }
        };
    }
}
