package com.erp.service;

import com.erp.common.BaseService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Slf4j
public class BusinessRuleService extends BaseService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private ObjectMapper objectMapper;

    private static final String NS = "businessRule.";

    public Map<String, Object> getBusinessRuleList(Map<String, Object> params) {
        commonService.applyPagination(params);
        int totalCount = sqlSession.selectOne(NS + "getBusinessRuleListCnt", params);
        List<Map<String, Object>> list = sqlSession.selectList(NS + "getBusinessRuleList", params);
        return commonService.buildListResponse(list, totalCount, params);
    }

    public Map<String, Object> getBusinessRuleInfo(Map<String, Object> params) {
        Map<String, Object> row = sqlSession.selectOne(NS + "getBusinessRuleInfo", params);
        if (row != null) {
            parseJsonField(row, "nodes");
            parseJsonField(row, "connections");
        }
        return row;
    }

    @Transactional
    public Map<String, Object> insertBusinessRule(Map<String, Object> params) {
        String ruleId = "rule_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12);
        params.put("rule_id", ruleId);
        stringifyJsonField(params, "nodes");
        stringifyJsonField(params, "connections");
        sqlSession.insert(NS + "insertBusinessRule", params);
        return Map.of("rule_id", ruleId);
    }

    @Transactional
    public void updateBusinessRule(Map<String, Object> params) {
        stringifyJsonField(params, "nodes");
        stringifyJsonField(params, "connections");
        sqlSession.update(NS + "updateBusinessRule", params);
    }

    @Transactional
    public int deleteBusinessRule(Map<String, Object> params) {
        return sqlSession.update(NS + "deleteBusinessRule", params);
    }

    @Transactional
    public void toggleBusinessRule(Map<String, Object> params) {
        sqlSession.update(NS + "toggleBusinessRule", params);
    }

    // ── JSONB 유틸 ──

    private void parseJsonField(Map<String, Object> row, String key) {
        Object val = row.get(key);
        if (val instanceof String) {
            try {
                row.put(key, objectMapper.readValue((String) val, Object.class));
            } catch (Exception e) {
                log.warn("Failed to parse JSONB field '{}': {}", key, e.getMessage());
            }
        }
    }

    private void stringifyJsonField(Map<String, Object> params, String key) {
        Object val = params.get(key);
        if (val != null && !(val instanceof String)) {
            try {
                params.put(key, objectMapper.writeValueAsString(val));
            } catch (Exception e) {
                log.warn("Failed to stringify field '{}': {}", key, e.getMessage());
                params.put(key, "[]");
            }
        }
        if (val == null) {
            params.put(key, "[]");
        }
    }
}
