<?php

namespace App\Http\Requests\Quote;

use Illuminate\Foundation\Http\FormRequest;

/**
 * 다건 BOM 기반 견적 산출 요청
 *
 * React 견적등록 화면에서 여러 품목의 자동 견적 산출 시 사용됩니다.
 * React QuoteFormItem 인터페이스의 필드명(camelCase)과
 * API 입력 변수(W0, H0 등)를 모두 지원합니다.
 */
class QuoteBomBulkCalculateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            // 품목 배열 (최소 1개, 최대 100개)
            'items' => 'required|array|min:1|max:100',

            // 각 품목별 필수 입력
            'items.*.finished_goods_code' => 'required|string|max:50',

            // React 필드명 (camelCase) - 우선 적용
            'items.*.openWidth' => 'nullable|numeric|min:100|max:20000',
            'items.*.openHeight' => 'nullable|numeric|min:100|max:20000',
            'items.*.quantity' => 'nullable|integer|min:1',
            'items.*.productCategory' => 'nullable|string|in:SCREEN,STEEL',
            'items.*.guideRailType' => 'nullable|string|in:wall,ceiling,floor,mixed',
            'items.*.motorPower' => 'nullable|string|in:single,three',
            'items.*.controller' => 'nullable|string|in:basic,smart,premium',
            'items.*.wingSize' => 'nullable|numeric|min:0|max:500',
            'items.*.inspectionFee' => 'nullable|numeric|min:0',

            // API 변수명 (약어) - React 필드명이 없을 때 사용
            'items.*.W0' => 'nullable|numeric|min:100|max:20000',
            'items.*.H0' => 'nullable|numeric|min:100|max:20000',
            'items.*.QTY' => 'nullable|integer|min:1',
            'items.*.PC' => 'nullable|string|in:SCREEN,STEEL',
            'items.*.GT' => 'nullable|string|in:wall,ceiling,floor,mixed',
            'items.*.MP' => 'nullable|string|in:single,three',
            'items.*.CT' => 'nullable|string|in:basic,smart,premium',
            'items.*.WS' => 'nullable|numeric|min:0|max:500',
            'items.*.INSP' => 'nullable|numeric|min:0',

            // 디버그 모드 (개발용)
            'debug' => 'nullable|boolean',
        ];
    }

    public function attributes(): array
    {
        return [
            'items' => __('validation.attributes.items'),
            'items.*.finished_goods_code' => __('validation.attributes.finished_goods_code'),
            'items.*.openWidth' => __('validation.attributes.open_width'),
            'items.*.openHeight' => __('validation.attributes.open_height'),
            'items.*.quantity' => __('validation.attributes.quantity'),
            'items.*.productCategory' => __('validation.attributes.product_category'),
            'items.*.guideRailType' => __('validation.attributes.guide_rail_type'),
            'items.*.motorPower' => __('validation.attributes.motor_power'),
            'items.*.controller' => __('validation.attributes.controller'),
            'items.*.wingSize' => __('validation.attributes.wing_size'),
            'items.*.inspectionFee' => __('validation.attributes.inspection_fee'),
        ];
    }

    public function messages(): array
    {
        return [
            'items.required' => __('error.items_required'),
            'items.min' => __('error.items_min'),
            'items.max' => __('error.items_max'),
            'items.*.finished_goods_code.required' => __('error.finished_goods_code_required'),
        ];
    }

    /**
     * 입력 품목 배열 반환 (FormulaEvaluatorService용)
     *
     * React 필드명(camelCase)과 API 변수명(약어) 모두 지원
     * React 필드명 우선, 없으면 API 변수명 사용
     *
     * @return array<int, array{finished_goods_code: string, inputs: array}>
     */
    public function getInputItems(): array
    {
        $validated = $this->validated();
        $result = [];

        foreach ($validated['items'] as $index => $item) {
            $result[] = [
                'index' => $index,
                'finished_goods_code' => $item['finished_goods_code'],
                'inputs' => $this->normalizeInputVariables($item),
            ];
        }

        return $result;
    }

    /**
     * 단일 품목의 입력 변수 정규화
     *
     * React 필드명 → API 변수명 매핑
     * - openWidth → W0
     * - openHeight → H0
     * - quantity → QTY
     * - productCategory → PC
     * - guideRailType → GT
     * - motorPower → MP
     * - controller → CT
     * - wingSize → WS
     * - inspectionFee → INSP
     */
    private function normalizeInputVariables(array $item): array
    {
        return [
            'W0' => (float) ($item['openWidth'] ?? $item['W0'] ?? 0),
            'H0' => (float) ($item['openHeight'] ?? $item['H0'] ?? 0),
            'QTY' => (int) ($item['quantity'] ?? $item['QTY'] ?? 1),
            'PC' => $item['productCategory'] ?? $item['PC'] ?? 'SCREEN',
            'GT' => $item['guideRailType'] ?? $item['GT'] ?? 'wall',
            'MP' => $item['motorPower'] ?? $item['MP'] ?? 'single',
            'CT' => $item['controller'] ?? $item['CT'] ?? 'basic',
            'WS' => (float) ($item['wingSize'] ?? $item['WS'] ?? 50),
            'INSP' => (float) ($item['inspectionFee'] ?? $item['INSP'] ?? 50000),
        ];
    }

    /**
     * 필수 입력 검증 (W0, H0)
     *
     * React 필드명이든 API 변수명이든 둘 중 하나는 있어야 함
     */
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            $items = $this->input('items', []);

            foreach ($items as $index => $item) {
                // W0 (openWidth 또는 W0) 검증
                $w0 = $item['openWidth'] ?? $item['W0'] ?? null;
                if ($w0 === null || $w0 === '') {
                    $validator->errors()->add(
                        "items.{$index}.openWidth",
                        __('error.open_width_required')
                    );
                }

                // H0 (openHeight 또는 H0) 검증
                $h0 = $item['openHeight'] ?? $item['H0'] ?? null;
                if ($h0 === null || $h0 === '') {
                    $validator->errors()->add(
                        "items.{$index}.openHeight",
                        __('error.open_height_required')
                    );
                }
            }
        });
    }
}
