<?php

namespace App\Services\Quote\Handlers;

use App\Services\Quote\EstimatePriceService;

/**
 * 경동기업 전용 견적 계산 핸들러
 *
 * 5130 레거시 시스템의 견적 로직을 SAM에 구현
 * tenant_id = 287 전용
 */
class KyungdongFormulaHandler
{
    private const TENANT_ID = 287;

    private EstimatePriceService $priceService;

    public function __construct(?EstimatePriceService $priceService = null)
    {
        $this->priceService = $priceService ?? new EstimatePriceService(self::TENANT_ID);
    }

    // =========================================================================
    // 모터 용량 계산
    // =========================================================================

    /**
     * 모터 용량 계산 (3차원 조건: 제품타입 × 인치 × 중량)
     *
     * @param  string  $productType  제품 타입 (screen, steel)
     * @param  float  $weight  중량 (kg)
     * @param  string  $bracketInch  브라켓 인치 (4, 5, 6, 8)
     * @return string 모터 용량 (150K, 300K, 400K, 500K, 600K, 800K, 1000K)
     */
    public function calculateMotorCapacity(string $productType, float $weight, string $bracketInch): string
    {
        $inch = (int) $bracketInch;

        if ($productType === 'screen') {
            return $this->calculateScreenMotor($weight, $inch);
        }

        return $this->calculateSteelMotor($weight, $inch);
    }

    /**
     * 스크린 모터 용량 계산
     */
    private function calculateScreenMotor(float $weight, int $inch): string
    {
        if ($inch === 4) {
            if ($weight <= 150) {
                return '150K';
            }
            if ($weight <= 300) {
                return '300K';
            }

            return '400K';
        }

        if ($inch === 5) {
            if ($weight <= 123) {
                return '150K';
            }
            if ($weight <= 246) {
                return '300K';
            }
            if ($weight <= 327) {
                return '400K';
            }
            if ($weight <= 500) {
                return '500K';
            }

            return '600K';
        }

        if ($inch === 6) {
            if ($weight <= 104) {
                return '150K';
            }
            if ($weight <= 208) {
                return '300K';
            }
            if ($weight <= 300) {
                return '400K';
            }
            if ($weight <= 424) {
                return '500K';
            }

            return '600K';
        }

        // 기본값
        return '300K';
    }

    /**
     * 철재 모터 용량 계산
     */
    private function calculateSteelMotor(float $weight, int $inch): string
    {
        if ($inch === 4) {
            if ($weight <= 300) {
                return '300K';
            }

            return '400K';
        }

        if ($inch === 5) {
            if ($weight <= 246) {
                return '300K';
            }
            if ($weight <= 327) {
                return '400K';
            }
            if ($weight <= 500) {
                return '500K';
            }

            return '600K';
        }

        if ($inch === 6) {
            if ($weight <= 208) {
                return '300K';
            }
            if ($weight <= 277) {
                return '400K';
            }
            if ($weight <= 424) {
                return '500K';
            }
            if ($weight <= 508) {
                return '600K';
            }
            if ($weight <= 800) {
                return '800K';
            }

            return '1000K';
        }

        if ($inch === 8) {
            if ($weight <= 324) {
                return '500K';
            }
            if ($weight <= 388) {
                return '600K';
            }
            if ($weight <= 611) {
                return '800K';
            }

            return '1000K';
        }

        // 기본값
        return '300K';
    }

    // =========================================================================
    // 브라켓 크기 계산
    // =========================================================================

    /**
     * 브라켓 크기 결정
     *
     * @param  float  $weight  중량 (kg)
     * @param  string|null  $bracketInch  브라켓 인치 (선택)
     * @return string 브라켓 크기 (530*320, 600*350, 690*390)
     */
    public function calculateBracketSize(float $weight, ?string $bracketInch = null): string
    {
        $motorCapacity = $this->getMotorCapacityByWeight($weight, $bracketInch);

        return match ($motorCapacity) {
            '300K', '400K' => '530*320',
            '500K', '600K' => '600*350',
            '800K', '1000K' => '690*390',
            default => '530*320',
        };
    }

    /**
     * 중량으로 모터 용량 판단 (인치 없을 때)
     */
    private function getMotorCapacityByWeight(float $weight, ?string $bracketInch = null): string
    {
        if ($bracketInch) {
            // 인치가 있으면 철재 기준으로 계산
            return $this->calculateSteelMotor($weight, (int) $bracketInch);
        }

        // 인치 없으면 중량만으로 판단
        if ($weight <= 300) {
            return '300K';
        }
        if ($weight <= 400) {
            return '400K';
        }
        if ($weight <= 500) {
            return '500K';
        }
        if ($weight <= 600) {
            return '600K';
        }
        if ($weight <= 800) {
            return '800K';
        }

        return '1000K';
    }

