package com.erp.service;

import com.erp.common.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommonService extends BaseService {

    private static final String NS = "common.";

    /**
     * company_code 필터 적용: SUPER_ADMIN("*")은 전체 조회, 나머지는 자사 데이터만
     */
    public void applyCompanyCodeFilter(Map<String, Object> params) {
        String companyCode = (String) params.get("company_code");
        if ("*".equals(companyCode)) {
            params.put("company_code", "*");
        }
    }

    /**
     * 페이지네이션 파라미터 정규화
     */
    public void applyPagination(Map<String, Object> params) {
        Object limitObj = params.get("limit");
        Object pageObj = params.get("page");

        if (limitObj != null) {
            int limit = Integer.parseInt(limitObj.toString());
            int page = pageObj != null ? Integer.parseInt(pageObj.toString()) : 1;
            int offset = (page - 1) * limit;
            params.put("limit", limit);
            params.put("offset", offset);
        }
    }

    /**
     * 리스트 응답 빌드: list, totalCount, pagination 정보를 포함한 Map 반환
     */
    public Map<String, Object> buildListResponse(List<Map<String, Object>> list, int totalCount, Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        result.put("list", list);
        result.put("total_count", totalCount);
        Object limitObj = params.get("limit");
        Object pageObj = params.get("page");
        if (limitObj != null) {
            int limit = Integer.parseInt(limitObj.toString());
            int page = pageObj != null ? Integer.parseInt(pageObj.toString()) : 1;
            result.put("limit", limit);
            result.put("page", page);
            result.put("total_page", (int) Math.ceil((double) totalCount / limit));
        }
        return result;
    }

    /**
     * Map의 snake_case 키를 camelCase로 변환
     * DB 결과를 프론트에 내려줄 때 사용
     */
    public Map<String, Object> toCamelCaseKeys(Map<String, Object> row) {
        if (row == null) return null;
        Map<String, Object> result = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : row.entrySet()) {
            result.put(snakeToCamel(entry.getKey()), entry.getValue());
        }
        return result;
    }

    public List<Map<String, Object>> toCamelCaseKeysList(List<Map<String, Object>> list) {
        if (list == null) return null;
        return list.stream().map(this::toCamelCaseKeys).collect(Collectors.toList());
    }

    private String snakeToCamel(String name) {
        if (name == null || !name.contains("_")) return name;
        StringBuilder sb = new StringBuilder();
        boolean nextUpper = false;
        for (char c : name.toCharArray()) {
            if (c == '_') { nextUpper = true; }
            else { sb.append(nextUpper ? Character.toUpperCase(c) : c); nextUpper = false; }
        }
        return sb.toString();
    }

    /**
     * 공통 코드 목록 조회
     */
    public List<Map<String, Object>> getCodeList(Map<String, Object> params) {
        applyCompanyCodeFilter(params);
        return sqlSession.selectList(NS + "selectCodeList", params);
    }
}
