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 java.util.*;

/**
 * Test Button Dataflow Service
 *
 * testButtonDataflowRoutes.ts 의 두 가지 추가 기능을 구현한다:
 *   1. getAllRelationships  — 버튼 제어용 전체 관계 목록
 *   2. getTestStatus        — 테스트 모드 상태 응답
 *
 * 나머지 엔드포인트는 ButtonDataflowController/Service 가 이미 처리한다.
 */
@Service
@Slf4j
public class TestButtonDataflowService extends BaseService {

    @Autowired
    private ObjectMapper objectMapper;

    // ══════════════════════════════════════════════════════════════
    // 전체 관계 목록 (버튼 제어용)
    // Node.js getAllRelationshipsForButtonControl 동일 로직
    // ══════════════════════════════════════════════════════════════

    /**
     * dataflow_diagrams 테이블에서 관계도를 조회하고,
     * 각 관계도의 relationships JSONB 에서 fromTable / toTable 정보를 추출하여
     * { id, name, sourceTable, targetTable, category } 목록으로 반환한다.
     */
    public List<Map<String, Object>> getAllRelationships(String companyCode) {
        log.info("전체 관계 목록 조회 - companyCode: {}", companyCode);

        Map<String, Object> params = new HashMap<>();
        params.put("company_code", companyCode);
        List<Map<String, Object>> diagrams = sqlSession.selectList("testButtonDataflow.selectDiagramsForRelationships", params);

        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> diagram : diagrams) {
            Map<String, Object> relationships = parseToMap(diagram.get("relationships"));

            String sourceTable = "";
            String targetTable = "";

            // relationships.fromTable.tableName
            Object fromTableRaw = relationships.get("from_table");
            if (fromTableRaw instanceof Map<?, ?> ft) {
                Object tn = ft.get("table_name");
                if (tn != null) sourceTable = tn.toString();
            }
            // relationships.toTable.tableName
            Object toTableRaw = relationships.get("to_table");
            if (toTableRaw instanceof Map<?, ?> tt) {
                Object tn = tt.get("table_name");
                if (tn != null) targetTable = tn.toString();
            }

            Object diagId   = diagram.get("diagram_id");
            Object diagName = diagram.get("diagram_name");

            Map<String, Object> entry = new LinkedHashMap<>();
            entry.put("id",          diagId != null ? diagId.toString() : "");
            entry.put("name",        diagName != null ? diagName.toString()
                    : "관계 " + (diagId != null ? diagId : ""));
            entry.put("source_table", sourceTable);
            entry.put("target_table", targetTable);
            entry.put("category",    "데이터 흐름");
            result.add(entry);
        }

        log.info("전체 관계 {}개 조회 완료", result.size());
        return result;
    }

    // ══════════════════════════════════════════════════════════════
    // 테스트 상태 응답
    // Node.js test-status 엔드포인트 동일 구조
    // ══════════════════════════════════════════════════════════════

    /**
     * Node.js 의 테스트 사용자 정보 + 환경 정보를 Spring 환경에 맞게 반환.
     */
    public Map<String, Object> getTestStatus(String companyCode) {
        Map<String, Object> user = new LinkedHashMap<>();
        user.put("user_id",      "spring-test-user");
        user.put("user_name",    "Spring Test User");
        user.put("company_code", companyCode);
        user.put("email",       "test@example.com");

        Map<String, Object> status = new LinkedHashMap<>();
        status.put("message",     "테스트 모드 활성화됨");
        status.put("user",        user);
        status.put("environment", "development");
        return status;
    }

    // ══════════════════════════════════════════════════════════════
    // Private helpers
    // ══════════════════════════════════════════════════════════════

    @SuppressWarnings("unchecked")
    private Map<String, Object> parseToMap(Object raw) {
        if (raw == null) return Collections.emptyMap();
        if (raw instanceof Map<?, ?>) return (Map<String, Object>) raw;
        try {
            return objectMapper.readValue(raw.toString(), Map.class);
        } catch (Exception e) {
            log.warn("JSON→Map 파싱 실패: {}", e.getMessage());
            return Collections.emptyMap();
        }
    }
}
