package com.zioinfo.mes.stocktake;

import com.zioinfo.mes.admin.AuditService;
import com.zioinfo.mes.inventory.InventoryService;
import com.zioinfo.mes.stocktake.mapper.StocktakeMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 재고실사 서비스 — 실사 카운트 기록(차이 계산) + 차이 조정(재고 보정).
 *
 * <p>count: 시스템 재고 대비 실사 수량 차이 기록(COUNTED).
 * adjust: 차이를 재고에 반영({@link InventoryService#adjust} ADJUST 수불) → ADJUSTED.
 */
@Service
@RequiredArgsConstructor
public class StocktakeService {

    private final StocktakeMapper mapper;
    private final InventoryService inventory;
    private final AuditService audit;

    public List<MesStocktake> list(String stocktakeNo, String status) {
        return mapper.findAll(stocktakeNo, status);
    }

    public MesStocktake get(Long id) {
        MesStocktake s = mapper.findById(id);
        if (s == null) throw new RuntimeException("ERR-STK-404: 실사 없음");
        return s;
    }

    /** 실사 카운트 기록 — 시스템 재고 조회 후 차이 계산. */
    @Transactional
    public MesStocktake count(MesStocktake s, String actor) {
        if (s.getItemCode() == null || s.getItemCode().isBlank())
            throw new IllegalArgumentException("ERR-STK-400: itemCode 필수");
        if (s.getCountedQty() == null)
            throw new IllegalArgumentException("ERR-STK-400: countedQty 필수");
        double systemQty = inventory.available(s.getItemCode());
        s.setSystemQty(systemQty);
        s.setDiffQty(s.getCountedQty() - systemQty);
        if (s.getStocktakeNo() == null || s.getStocktakeNo().isBlank())
            s.setStocktakeNo("STK-" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE));
        s.setStatus("COUNTED");
        s.setCreatedBy(actor);
        mapper.insert(s);
        audit.log("STOCKTAKE_COUNT", s.getStocktakeNo(),
            "item=" + s.getItemCode() + " diff=" + s.getDiffQty());
        return mapper.findById(s.getId());
    }

    /** 차이 조정 — 재고를 실사 수량으로 보정. */
    @Transactional
    public MesStocktake adjust(Long id, String actor) {
        MesStocktake s = get(id);
        if ("ADJUSTED".equals(s.getStatus()))
            throw new RuntimeException("ERR-STK-409: 이미 조정 반영됨");
        inventory.adjust(s.getItemCode(), s.getWarehouseCode(), s.getLocationCode(), s.getLotNo(),
            s.getCountedQty(), s.getStocktakeNo(), actor);
        mapper.updateStatus(id, "ADJUSTED");
        audit.log("STOCKTAKE_ADJUST", s.getStocktakeNo(), "item=" + s.getItemCode() + " → 재고보정");
        return mapper.findById(id);
    }
}