    // =========================================================================
    // 주자재(스크린) 계산
    // =========================================================================

    /**
     * 스크린 주자재 가격 계산
     *
     * @param  float  $width  폭 (mm)
     * @param  float  $height  높이 (mm)
     * @return array [unit_price, area, total_price]
     */
    public function calculateScreenPrice(float $width, float $height): array
    {
        // 면적 계산: W0 × (H0 + 550) / 1,000,000
        // 5130 공식: col10 × (col11 + 550) / 1,000,000
        $calculateHeight = $height + 550;
        $area = ($width * $calculateHeight) / 1000000;

        // 원자재 단가 조회 (실리카/스크린)
        $unitPrice = $this->getRawMaterialPrice('실리카');

        // 5130 동일: round(area, 2) 후 단가 곱셈
        $roundedArea = round($area, 2);

        return [
            'unit_price' => $unitPrice,
            'area' => $roundedArea,
            'total_price' => round($unitPrice * $roundedArea),
        ];
    }

    /**
     * 슬랫(철재) 주자재 가격 계산
     * 5130 공식: W0 × (H0 + 50) / 1,000,000 × 단가
     *
     * @return array [unit_price, area, total_price]
     */
    public function calculateSlatPrice(float $width, float $height): array
    {
        $calculateHeight = $height + 50;
        $area = ($width * $calculateHeight) / 1000000;

        // 원자재 단가 조회 (방화/슬랫)
        $unitPrice = $this->getRawMaterialPrice('방화');

        $roundedArea = round($area, 2);

        return [
            'unit_price' => $unitPrice,
            'area' => $roundedArea,
            'total_price' => round($unitPrice * $roundedArea),
        ];
    }

    // =========================================================================
    // 단가 조회 메서드 (EstimatePriceService 사용)
    // =========================================================================

    /**
     * 원자재 단가 조회
     */
    public function getRawMaterialPrice(string $materialName): float
    {
        return $this->priceService->getRawMaterialPrice($materialName);
    }

    /**
     * 모터 단가 조회
     */
    public function getMotorPrice(string $motorCapacity): float
    {
        return $this->priceService->getMotorPrice($motorCapacity);
    }

    /**
     * 제어기 단가 조회
     */
    public function getControllerPrice(string $controllerType): float
    {
        return $this->priceService->getControllerPrice($controllerType);
    }

    /**
     * 샤프트 단가 조회
     */
    public function getShaftPrice(string $size, float $length): float
    {
        return $this->priceService->getShaftPrice($size, $length);
    }

    /**
     * 5130 고정 샤프트 제품 규격 매핑
     * col59~65: 3인치 300, 4인치 3000/4500/6000, 5인치 6000/7000/8200
     *
     * @param  string  $size  인치 (3, 4, 5)
     * @param  float  $lengthMm  W0 올림값 (mm)
     * @return float 매핑된 길이 (m 단위), 0이면 매핑 불가
     */
    private function mapShaftToFixedProduct(string $size, float $lengthMm): float
    {
        $products = match ($size) {
            '3' => [300],
            '4' => [3000, 4500, 6000],
            '5' => [6000, 7000, 8200],
            default => [6000, 7000, 8200],  // 기본 5인치
        };

        // 올림값 이상인 제품 중 가장 작은 것 선택
        foreach ($products as $productMm) {
            if ($lengthMm <= $productMm) {
                return $productMm / 1000;  // mm → m
            }
        }

        return 0;  // 매핑 불가 (초과)
    }

    /**
     * 파이프 단가 조회
     */
    public function getPipePrice(string $thickness, int $length): float
    {
        return $this->priceService->getPipePrice($thickness, $length);
    }

    /**
     * 모터 받침용 앵글 단가 조회
     *
     * @param  string  $searchOption  검색옵션 (스크린용, 철제300K 등)
     */
    public function getAnglePrice(string $searchOption): float
    {
        return $this->priceService->getAnglePrice($searchOption);
    }

    /**
     * 부자재용 앵글 단가 조회
     *
     * @param  string  $angleType  앵글타입 (앵글3T, 앵글4T)
     * @param  string  $size  길이 (2.5, 10)
     */
    public function getMainAnglePrice(string $angleType, string $size): float
    {
        return $this->priceService->getMainAnglePrice($angleType, $size);
    }

    // =========================================================================
    // 절곡품 계산 (10종)
    // =========================================================================

