package com.zioinfo.mes.barcode;

import com.zioinfo.mes.common.ApiResponse;
import com.zioinfo.mes.common.AuthSupport;
import com.zioinfo.mes.inventory.mapper.InventoryMapper;
import com.zioinfo.mes.item.mapper.ItemMapper;
import com.zioinfo.mes.lotserial.mapper.LotSerialMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 바코드/QR API — 발번·검증·스캔 해석. 모바일 현장 스캔(입출고/이동/조회)에서 사용.
 *
 * <p>코드 규칙: {@code TYPE:VALUE} (예 ITEM:FG-1001, LOT:LOT-001, LOC:WH-MAIN/A-01-01).
 * 조회 Viewer+, 발번 Worker+.
 */
@RestController
@RequestMapping("/api/mes/barcode")
@RequiredArgsConstructor
public class BarcodeController {

    private final ItemMapper itemMapper;
    private final LotSerialMapper lotMapper;
    private final InventoryMapper inventoryMapper;

    /** 바코드 발번 — TYPE:VALUE 인코딩 문자열 반환. */
    @PostMapping("/generate")
    public ApiResponse<Map<String, Object>> generate(@RequestBody GenerateRequest req, Authentication auth) {
        AuthSupport.actor(auth);
        String type = req.type() == null ? "ITEM" : req.type().toUpperCase();
        if (req.value() == null || req.value().isBlank())
            throw new IllegalArgumentException("ERR-BC-400: value 필수");
        String code = type + ":" + req.value();
        Map<String, Object> m = new LinkedHashMap<>();
        m.put("type", type);
        m.put("value", req.value());
        m.put("code", code);
        return ApiResponse.ok(m);
    }

    /**
     * 스캔 해석 — TYPE:VALUE 를 파싱하고 대상 엔티티를 조회한다.
     * 모바일 입출고/이동/조회 진입점.
     */
    @GetMapping("/resolve")
    public ApiResponse<Map<String, Object>> resolve(@RequestParam String code) {
        Map<String, Object> m = new LinkedHashMap<>();
        if (code == null || code.isBlank())
            throw new IllegalArgumentException("ERR-BC-400: code 필수");
        String type, value;
        int idx = code.indexOf(':');
        if (idx > 0) {
            type = code.substring(0, idx).toUpperCase();
            value = code.substring(idx + 1);
        } else {
            // 접두사 없으면 품목 바코드/코드로 추정
            type = "ITEM";
            value = code;
        }
        m.put("type", type);
        m.put("value", value);
        switch (type) {
            case "ITEM" -> {
                var item = itemMapper.findByCode(value);
                if (item == null) item = itemMapper.findAll(null, null, value).stream().findFirst().orElse(null);
                m.put("found", item != null);
                m.put("item", item);
                if (item != null) m.put("stock", inventoryMapper.sumQty(item.getItemCode()));
            }
            case "LOT" -> {
                var lot = lotMapper.findByLot(value);
                m.put("found", lot != null);
                m.put("lot", lot);
            }
            case "LOC" -> {
                m.put("found", true);
                m.put("location", value);
            }
            default -> {
                m.put("found", false);
                m.put("message", "알 수 없는 코드 유형");
            }
        }
        return ApiResponse.ok(m);
    }

    record GenerateRequest(String type, String value) {}
}
