package incheon.sgp.rst.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.springframework.stereotype.Service;


import incheon.sgp.rst.mapper.RstVoluMapper;
import incheon.sgp.rst.service.RstVoluService;

/**
 * @ClassName : RstVoluServiceImpl.java
 * @Description : 부동산 시장동향 통계 서비스 구현체
 * @author : 이주훈
 * @since : 2025.10.27
 * @version : 1.0
 */
@Service
public class RstVoluServiceImpl  implements RstVoluService {

	// 매퍼 주입
    private final RstVoluMapper rstVoluMapper; 

    // 매퍼 생성자 주입
    public RstVoluServiceImpl(RstVoluMapper rstVoluMapper) {
        this.rstVoluMapper = rstVoluMapper;
    }

    @Override
    public Map<String, Object> getSalesVolume(String crtrYm, String sttySggCd) throws Exception {
        return getTradeVolume(crtrYm, sttySggCd, "1"); // 매매
    }

    @Override
    public Map<String, Object> getRentalVolume(String crtrYm, String sttySggCd) throws Exception {
        return getTradeVolume(crtrYm, sttySggCd, "2"); // 전월세
    }
    
    /**
     * 인천광역시 주택 거래량 조회 (공통 모듈화)
     */
    public Map<String, Object> getTradeVolume(String crtrYm, String sttySggCd, String ctrtMthdCd) throws Exception {
    	// 전월
        String prevYm = getPrevYm(crtrYm);
        // 전년동월
        String lastYearYm = getLastYearYm(crtrYm);
        
        System.out.println("crtrYm : " + crtrYm);
        System.out.println("sttySggCd : " + sttySggCd);
        System.out.println("ctrtMthdCd : " + ctrtMthdCd);

        // 주택 거래량 파라미터 map 세팅
        Map<String, Object> param = new HashMap<>();
        param.put("sttySggCd", sttySggCd);			// 시군구코드
        param.put("ctrtMthdCd", ctrtMthdCd); 		// 매매(1) OR 전월세(2) 

        // 현재월 데이터 조회
        Map<String, Object> currentParam = new HashMap<>(param);
        currentParam.put("crtrYm", crtrYm);
        int currentCount = rstVoluMapper.selectTradeVolume(currentParam);

        // 전월 데이터 조회
        Map<String, Object> prevParam = new HashMap<>(param);
        prevParam.put("crtrYm", prevYm);
        int prevMonthCount = 0;
        if (prevYm != null && !prevYm.isEmpty()) {
            prevMonthCount = rstVoluMapper.selectTradeVolume(prevParam);
            System.out.println("prevMonthCount : " + prevMonthCount);
        }

        // 전년동월 데이터 조회
        Map<String, Object> lastYearParam = new HashMap<>(param);
        lastYearParam.put("crtrYm", lastYearYm);
        int lastYearCount = 0;
        if (lastYearYm != null && !lastYearYm.isEmpty()) {
            lastYearCount = rstVoluMapper.selectTradeVolume(lastYearParam);
            System.out.println("lastYearCount : " + lastYearCount);
        }

    	Double prevMonthRate = null;
    	Double lastYearRate = null;
    	// 전월대비 증감율 계산
    	if (prevMonthCount > 0) {
    		prevMonthRate = Math.round(((double)(currentCount - prevMonthCount) / prevMonthCount) * 1000) / 10.0;
    	    System.out.println("PrevMonthRate : " + prevMonthRate);
    	}
    	// 전년동월대비 증감율 계산
    	if (lastYearCount > 0) {
    		lastYearRate = Math.round(((double)(currentCount - lastYearCount) / lastYearCount) * 1000) / 10.0;
    	    System.out.println("LastYearRate : " + lastYearRate);
    	}
        
        // 그래프 공통 파라미터 map 세팅
        Map<String, Object> trendParam = new HashMap<>();
        trendParam.put("crtrYm", crtrYm);
        trendParam.put("sttySggCd", sttySggCd);
        trendParam.put("ctrtMthdCd", ctrtMthdCd); 		// 매매(1) OR 전월세(2) 
        
        // 월별 주택거래량 데이터 조회
        List<Map<String, Object>> monthlyTrend = rstVoluMapper.selectMonthlyTradeTrend(trendParam);
        
        int size = monthlyTrend.size();
        int[] monthlyTrendList = new int[size];
        List<String> monthLabels = new ArrayList<>();
        
        // 13개월치 - 월 / 거래량
        int i = 0;
        for (Map<String, Object> row : monthlyTrend) {
            System.out.println("monthlyTrend row = " + row);

            String ym = row.get("crtrYm").toString();
            String label = ym.substring(2, 4) + "." + ym.substring(4, 6); // 202508 → 25.08

            int total = ((Number) row.getOrDefault("totalCount", 0)).intValue();

            monthlyTrendList[i] = total;
            monthLabels.add(label);
            i++;
        }
        
        // 주택유형별 코드 세팅
        List<String[]> typeList = List.of(
        	new String[]{"1", "아파트"},
        	new String[]{"2", "연립주택"},
        	new String[]{"3", "다세대주택"},
            new String[]{"4", "단독주택"},
            new String[]{"5", "다가구주택"}
        );
        
        // 연월
        List<String> ymList = new ArrayList<>();
        for (Map<String, Object> row : monthlyTrend) {
            ymList.add(row.get("crtrYm").toString());
        }

        // 결과를 담을 Map 초기화
        Map<String, List<Integer>> trendTypeData = new HashMap<>();
        for (String[] type : typeList) {
        	trendTypeData.put(type[1], new ArrayList<>());  
        }

        // 주택유형별 반복 쿼리 실행
        for (String[] type : typeList) {
            String hsTypeSeCd = type[0];
            String typeNm = type[1];

            trendParam.put("hsTypeSeCd", hsTypeSeCd);
            List<Map<String, Object>> resultList = rstVoluMapper.selectMonthlyTradeTrendByType(trendParam);

            for (String ym : ymList) {
                int total = 0;
                for (Map<String, Object> row : resultList) {
                    if (ym.equals(row.get("crtrYm").toString())) {
                        total = ((Number) row.get("totalCount")).intValue();
                        break;
                    }
                }
                trendTypeData.get(typeNm).add(total);
            }
        }
        
        // 리턴 Map 구성
        Map<String, Object> result = new HashMap<>();
        result.put("crtrYm", crtrYm);
        result.put("prevYm", prevYm);
        result.put("lastYearYm", lastYearYm);
        result.put("currentCount", currentCount);
        result.put("prevMonthCount", prevMonthCount);
        result.put("lastYearCount", lastYearCount);
        result.put("prevMonthRate", prevMonthRate);
        result.put("lastYearRate", lastYearRate);
        result.put("monthLabels", monthLabels);
        result.put("typeList", typeList.stream().map(t -> t[1]).toList());
        
        if ("1".equals(String.valueOf(ctrtMthdCd))) {
        	result.put("monthlySalesList", monthlyTrendList);
            result.put("salesTypeData", trendTypeData);
        } else if ("2".equals(String.valueOf(ctrtMthdCd))) {
        	result.put("monthlyRentalList", monthlyTrendList);
            result.put("rentalTypeData", trendTypeData);
        }
        return result;
    }
    