    /**
     * 절곡품 항목 계산 (10종)
     *
     * 케이스, 케이스용 연기차단재, 케이스 마구리, 가이드레일,
     * 레일용 연기차단재, 하장바, L바, 보강평철, 무게평철12T, 환봉
     *
     * @param  array  $params  입력 파라미터
     * @return array 절곡품 항목 배열
     */
    public function calculateSteelItems(array $params): array
    {
        $items = [];

        // 기본 파라미터
        $width = (float) ($params['W0'] ?? 0);
        $height = (float) ($params['H0'] ?? 0);
        $quantity = (int) ($params['QTY'] ?? 1);
        $productType = $params['product_type'] ?? 'screen';
        $modelName = $params['model_name'] ?? $params['product_model'] ?? 'KSS01';
        $rawFinish = $params['finishing_type'] ?? 'SUS';
        // DB에는 'SUS', 'EGI'로 저장 → 'SUS마감' → 'SUS' 변환
        $finishingType = str_replace('마감', '', $rawFinish);

        // 절곡품 관련 파라미터
        $caseSpec = $params['case_spec'] ?? '500*380';
        $caseLength = (float) ($params['case_length'] ?? ($width + 220));  // mm 단위 (레거시: W0+220)
        $guideType = $this->normalizeGuideType($params['guide_type'] ?? '벽면형');
        $guideSpec = $params['guide_spec'] ?? $params['guide_rail_spec'] ?? '120*70';
        $guideLength = (float) ($params['guide_length'] ?? ($height + 250)) / 1000;  // m 단위 (레거시: H0+250)
        $bottomBarLength = (float) ($params['bottombar_length'] ?? $width) / 1000;  // m 단위 (레거시: W0)
        $lbarLength = (float) ($params['lbar_length'] ?? ($width + 220)) / 1000;  // m 단위 (레거시: W0+220)
        $flatBarLength = (float) ($params['flatbar_length'] ?? ($width + 220)) / 1000;  // m 단위 (레거시: W0+220)
        $weightPlateQty = (int) ($params['weight_plate_qty'] ?? 0);  // 무게평철 수량
        // 환봉 수량: 5130 자동계산 (col10=폭 기준)
        // ≤3000→1, ≤6000→2, ≤9000→3, ≤12000→4 (× 수량)
        $roundBarQty = (int) ($params['round_bar_qty'] ?? -1);
        if ($roundBarQty < 0) {
            if ($width <= 3000) {
                $roundBarQty = 1 * $quantity;
            } elseif ($width <= 6000) {
                $roundBarQty = 2 * $quantity;
            } elseif ($width <= 9000) {
                $roundBarQty = 3 * $quantity;
            } elseif ($width <= 12000) {
                $roundBarQty = 4 * $quantity;
            } else {
                $roundBarQty = 0;
            }
        }

        // 1. 케이스 (단가/1000 × 길이mm × 수량)
        $casePrice = $this->priceService->getCasePrice($caseSpec);
        if ($casePrice > 0 && $caseLength > 0) {
            // 5130: round($shutter_price * $total_length * 1000) * $su → 단건 반올림 후 × QTY
            $perUnitPrice = round(($casePrice / 1000) * $caseLength);
            $items[] = [
                'category' => 'steel',
                'item_name' => '케이스',
                'specification' => "{$caseSpec} {$caseLength}mm",
                'unit' => 'm',
                'quantity' => $caseLength / 1000 * $quantity,
                'unit_price' => $casePrice,
                'total_price' => $perUnitPrice * $quantity,
            ];
        }

        // 2. 케이스용 연기차단재 - 5130: round(단가 × 길이m) × QTY
        $caseSmokePrice = $this->priceService->getCaseSmokeBlockPrice();
        if ($caseSmokePrice > 0 && $caseLength > 0) {
            $lengthM = $caseLength / 1000;
            $perUnitSmoke = round($caseSmokePrice * $lengthM);
            $items[] = [
                'category' => 'steel',
                'item_name' => '케이스용 연기차단재',
                'specification' => "{$lengthM}m",
                'unit' => 'm',
                'quantity' => $lengthM * $quantity,
                'unit_price' => $caseSmokePrice,
                'total_price' => $perUnitSmoke * $quantity,
            ];
        }

        // 3. 케이스 마구리 - 5130: round(단가 × QTY)
        $caseCapSpec = $this->convertToCaseCapSpec($caseSpec);
        $caseCapPrice = $this->priceService->getCaseCapPrice($caseCapSpec);
        if ($caseCapPrice > 0) {
            $capQty = $quantity;
            $items[] = [
                'category' => 'steel',
                'item_name' => '케이스 마구리',
                'specification' => $caseCapSpec,
                'unit' => 'EA',
                'quantity' => $capQty,
                'unit_price' => $caseCapPrice,
                'total_price' => round($caseCapPrice * $capQty),
            ];
        }

        // 4. 가이드레일 (단가 × 길이m × 수량) - 타입별 처리
        $guideItems = $this->calculateGuideRails($modelName, $finishingType, $guideType, $guideSpec, $guideLength, $quantity);
        $items = array_merge($items, $guideItems);

        // 5. 레일용 연기차단재 - 5130: round(단가 × 길이m) × multiplier × QTY
        $railSmokePrice = $this->priceService->getRailSmokeBlockPrice();
        if ($railSmokePrice > 0 && $guideLength > 0) {
            $railSmokeMultiplier = ($productType === 'slat') ? 1 : 2;
            $railSmokeQty = $railSmokeMultiplier * $quantity;
            $perUnitRailSmoke = round($railSmokePrice * $guideLength);
            $items[] = [
                'category' => 'steel',
                'item_name' => '레일용 연기차단재',
                'specification' => ($railSmokeMultiplier > 1) ? "{$guideLength}m × 2" : "{$guideLength}m",
                'unit' => 'm',
                'quantity' => $guideLength * $railSmokeQty,
                'unit_price' => $railSmokePrice,
                'total_price' => $perUnitRailSmoke * $railSmokeQty,
            ];
        }

        // 6. 하장바 (단가 × 길이m × 수량)
        $bottomBarPrice = $this->priceService->getBottomBarPrice($modelName, $finishingType);
        if ($bottomBarPrice > 0 && $bottomBarLength > 0) {
            $items[] = [
                'category' => 'steel',
                'item_name' => '하장바',
                'specification' => "{$modelName} {$finishingType} {$bottomBarLength}m",
                'unit' => 'm',
                'quantity' => $bottomBarLength * $quantity,
                'unit_price' => $bottomBarPrice,
                'total_price' => round($bottomBarPrice * $bottomBarLength * $quantity),
            ];
        }

        // 7. L바 (단가 × 길이m × 수량) - 스크린 전용, 슬랫 미사용
        $lbarPrice = ($productType !== 'slat') ? $this->priceService->getLBarPrice($modelName) : 0;
        if ($lbarPrice > 0 && $lbarLength > 0) {
            $items[] = [
                'category' => 'steel',
                'item_name' => 'L바',
                'specification' => "{$modelName} {$lbarLength}m",
                'unit' => 'm',
                'quantity' => $lbarLength * $quantity,
                'unit_price' => $lbarPrice,
                'total_price' => round($lbarPrice * $lbarLength * $quantity),
            ];
        }

        // 8. 보강평철 (단가 × 길이m × 수량) - 스크린 전용, 슬랫 미사용
        $flatBarPrice = ($productType !== 'slat') ? $this->priceService->getFlatBarPrice() : 0;
        if ($flatBarPrice > 0 && $flatBarLength > 0) {
            $items[] = [
                'category' => 'steel',
                'item_name' => '보강평철',
                'specification' => "{$flatBarLength}m",
                'unit' => 'm',
                'quantity' => $flatBarLength * $quantity,
                'unit_price' => $flatBarPrice,
                'total_price' => round($flatBarPrice * $flatBarLength * $quantity),
            ];
        }

        // 9. 무게평철12T (고정 12,000원 × 수량)
        if ($weightPlateQty > 0) {
            $weightPlatePrice = 12000;
            $items[] = [
                'category' => 'steel',
                'item_name' => '무게평철12T',
                'specification' => '12T',
                'unit' => 'EA',
                'quantity' => $weightPlateQty * $quantity,
                'unit_price' => $weightPlatePrice,
                'total_price' => $weightPlatePrice * $weightPlateQty * $quantity,
            ];
        }

        // 10. 환봉 (고정 2,000원 × 수량) - 스크린 전용, 슬랫 미사용
        if ($roundBarQty > 0 && $productType !== 'slat') {
            $roundBarPrice = 2000;
            $items[] = [
                'category' => 'steel',
                'item_name' => '환봉',
                'specification' => '',
                'unit' => 'EA',
                'quantity' => $roundBarQty,
                'unit_price' => $roundBarPrice,
                'total_price' => $roundBarPrice * $roundBarQty,
            ];
        }

        return $items;
    }

