package com.zioinfo.kintex.module.m2;

import com.zioinfo.kintex.auth.EventAccessGuard;
import com.zioinfo.kintex.auth.KintexPrincipal;
import com.zioinfo.kintex.common.ApiResponse;
import com.zioinfo.kintex.module.m2.dto.HallTreeDto;
import com.zioinfo.kintex.module.m2.mapper.HallMapper;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 평면도 선택 트리 API — 대분류(전시장) > 중분류(홀) > 소분류(구역).
 * 로그인 사용자 조회 가능(홀 마스터는 비밀 아님 — 자격증명·PII 없음). 데이터 원천: hall + hall_zone(V60).
 */
@RestController
@RequestMapping("/api/halls/tree")
public class HallTreeController {

    private final HallMapper hallMapper;
    private final EventAccessGuard guard;

    public HallTreeController(HallMapper hallMapper, EventAccessGuard guard) {
        this.hallMapper = hallMapper;
        this.guard = guard;
    }

    @GetMapping
    public ApiResponse<HallTreeDto> tree(@AuthenticationPrincipal KintexPrincipal principal) {
        guard.require(principal);

        // 구역을 홀별로 그룹핑
        Map<String, List<HallTreeDto.ZoneNode>> zonesByHall = new LinkedHashMap<>();
        for (Map<String, Object> z : hallMapper.findAllZones()) {
            zonesByHall.computeIfAbsent(str(z.get("hallId")), k -> new ArrayList<>())
                    .add(new HallTreeDto.ZoneNode(str(z.get("zoneId")), str(z.get("label"))));
        }

        // 홀을 전시장(대분류)별로 그룹핑
        Map<Integer, List<HallTreeDto.HallNode>> hallsByCenter = new LinkedHashMap<>();
        for (Map<String, Object> h : hallMapper.findAllHalls()) {
            String hallId = str(h.get("hallId"));
            int center = ((Number) h.get("center")).intValue();
            List<Double> dims = h.get("widthM") == null || h.get("depthM") == null
                    ? List.of()
                    : List.of(((Number) h.get("widthM")).doubleValue(), ((Number) h.get("depthM")).doubleValue());
            hallsByCenter.computeIfAbsent(center, k -> new ArrayList<>())
                    .add(new HallTreeDto.HallNode(hallId, str(h.get("label")), dims,
                            zonesByHall.getOrDefault(hallId, List.of())));
        }

        List<HallTreeDto.Center> centers = hallsByCenter.entrySet().stream()
                .map(e -> new HallTreeDto.Center(e.getKey(), "제" + e.getKey() + "전시장", e.getValue()))
                .toList();
        return ApiResponse.ok(new HallTreeDto(centers));
    }

    private static String str(Object o) {
        return o == null ? null : String.valueOf(o);
    }
}