    /*
     * 기준연월 유틸 계산
     * */
    // 전월 계산
    private String getPrevYm(String crtrYm) { 
    	if (crtrYm == null || crtrYm.trim().length() < 6) {
            return "";
        }
        int year = Integer.parseInt(crtrYm.substring(0, 4));
        int month = Integer.parseInt(crtrYm.substring(4, 6));
        
    	// 최초 연월 (200601) → 전월 비교 불가
        if (year == 2006 && month == 1) {return "";}
        if (month == 1) {
        	year -= 1; month = 12; 
        }else { 
        	month -= 1;
        }
        if (year < 2006) {return "";}
        System.out.println("year : " + year + " month : " + month);
        return String.format("%04d%02d", year, month);
    }

    // 전년동월 계산 
    private String getLastYearYm(String crtrYm) {
    	if (crtrYm == null || crtrYm.trim().length() < 6) {
            return "";
        }
        int year = Integer.parseInt(crtrYm.substring(0, 4));
        int month = Integer.parseInt(crtrYm.substring(4, 6));
        
        // 최초 연월 (200601) → 전월 비교 불가
        if (year == 2006) {return "";}
        year -= 1;
        if (year < 2006) {return "";}
        System.out.println("year : " + year + " month : " + month);
        return String.format("%04d%02d", year, month);
    }

    /*
     * 최신 기준연월 조회
     * */
    @Override
    public Map<String, Object> getCrtrYmRange() throws Exception {
    	System.out.println("getCrtrYmRange() 실행");
        return rstVoluMapper.getCrtrYmRange();
    }
    
    /*
     * 지도용 군구별 거래량 조회 (매매/전월세)
     * */
    @Override
    public Map<String, Object> selectRegionTradeVolume(String crtrYm) throws Exception {
        Map<String, Object> result = new HashMap<>();

        // 매매(1)
        Map<String, Object> salesParam = new HashMap<>();
        salesParam.put("crtrYm", crtrYm);
        salesParam.put("ctrtMthdCd", "1");

        List<Map<String, Object>> salesList = rstVoluMapper.selectRegionTradeVolume(salesParam);

        // 전월세(2)
        Map<String, Object> rentalParam = new HashMap<>();
        rentalParam.put("crtrYm", crtrYm);
        rentalParam.put("ctrtMthdCd", "2");

        List<Map<String, Object>> rentalList = rstVoluMapper.selectRegionTradeVolume(rentalParam);


        result.put("salesList", salesList);
        result.put("rentalList", rentalList);

        return result;
    }

}