    /**
     * 가이드레일 계산 (타입별 처리)
     *
     * @param  string  $modelName  모델코드
     * @param  string  $finishingType  마감재질
     * @param  string  $guideType  가이드레일 타입 (벽면형, 측면형, 혼합형)
     * @param  string  $guideSpec  가이드레일 규격 (120*70, 120*100)
     * @param  float  $guideLength  가이드레일 길이 (m)
     * @param  int  $quantity  수량
     * @return array 가이드레일 항목 배열
     */
    /**
     * 모델별 가이드레일 규격 매핑
     *
     * BDmodels 테이블 기준:
     * KSS01/02, KSE01, KWE01 → 120*70 / 120*120
     * KTE01, KQTS01           → 130*75 / 130*125
     * KDSS01                  → 150*150 / 150*212
     */
    private function getGuideRailSpecs(string $modelName): array
    {
        return match ($modelName) {
            'KTE01', 'KQTS01' => ['wall' => '130*75', 'side' => '130*125'],
            'KDSS01' => ['wall' => '150*150', 'side' => '150*212'],
            default => ['wall' => '120*70', 'side' => '120*120'],
        };
    }

    private function calculateGuideRails(
        string $modelName,
        string $finishingType,
        string $guideType,
        string $guideSpec,
        float $guideLength,
        int $quantity
    ): array {
        $items = [];

        if ($guideLength <= 0) {
            return $items;
        }

        $specs = $this->getGuideRailSpecs($modelName);
        $wallSpec = $specs['wall'];
        $sideSpec = $specs['side'];

        // 5130: 세트가격(단가×2 또는 wall+side) → round(세트가격 × 길이m) × QTY
        switch ($guideType) {
            case '벽면형':
                $price = $this->priceService->getGuideRailPrice($modelName, $finishingType, $wallSpec);
                if ($price > 0) {
                    $setPrice = $price * 2;  // 5130: 2개 세트 가격
                    $perSetTotal = round($setPrice * $guideLength);
                    $items[] = [
                        'category' => 'steel',
                        'item_name' => '가이드레일',
                        'specification' => "{$modelName} {$finishingType} {$wallSpec} {$guideLength}m × 2",
                        'unit' => 'm',
                        'quantity' => $guideLength * 2 * $quantity,
                        'unit_price' => $price,
                        'total_price' => $perSetTotal * $quantity,
                    ];
                }
                break;

            case '측면형':
                $price = $this->priceService->getGuideRailPrice($modelName, $finishingType, $sideSpec);
                if ($price > 0) {
                    $setPrice = $price * 2;  // 5130: 2개 세트 가격
                    $perSetTotal = round($setPrice * $guideLength);
                    $items[] = [
                        'category' => 'steel',
                        'item_name' => '가이드레일',
                        'specification' => "{$modelName} {$finishingType} {$sideSpec} {$guideLength}m × 2",
                        'unit' => 'm',
                        'quantity' => $guideLength * 2 * $quantity,
                        'unit_price' => $price,
                        'total_price' => $perSetTotal * $quantity,
                    ];
                }
                break;

            case '혼합형':
                $priceWall = $this->priceService->getGuideRailPrice($modelName, $finishingType, $wallSpec);
                $priceSide = $this->priceService->getGuideRailPrice($modelName, $finishingType, $sideSpec);

                // 5130: (wallPrice + sidePrice) → round(합산가격 × 길이m) × QTY (단일 항목)
                $setPrice = ($priceWall ?: 0) + ($priceSide ?: 0);
                if ($setPrice > 0) {
                    $perSetTotal = round($setPrice * $guideLength);
                    $spec = "{$modelName} {$finishingType} {$wallSpec}/{$sideSpec} {$guideLength}m";
                    $items[] = [
                        'category' => 'steel',
                        'item_name' => '가이드레일',
                        'specification' => $spec,
                        'unit' => 'm',
                        'quantity' => $guideLength * 2 * $quantity,
                        'unit_price' => $setPrice,
                        'total_price' => $perSetTotal * $quantity,
                    ];
                }
                break;
        }

        return $items;
    }

