package com.zioinfo.mes.equipment;

import com.zioinfo.mes.admin.AuditService;
import com.zioinfo.mes.ai.AiService;
import com.zioinfo.mes.common.ApiResponse;
import com.zioinfo.mes.common.AuthSupport;
import com.zioinfo.mes.equipment.mapper.EquipmentMapper;
import com.zioinfo.mes.integration.ItsmClient;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 설비 마스터 API + 예지보전(AI) + 비가동→ITSM SR 연계.
 * 조회 Viewer+, 기준정보 변경 Manager+, 상태변경 Worker+.
 */
@RestController
@RequestMapping("/api/mes/equipment")
@RequiredArgsConstructor
public class EquipmentController {

    private final EquipmentMapper mapper;
    private final AuditService audit;
    private final AiService ai;
    private final ItsmClient itsm;

    @GetMapping
    public ApiResponse<List<MesEquipment>> list(@RequestParam(required = false) String status,
                                                @RequestParam(required = false) String runStatus) {
        return ApiResponse.ok(mapper.findAll(status, runStatus));
    }

    @GetMapping("/{id}")
    public ApiResponse<MesEquipment> get(@PathVariable Long id) {
        return ApiResponse.ok(require(id));
    }

    @PostMapping
    public ApiResponse<MesEquipment> create(@RequestBody MesEquipment e, Authentication auth) {
        AuthSupport.requireManager(auth);
        if (e.getEquipmentCode() == null) throw new IllegalArgumentException("ERR-EQP-400: equipmentCode 필수");
        if (mapper.countByCode(e.getEquipmentCode(), null) > 0)
            throw new RuntimeException("ERR-EQP-409: 중복 설비코드");
        if (e.getStatus() == null) e.setStatus("ACTIVE");
        if (e.getRunStatus() == null) e.setRunStatus("IDLE");
        e.setCreatedBy(AuthSupport.actor(auth));
        mapper.insert(e);
        audit.log("EQUIPMENT_CREATE", e.getEquipmentCode(), "");
        return ApiResponse.ok(mapper.findById(e.getId()));
    }

    @PutMapping("/{id}")
    public ApiResponse<MesEquipment> update(@PathVariable Long id, @RequestBody MesEquipment e, Authentication auth) {
        AuthSupport.requireManager(auth);
        require(id);
        e.setId(id);
        mapper.update(e);
        audit.log("EQUIPMENT_UPDATE", e.getEquipmentCode(), "id=" + id);
        return ApiResponse.ok(mapper.findById(id));
    }

    /** 가동상태 변경(RUN/IDLE/DOWN/MAINT) — DOWN 시 ITSM SR 자동 생성. Worker+. */
    @PutMapping("/{id}/run-status")
    public ApiResponse<MesEquipment> runStatus(@PathVariable Long id, @RequestBody RunStatusRequest req) {
        MesEquipment e = require(id);
        mapper.updateRunStatus(id, req.runStatus());
        audit.log("EQUIPMENT_RUNSTATUS", e.getEquipmentCode(), "-> " + req.runStatus());
        if ("DOWN".equalsIgnoreCase(req.runStatus())) {
            String srId = itsm.createSr(
                "[MES] 설비 비가동: " + e.getEquipmentName(),
                "설비 " + e.getEquipmentCode() + " DOWN 발생. 사유: " + (req.reason() == null ? "미입력" : req.reason()),
                "HIGH");
            audit.log("EQUIPMENT_DOWN_SR", e.getEquipmentCode(), "srId=" + srId);
        }
        return ApiResponse.ok(mapper.findById(id));
    }

    /** 설비 예지보전 분석(AI). */
    @PostMapping("/{id}/predictive-maintenance")
    public ApiResponse<Map<String, Object>> pdm(@PathVariable Long id, @RequestBody PdmRequest req) {
        MesEquipment e = require(id);
        return ApiResponse.ok(ai.predictiveMaintenance(
            e.getEquipmentCode(), req.availability(), req.downtimeCount(), req.mtbfHours()));
    }

    @DeleteMapping("/{id}")
    public ApiResponse<Void> delete(@PathVariable Long id, Authentication auth) {
        AuthSupport.requireManager(auth);
        mapper.delete(id);
        audit.log("EQUIPMENT_DELETE", String.valueOf(id), "");
        return ApiResponse.ok(null);
    }

    private MesEquipment require(Long id) {
        MesEquipment e = mapper.findById(id);
        if (e == null) throw new RuntimeException("ERR-EQP-404: 설비 없음");
        return e;
    }

    record RunStatusRequest(String runStatus, String reason) {}
    record PdmRequest(double availability, int downtimeCount, double mtbfHours) {}
}
