package com.eactive.ext.kjb.statistics;

import java.io.IOException;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import com.eactive.eai.rms.common.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsMonth;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsMonthService;
import com.eactive.ext.kjb.statistics.mapping.ApiStatsUIMapper;
import com.eactive.ext.kjb.statistics.service.ApiStatsExcelExportService;
import com.eactive.ext.kjb.statistics.ui.ApiStatsChartUI;
import com.eactive.ext.kjb.statistics.ui.ApiStatsSearch;
import com.eactive.ext.kjb.statistics.ui.ApiStatsUI;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@RequiredArgsConstructor
public class ApiStatsMonthController {

	private final ApiStatsMonthService service;
	private final ApiStatsUIMapper mapper;
	private final ApiStatsExcelExportService excelExportService;

	@GetMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.view")
	public String view() {
		return "/onl/kjb/statistics/apiStatsMonthMan";
	}

	@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<ApiStatsUI>> selectList(ApiStatsSearch search, Pageable pageable) {
		Pageable sortedPageable = PageRequest.of(
				pageable.getPageNumber(),
				pageable.getPageSize(),
				Sort.by(Sort.Order.desc("statTime")));

		Page<ApiStatsMonth> page = service.selectList(search, sortedPageable);
		Page<ApiStatsUI> uiPage = page.map(mapper::toVo);

		return ResponseEntity.ok(new GridResponse<>(uiPage));
	}

	@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=CHART")
	public ResponseEntity<List<ApiStatsChartUI>> selectChartData(ApiStatsSearch search) {
		List<ApiStatsChartUI> chartData = service.selectChartData(search);
		return ResponseEntity.ok(chartData);
	}

	@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=LIST_SUMMARY")
	public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
		Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
		return ResponseEntity.ok(new GridResponse<>(page));
	}

	@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=EXCEL_EXPORT")
	public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
		log.info("Excel export started - search: {}", search);

		try {
			List<ApiStatsMonth> dataList = service.selectListForExcel(search);
			log.info("Data retrieved - count: {}", dataList.size());

			if (dataList.isEmpty()) {
				log.warn("No data found for export");
				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
				response.setContentType("application/json; charset=UTF-8");
				response.getWriter().write("{\"message\":\"조회된 데이터가 없습니다.\"}");
				response.getWriter().flush();
				return;
			}

			List<ApiStatsUI> uiList = dataList.stream()
					.map(mapper::toVo)
					.collect(Collectors.toList());
			log.info("Data converted to UI list - count: {}", uiList.size());

			String fileName = generateFileName(search);
			log.info("Generating Excel file: {}", fileName);

			excelExportService.exportApiStats(uiList, fileName, response);
			log.info("Excel export completed successfully");

		} catch (Exception e) {
			log.error("Excel export failed - error: {}", e.getMessage(), e);

			if (!response.isCommitted()) {
				response.reset();
				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				response.setContentType("application/json; charset=UTF-8");
				response.getWriter().write("{\"message\":\"Excel 파일 생성 중 오류가 발생했습니다: " + e.getMessage() + "\"}");
				response.getWriter().flush();
			} else {
				log.error("Cannot send error response - response already committed");
			}
		}
	}

	@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=EXCEL_EXPORT_SUMMARY")
	public void exportSummaryToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
		log.info("Excel export (summary) started - search: {}", search);

		try {
			List<ApiStatsUI> dataList = service.selectSummaryListForExcel(search);
			log.info("Summary data retrieved - count: {}", dataList.size());

			if (dataList.isEmpty()) {
				log.warn("No data found for export");
				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
				response.setContentType("application/json; charset=UTF-8");
				response.getWriter().write("{\"message\":\"조회된 데이터가 없습니다.\"}");
				response.getWriter().flush();
				return;
			}

			String fileName = generateSummaryFileName(search);
			log.info("Generating Excel file: {}", fileName);

			excelExportService.exportApiStats(dataList, fileName, response);
			log.info("Excel export (summary) completed successfully");

		} catch (Exception e) {
			log.error("Excel export (summary) failed - error: {}", e.getMessage(), e);

			if (!response.isCommitted()) {
				response.reset();
				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				response.setContentType("application/json; charset=UTF-8");
				response.getWriter().write("{\"message\":\"Excel 파일 생성 중 오류가 발생했습니다: " + e.getMessage() + "\"}");
				response.getWriter().flush();
			} else {
				log.error("Cannot send error response - response already committed");
			}
		}
	}

	private String generateFileName(ApiStatsSearch search) {
		String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
				? search.getSearchStartDateTime()
				: YearMonth.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
		return "API월별통계_" + timeRange + ".xlsx";
	}

	private String generateSummaryFileName(ApiStatsSearch search) {
		String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
				? search.getSearchStartDateTime()
				: YearMonth.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
		return "API월별통계_요약_" + timeRange + ".xlsx";
	}
}