    /**
     * 가이드타입 정규화 (5130 ↔ SAM 호환)
     *
     * 5130: '벽면', '측면', '혼합' (col6 필드)
     * SAM: '벽면형', '측면형', '혼합형' (switch case)
     */
    private function normalizeGuideType(string $type): string
    {
        return match ($type) {
            '벽면', '벽면형' => '벽면형',
            '측면', '측면형' => '측면형',
            '혼합', '혼합형' => '혼합형',
            default => $type,
        };
    }

    // =========================================================================
    // 부자재 계산 (3종)
    // =========================================================================

    /**
     * 부자재 항목 계산
     *
     * @param  array  $params  입력 파라미터
     * @return array 부자재 항목 배열
     */
    public function calculatePartItems(array $params): array
    {
        $items = [];

        $width = (float) ($params['W0'] ?? 0);
        $bracketInch = $params['bracket_inch'] ?? '5';
        $bracketSize = $params['BRACKET_SIZE'] ?? $this->calculateBracketSize(100, $bracketInch);
        $productType = $params['product_type'] ?? 'screen';
        $quantity = (int) ($params['QTY'] ?? 1);

        // 1. 감기샤프트 (5130: col59~65 고정 제품)
        // 5130 고정 규격: 3인치→0.3m, 4인치→3/4.5/6m, 5인치→6/7/8.2m
        $shaftSize = $bracketInch;
        $shaftLengthMm = ceil($width / 1000) * 1000;  // W0 → 올림 (mm)
        $shaftLength = $this->mapShaftToFixedProduct($shaftSize, $shaftLengthMm);
        $shaftPrice = $shaftLength > 0 ? $this->getShaftPrice($shaftSize, $shaftLength) : 0;
        if ($shaftPrice > 0) {
            $items[] = [
                'category' => 'parts',
                'item_name' => "감기샤프트 {$shaftSize}인치",
                'specification' => "{$shaftLength}m",
                'unit' => 'EA',
                'quantity' => $quantity,
                'unit_price' => $shaftPrice,
                'total_price' => $shaftPrice * $quantity,
            ];
        }

        // 2. 각파이프 (5130: col67 = col37 + 3000 × col66, col68/col69 자동계산)
        $pipeThickness = '1.4';
        $caseLength = (float) ($params['case_length'] ?? ($width + 220));  // col37 (mm)
        $connectionCount = (int) ($params['connection_count'] ?? 0);       // col66 (연결 수)
        $pipeBaseLength = $caseLength + 3000 * $connectionCount;           // col67

        // 5130 자동계산 공식: col67 기준
        $pipe3000Qty = (int) ($params['pipe_3000_qty'] ?? 0);
        $pipe6000Qty = (int) ($params['pipe_6000_qty'] ?? 0);

        if ($pipe3000Qty === 0 && $pipe6000Qty === 0) {
            // col68: 3000mm 파이프 수량
            if ($pipeBaseLength <= 9000) {
                $pipe3000Qty = 3 * $quantity;
            } elseif ($pipeBaseLength <= 12000) {
                $pipe3000Qty = 4 * $quantity;
            } elseif ($pipeBaseLength <= 15000) {
                $pipe3000Qty = 5 * $quantity;
            } elseif ($pipeBaseLength <= 18000) {
                $pipe3000Qty = 6 * $quantity;
            }

            // col69: 6000mm 파이프 수량 (18000 초과 시)
            if ($pipeBaseLength > 18000 && $pipeBaseLength <= 24000) {
                $pipe6000Qty = 4 * $quantity;
            } elseif ($pipeBaseLength > 24000 && $pipeBaseLength <= 30000) {
                $pipe6000Qty = 5 * $quantity;
            } elseif ($pipeBaseLength > 30000 && $pipeBaseLength <= 36000) {
                $pipe6000Qty = 6 * $quantity;
            } elseif ($pipeBaseLength > 36000 && $pipeBaseLength <= 42000) {
                $pipe6000Qty = 7 * $quantity;
            } elseif ($pipeBaseLength > 42000 && $pipeBaseLength <= 48000) {
                $pipe6000Qty = 8 * $quantity;
            }
        }

        if ($pipe3000Qty > 0) {
            $pipe3000Price = $this->getPipePrice($pipeThickness, 3000);
            if ($pipe3000Price > 0) {
                $items[] = [
                    'category' => 'parts',
                    'item_name' => '각파이프',
                    'specification' => "{$pipeThickness}T 3000mm",
                    'unit' => 'EA',
                    'quantity' => $pipe3000Qty,
                    'unit_price' => $pipe3000Price,
                    'total_price' => $pipe3000Price * $pipe3000Qty,
                ];
            }
        }
        if ($pipe6000Qty > 0) {
            $pipe6000Price = $this->getPipePrice($pipeThickness, 6000);
            if ($pipe6000Price > 0) {
                $items[] = [
                    'category' => 'parts',
                    'item_name' => '각파이프',
                    'specification' => "{$pipeThickness}T 6000mm",
                    'unit' => 'EA',
                    'quantity' => $pipe6000Qty,
                    'unit_price' => $pipe6000Price,
                    'total_price' => $pipe6000Price * $pipe6000Qty,
                ];
            }
        }

        // 3. 모터 받침용 앵글 (bracket angle)
        // 5130: calculateAngle(qty, itemList, '스크린용') → col2 검색, qty × $su × 4
        // 5130 슬랫: col23(앵글사이즈) 비어있으면 생략
        $motorCapacity = $params['MOTOR_CAPACITY'] ?? '300K';
        $bracketAngleEnabled = (bool) ($params['bracket_angle_enabled'] ?? ($productType !== 'slat'));
        if ($productType === 'screen') {
            $angleSearchOption = '스크린용';
        } else {
            // 철재/슬랫: bracketSize로 매핑
            $angleSearchOption = match ($bracketSize) {
                '530*320' => '철제300K',
                '600*350' => '철제400K',
                '690*390' => '철제800K',
                default => '철제300K',
            };
        }
        $anglePrice = $bracketAngleEnabled ? $this->getAnglePrice($angleSearchOption) : 0;
        if ($anglePrice > 0) {
            $angleQty = 4 * $quantity;  // 5130: $su * 4
            $items[] = [
                'category' => 'parts',
                'item_name' => '모터 받침용 앵글',
                'specification' => $angleSearchOption,
                'unit' => 'EA',
                'quantity' => $angleQty,
                'unit_price' => $anglePrice,
                'total_price' => $anglePrice * $angleQty,
            ];
        }

        // 4. 부자재 앵글 (main angle)
        // 스크린 5130: calculateMainAngle(1, $itemList, '앵글3T', '2.5') × col71
        // 슬랫 5130: calculateMainAngle(1, $itemList, '앵글4T', '2.5') × col77
        $mainAngleType = ($productType === 'slat') ? '앵글4T' : ($bracketSize === '690*390' ? '앵글4T' : '앵글3T');
        $mainAngleSize = '2.5';
        $mainAngleQty = (int) ($params['main_angle_qty'] ?? 2);  // col71/col77, default 2 (좌우)
        $mainAnglePrice = $this->getMainAnglePrice($mainAngleType, $mainAngleSize);
        if ($mainAnglePrice > 0 && $mainAngleQty > 0) {
            $items[] = [
                'category' => 'parts',
                'item_name' => "앵글 {$mainAngleType}",
                'specification' => "{$mainAngleSize}m",
                'unit' => 'EA',
                'quantity' => $mainAngleQty,
                'unit_price' => $mainAnglePrice,
                'total_price' => $mainAnglePrice * $mainAngleQty,
            ];
        }

        // 5. 조인트바 (슬랫 전용, 5130: price × col76, QTY 미적용)
        if ($productType === 'slat') {
            $jointBarQty = (int) ($params['joint_bar_qty'] ?? 0);
            if ($jointBarQty > 0) {
                $jointBarPrice = $this->getRawMaterialPrice('조인트바');
                if ($jointBarPrice > 0) {
                    $items[] = [
                        'category' => 'parts',
                        'item_name' => '조인트바',
                        'specification' => '',
                        'unit' => 'EA',
                        'quantity' => $jointBarQty,
                        'unit_price' => $jointBarPrice,
                        'total_price' => round($jointBarPrice * $jointBarQty),
                    ];
                }
            }
        }

        return $items;
    }

