package com.zioinfo.kintex.auction;

import com.zioinfo.kintex.auction.dto.AuctionDtos.BoqLine;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * F035 BOQ 규칙 기반 물량 산출 단위테스트 — 면적·둘레·부스수·유틸리티 주문 기반 라인 산식 고정.
 */
class BoqCalcTest {

    @Test
    void computesRuleBasedLines_forSingleBooth() {
        // 12×9=108㎡, 둘레 42m, 높이 3.5m, 유틸리티 1건.
        List<BoqLine> lines = BoqCalc.compute(108.0, 42.0, 1, 3.5, 1);
        assertEquals(6, lines.size()); // 구조2 + 바닥1 + 조명1 + 전기1 + 설비1(유틸)

        assertEquals("구조", lines.get(0).trade());
        assertEquals(108L, lines.get(0).qty());                 // 골조 = 바닥면적
        assertEquals(Math.round(42.0 * 3.5), lines.get(1).qty()); // 벽체 = 둘레×높이 = 147
        assertEquals(108L, lines.get(2).qty());                 // 바닥 = 바닥면적
        assertEquals(12L, lines.get(3).qty());                  // 조명 = ceil(108/9) = 12
        assertEquals(1L, lines.get(4).qty());                   // 전기 = 부스 1실
        assertEquals("설비", lines.get(5).trade());
        assertEquals(1L, lines.get(5).qty());                   // 설비 = 유틸리티 1건
    }

    @Test
    void lightingRoundsUp() {
        // 100㎡ → ceil(100/9)=12
        List<BoqLine> lines = BoqCalc.compute(100.0, 40.0, 1, 3.5, 0);
        assertEquals(12L, lines.get(3).qty());
    }

    @Test
    void omitsUtilityLineWhenNoOrders() {
        List<BoqLine> lines = BoqCalc.compute(108.0, 42.0, 1, 3.5, 0);
        assertEquals(5, lines.size());
        assertTrue(lines.stream().noneMatch(l -> "설비".equals(l.trade())));
    }

    @Test
    void estimatesPerimeterWhenMissing() {
        // 둘레 0 → 정사각형 근사 4√100 = 40, 벽체 = round(40×3.5) = 140
        List<BoqLine> lines = BoqCalc.compute(100.0, 0.0, 2, 3.5, 0);
        assertEquals(140L, lines.get(1).qty());
        assertTrue(lines.get(1).basis().contains("근사"));
        assertEquals(2L, lines.get(4).qty()); // 전기 = 부스 2실
    }

    @Test
    void usesDefaultHeightWhenMissing() {
        // 높이 0 → 3.5 기본. 벽체 = round(40×3.5)=140
        List<BoqLine> lines = BoqCalc.compute(100.0, 40.0, 1, 0.0, 0);
        assertEquals(Math.round(40.0 * BoqCalc.DEFAULT_HEIGHT_M), lines.get(1).qty());
    }

    @Test
    void emptyWhenNoBoothsOrZeroArea() {
        assertTrue(BoqCalc.compute(0.0, 0.0, 0, 0.0, 0).isEmpty());
        assertTrue(BoqCalc.compute(100.0, 40.0, 0, 3.5, 0).isEmpty()); // boothCount 0
        assertTrue(BoqCalc.compute(0.0, 40.0, 1, 3.5, 0).isEmpty());   // area 0
    }
}
