package incheon.ags.cms.history.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import incheon.ags.cms.admin.vo.RouteVO;
import incheon.ags.cms.download.service.ExcelDownloadService;
import incheon.ags.cms.history.service.HistoryService;
import incheon.ags.cms.history.mapper.HistoryMapper;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.psl.dataaccess.util.EgovMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service("historyService")
@RequiredArgsConstructor
public class HistoryServiceImpl implements HistoryService {

    private final HistoryMapper historyMapper;

    private final ExcelDownloadService excelDownloadService;

    @Override
    public List<EgovMap> selectVehiclesSummaryList(Map<String, Object> params) throws Exception {
        return historyMapper.selectVehiclesSummaryList(params);
    }

    @Override
    public int selectVehiclesSummaryTotalCount(Map<String, Object> params) throws Exception {
        return historyMapper.selectVehiclesSummaryTotalCount(params);
    }

    @Override
    public List<EgovMap> selectVehicleDailyRecordList(Map<String, Object> params) throws Exception {
        return historyMapper.selectVehicleDailyRecordList(params);
    }

    @Override
    public int selectVehicleDailyRecordTotalCount(Map<String, Object> params) throws Exception {
        return historyMapper.selectVehicleDailyRecordTotalCount(params);
    }
    @Autowired ObjectMapper objectMapper;

    @Override
    public JsonNode selectVehicleDrivePath(Map<String, Object> params) throws Exception {

        String strDrivePath = historyMapper.selectVehicleDrivePath(params);

        JsonNode drivePath = null;

        try {
            drivePath = objectMapper.readTree(strDrivePath);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return drivePath;
    }

    @Override
    public List<RouteVO> selectMappingRouteList(Map<String, Object> params) throws Exception {

        List<RouteVO> routeList = historyMapper.selectMappingRouteList(params);

        if (routeList != null && !routeList.isEmpty()) {
            for (RouteVO route : routeList) {
                if (route.getStrGeom() != null) {
                    try {
                        route.setGeom(objectMapper.readTree(route.getStrGeom()));
                        route.setStrGeom(null);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        return routeList;
    }


    @Override
    public ResponseEntity<Resource> excelDownloadVehiclesSummaryList(Map<String, Object> params) throws Exception {

        List<EgovMap> summary = historyMapper.selectVehiclesSummaryAllList(params);
        List<Map<String, Object>> data = summary.stream()
                .map(m -> {
                    Map<String, Object> row = (Map<String, Object>) m;

                    row.put("totWtspklSecnd", secondToTime((Integer) row.get("totWtspklSecnd")));
                    row.put("totWtspklDstnc", meterToKm((Integer) row.get("totWtspklDstnc")));

                    return row;
                })
                .collect(Collectors.toList());


        String fileName = "청소차량_차량별_통계_" + params.get("beginYmd") + "~" + params.get("endYmd");

        Map<String, String> columnMap = new LinkedHashMap<>();
        columnMap.put("rowNum", "번호");
        columnMap.put("vhrno", "차량번호");
        columnMap.put("clnTypeNm", "차량종류");
        columnMap.put("sggNm", "소속구");
        columnMap.put("totWtspklSecnd", "청소시간");
        columnMap.put("totWtspklDstnc", "청소거리(Km)");
        columnMap.put("totWtspklQty", "살수/흡입량(L)");
        columnMap.put("spdVltnCnt", "과속(회)");
        columnMap.put("raduVltnCnt", "경로이탈(회)");

        return excelDownloadService.downloadExcel(fileName, data, columnMap);
    }

    @Override
    public ResponseEntity<Resource> excelDownloadVehicleDailyRecordList(Map<String, Object> params) throws Exception {

        String vhrno = (String) params.get("vhrno");
        
        List<EgovMap> summary = historyMapper.selectVehicleDailyRecordAllList(params);
        List<Map<String, Object>> data = summary.stream()
                .map(m -> {
                    Map<String, Object> row = (Map<String, Object>) m;

                    row.put("vhrno", vhrno);
                    row.put("totWtspklSecnd", secondToTime((Integer) row.get("totWtspklSecnd")));
                    row.put("totWtspklDstnc", meterToKm((Integer) row.get("totWtspklDstnc")));

                    return row;
                })
                .collect(Collectors.toList());

        String fileName = "청소차량_운행일지_" + params.get("vhrno") + "_" + params.get("beginYmd") + "~" + params.get("endYmd");

        Map<String, String> columnMap = new LinkedHashMap<>();
        columnMap.put("rowNum", "번호");
        columnMap.put("oprYmd", "운행일자");
        columnMap.put("vhrno", "차량번호");
        columnMap.put("totWtspklSecnd", "청소시간");
        columnMap.put("totWtspklDstnc", "청소거리(Km)");
        columnMap.put("totWtspklQty", "살수/흡입량(L)");
        columnMap.put("spdVltnCnt", "과속(회)");
        columnMap.put("raduVltnCnt", "경로이탈(회)");
        columnMap.put("oprBgngDt", "출발시간");
        columnMap.put("oprEndDt", "도착시간");

        return excelDownloadService.downloadExcel(fileName, data, columnMap);
    }

    @Override
    public List<EgovMap> selectCleaningIncrsData(Map<String, Object> params) throws Exception {

        List<EgovMap> incrsData = historyMapper.selectCleaningIncrsData(params);
        incrsData.forEach(d -> {
            // 속도에 한자리 소수점 붙이기
            double spd = d.get("spd") != null ? (((int) d.get("spd")) / 10.0) : 0.0;
            d.put("spd", spd);
        });

        return incrsData;
    }


    private String secondToTime(Integer sec) {
        if (sec == null || sec <= 0) return null;

        int hours = sec / 3600;
        int minutes = (sec % 3600) / 60;
        int seconds = sec % 60;

        StringBuilder sb = new StringBuilder();

        if (0 < hours) sb.append(hours).append("시간 ");
        if (0 < minutes) sb.append(minutes).append("분 ");
        if (0 < seconds || sb.length() == 0) sb.append(seconds).append("초");

        return sb.toString().trim();
    }

    private Double meterToKm(Integer meter) {
        if (meter == null) return null;
        double km = meter / 1000.0;
        return Math.round(km * 10) / 10.0;  // 소수점 1자리까지
    }

    private String addComma(Integer num) {
        if (num == null) return null;

        String str = Integer.toString(num);
        StringBuilder sb = new StringBuilder();

        int count = 0;
        for (int i = str.length() - 1; i >= 0; i--) {
            sb.append(str.charAt(i));
            count++;
            if (count % 3 == 0 && i != 0) {
                sb.append(',');
            }
        }

        return sb.reverse().toString();
    }



}