    // =========================================================================
    // 전체 동적 항목 계산
    // =========================================================================

    /**
     * 동적 항목 전체 계산
     *
     * @param  array  $inputs  입력 파라미터
     * @return array 계산된 항목 배열
     */
    public function calculateDynamicItems(array $inputs): array
    {
        $items = [];

        $width = (float) ($inputs['W0'] ?? 0);
        $height = (float) ($inputs['H0'] ?? 0);
        $quantity = (int) ($inputs['QTY'] ?? 1);
        $bracketInch = $inputs['bracket_inch'] ?? '5';
        $productType = $inputs['product_type'] ?? 'screen';

        // 중량 계산 (5130 로직) - 제품타입별 면적/중량 공식
        if ($productType === 'slat') {
            // 슬랫: W0 × (H0 + 50) / 1M, 중량 = 면적 × 25
            $area = ($width * ($height + 50)) / 1000000;
            $weight = $area * 25;
        } else {
            // 스크린/철재: W1 × (H1 + 550) / 1M
            $W1 = $width + 160;
            $H1 = $height + 350;
            $area = ($W1 * ($H1 + 550)) / 1000000;
            if ($productType === 'steel') {
                $weight = $area * 25;
            } else {
                $weight = $area * 2 + ($width / 1000) * 14.17;
            }
        }

        // 모터 용량/브라켓 크기 계산 (입력값 우선, 없으면 자동계산)
        $motorCapacity = $inputs['MOTOR_CAPACITY'] ?? $this->calculateMotorCapacity($productType, $weight, $bracketInch);
        $bracketSize = $inputs['BRACKET_SIZE'] ?? $this->calculateBracketSize($weight, $bracketInch);

        // 입력값에 계산된 값 추가 (부자재 계산용)
        $inputs['WEIGHT'] = $weight;
        $inputs['MOTOR_CAPACITY'] = $motorCapacity;
        $inputs['BRACKET_SIZE'] = $bracketSize;

        // 0. 검사비 (5130: inspectionFee × col14, 기본 50,000원)
        $inspectionFee = (int) ($inputs['inspection_fee'] ?? 50000);
        if ($inspectionFee > 0) {
            $items[] = [
                'category' => 'inspection',
                'item_code' => 'KD-INSPECTION',
                'item_name' => '검사비',
                'specification' => '',
                'unit' => 'EA',
                'quantity' => $quantity,
                'unit_price' => $inspectionFee,
                'total_price' => $inspectionFee * $quantity,
            ];
        }

        // 1. 주자재 (스크린 또는 슬랫)
        if ($productType === 'slat') {
            $materialResult = $this->calculateSlatPrice($width, $height);
            $materialName = '주자재(슬랫)';
            $materialCode = 'KD-SLAT';
        } else {
            $materialResult = $this->calculateScreenPrice($width, $height);
            $materialName = '주자재(스크린)';
            $materialCode = 'KD-SCREEN';
        }
        $items[] = [
            'category' => 'material',
            'item_code' => $materialCode,
            'item_name' => $materialName,
            'specification' => "면적 {$materialResult['area']}㎡",
            'unit' => '㎡',
            'quantity' => $materialResult['area'] * $quantity,
            'unit_price' => $materialResult['unit_price'],
            'total_price' => $materialResult['total_price'] * $quantity,
        ];

        // 2. 모터
        $motorPrice = $this->getMotorPrice($motorCapacity);
        $items[] = [
            'category' => 'motor',
            'item_code' => "KD-MOTOR-{$motorCapacity}",
            'item_name' => "모터 {$motorCapacity}",
            'specification' => $motorCapacity,
            'unit' => 'EA',
            'quantity' => $quantity,
            'unit_price' => $motorPrice,
            'total_price' => $motorPrice * $quantity,
        ];

        // 3. 제어기 (5130: 매립형×col15 + 노출형×col16 + 뒷박스×col17)
        // 5130: 제어기 = price_매립 × col15 + price_노출 × col16 + price_뒷박스 × col17
        // col15/col16/col17은 고정 수량 (QTY와 무관, $su를 곱하지 않음)
        $controllerType = $inputs['controller_type'] ?? '매립형';
        $controllerQty = (int) ($inputs['controller_qty'] ?? 1);
        $controllerPrice = $this->getControllerPrice($controllerType);
        if ($controllerPrice > 0 && $controllerQty > 0) {
            $items[] = [
                'category' => 'controller',
                'item_code' => 'KD-CTRL-'.strtoupper($controllerType),
                'item_name' => "제어기 {$controllerType}",
                'specification' => $controllerType,
                'unit' => 'EA',
                'quantity' => $controllerQty,
                'unit_price' => $controllerPrice,
                'total_price' => $controllerPrice * $controllerQty,
            ];
        }

        // 뒷박스 (5130: col17 수량, QTY와 무관)
        $backboxQty = (int) ($inputs['backbox_qty'] ?? 1);
        if ($backboxQty > 0) {
            $backboxPrice = $this->getControllerPrice('뒷박스');
            if ($backboxPrice > 0) {
                $items[] = [
                    'category' => 'controller',
                    'item_code' => 'KD-CTRL-BACKBOX',
                    'item_name' => '뒷박스',
                    'specification' => '',
                    'unit' => 'EA',
                    'quantity' => $backboxQty,
                    'unit_price' => $backboxPrice,
                    'total_price' => $backboxPrice * $backboxQty,
                ];
            }
        }

        // 4. 절곡품
        // installation_type → guide_type 매핑 (calculateSteelItems는 guide_type 사용)
        if (isset($inputs['installation_type']) && ! isset($inputs['guide_type'])) {
            $inputs['guide_type'] = $this->normalizeGuideType($inputs['installation_type']);
        }
        $steelItems = $this->calculateSteelItems($inputs);
        $items = array_merge($items, $steelItems);

        // 5. 부자재
        $partItems = $this->calculatePartItems($inputs);
        $items = array_merge($items, $partItems);

        return $items;
    }

    /**
     * 케이스 규격 → 마구리 규격 변환
     *
     * 레거시 updateCol45/Slat_updateCol46 공식:
     * 마구리 규격 = (케이스 가로 + 5) × (케이스 세로 + 5)
     * 예: 500*380 → 505*385
     */
    private function convertToCaseCapSpec(string $caseSpec): string
    {
        if (str_contains($caseSpec, '*')) {
            $parts = explode('*', $caseSpec);
            $width = (int) trim($parts[0]) + 5;
            $height = (int) trim($parts[1]) + 5;

            return "{$width}*{$height}";
        }

        return $caseSpec;
    }
}
