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 TemplateService extends BaseService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private ObjectMapper objectMapper;

    private static final String NS = "template.";

    // ──────────────────────────────────────────────────
    // 목록
    // ──────────────────────────────────────────────────

    public Map<String, Object> getTemplateList(Map<String, Object> params) {
        commonService.applyPagination(params);
        int totalCount = sqlSession.selectOne(NS + "getTemplateListCnt", params);
        List<Map<String, Object>> list = sqlSession.selectList(NS + "getTemplateList", params);
        for (Map<String, Object> row : list) {
            parseJsonField(row, "views");
        }
        return commonService.buildListResponse(list, totalCount, params);
    }

    // ──────────────────────────────────────────────────
    // 단건
    // ──────────────────────────────────────────────────

    public Map<String, Object> getTemplateInfo(Map<String, Object> params) {
        Map<String, Object> row = sqlSession.selectOne(NS + "getTemplateInfo", params);
        if (row == null) return null;

        // JSONB 문자열 → 객체 변환
        parseJsonField(row, "fields");
        parseJsonField(row, "views");
        parseJsonField(row, "connections");

        return row;
    }

    // ──────────────────────────────────────────────────
    // 등록
    // ──────────────────────────────────────────────────

    @Transactional
    public Map<String, Object> insertTemplate(Map<String, Object> params) {
        String templateId = "tpl_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12);
        params.put("template_id", templateId);

        // 객체 → JSON 문자열 변환
        stringifyJsonField(params, "fields");
        stringifyJsonField(params, "views");
        stringifyJsonField(params, "connections");

        sqlSession.insert(NS + "insertTemplate", params);

        Map<String, Object> result = new HashMap<>();
        result.put("template_id", templateId);
        return result;
    }

    // ──────────────────────────────────────────────────
    // 수정
    // ──────────────────────────────────────────────────

    @Transactional
    public void updateTemplate(Map<String, Object> params) {
        stringifyJsonField(params, "fields");
        stringifyJsonField(params, "views");
        stringifyJsonField(params, "connections");

        sqlSession.update(NS + "updateTemplate", params);
    }

    // ──────────────────────────────────────────────────
    // 게시
    // ──────────────────────────────────────────────────

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

    // ──────────────────────────────────────────────────
    // 삭제 (소프트)
    // ──────────────────────────────────────────────────

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

    // ──────────────────────────────────────────────────
    // JSON 유틸
    // ──────────────────────────────────────────────────

    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("JSON 파싱 실패: key={}, value={}", key, val, e);
            }
        }
    }

    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("JSON 직렬화 실패: key={}", key, e);
                params.put(key, "[]");
            }
        }
    }
}
