package incheon.sgp.rst.web;

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

import incheon.sgp.rst.service.RstTaskLyrTreeService;
import incheon.sgp.rst.vo.RstTaskLayerInfoVO;
import incheon.uis.ums.service.UisTaskLyrTreeService;
import incheon.uis.ums.vo.UisTaskLayerInfoVO;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpMethod;
import javax.annotation.PostConstruct;

import incheon.com.cmm.api.DefaultApiResponse;
import incheon.sgp.rst.service.RstGeoServerService;
import incheon.sgp.rst.service.RstLayerService;
import incheon.sgp.rst.vo.RstLayerSearchVO;
import incheon.sgp.rst.vo.RstLayerVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * Mapprime 연동 컨트롤러
 * @since 2025. 09. 08
 */
@RestController
@RequestMapping("/sgp/rst/layers")
@RequiredArgsConstructor
@Slf4j
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class RstLayersController {

    /**
     * UTF-8 설정 초기화
     */
    @PostConstruct
    public void init() {
        // 시스템 프로퍼티로 UTF-8 설정
        System.setProperty("file.encoding", "UTF-8");
        System.setProperty("sun.jnu.encoding", "UTF-8");
    }

    private final RstGeoServerService rstGeoServerService;
    private final RestTemplate restTemplate;
	private final RstLayerService rstLayerService;
    private final RstTaskLyrTreeService rstTaskLyrTreeService;


    /**
     * 레이어 목록 조회
     */
    @GetMapping
    public ResponseEntity<List<Map<String, Object>>> getLayerList() {
        log.info("GeoServer 레이어 목록 조회 요청");

        try {
            List<Map<String, Object>> layerList = rstGeoServerService.getLayerList();

            // UTF-8 Content-Type 헤더 설정
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(new MediaType("application", "json", java.nio.charset.StandardCharsets.UTF_8));

            return ResponseEntity.ok().headers(headers).body(layerList);
        } catch (Exception e) {
            log.error("레이어 목록 조회 중 오류 발생", e);
            return ResponseEntity.internalServerError()
                    .body(List.of(Map.of("success", false, "message", "레이어 목록 조회 중 오류 발생")));
        }
    }

    /**
     * 특정 레이어 정보 조회
     */
    @GetMapping("/info/{layerName}")
    public ResponseEntity<Map<String, Object>> getLayerInfo(@PathVariable String layerName) {
        log.info("GeoServer 레이어 정보 조회 요청: {}", layerName);

        try {
            Map<String, Object> layerInfo = rstGeoServerService.getLayerInfo(layerName);
            return ResponseEntity.ok(layerInfo);
        } catch (Exception e) {
            log.error("레이어 정보 조회 중 오류 발생", e);
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "레이어 정보 조회 중 오류 발생"));
        }
    }
    
    @GetMapping("/infos")
	public ResponseEntity<List<RstLayerVO>> infos(RstLayerSearchVO searchVO) {
    	
    	try {
			if (searchVO.getPageIndex() < 1) {
				searchVO.setPageIndex(1);
			}
			List<RstLayerVO> content = null;
            searchVO.setSchemaName("icsgp"); //TODO: 임시
			//searchVO.setCategory("부동산 통계 지도"); //TODO: 임시
			content = rstLayerService.selectLayerList(searchVO);
			long total = rstLayerService.selectLayerListTotCnt(searchVO);
			
			Map<String, Object> response = new HashMap<>();
			response.put("content", content);
			response.put("totalElements", total);
			if(searchVO.getPageSize() > 1) {
				response.put("page", searchVO.getPageIndex());
				response.put("size", searchVO.getPageSize());
				response.put("totalPages", (int) Math.ceil((double) total / searchVO.getPageSize()));
			}
			
	
	        return ResponseEntity.ok().body(content);
	    } catch (Exception e) {
	        log.error("레이어 목록 조회 중 오류 발생", e);
	        // 오류 발생 시에도 반환 타입(List<UisLayerVO>)에 맞게 빈 리스트 반환
	        return ResponseEntity.internalServerError().body(Collections.emptyList());
	    }
    }

	@GetMapping("/info/{id}")
	public DefaultApiResponse<RstLayerVO> getInfo(@PathVariable Long id) {
		RstLayerVO response = rstLayerService.selectLayerById(id);
		return DefaultApiResponse.success(response);
	}
    
    /**
     * GeoServer Capabilities 조회
     */
    @Deprecated
    @GetMapping("/capabilities")
    public ResponseEntity<Map<String, Object>> getCapabilities() {
        log.info("GeoServer Capabilities 조회 요청");

        try {
            Map<String, Object> result = rstGeoServerService.getCapabilities();

            // UTF-8 Content-Type 헤더 설정
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(new MediaType("application", "json", java.nio.charset.StandardCharsets.UTF_8));

            return ResponseEntity.ok().headers(headers).body(result);
        } catch (Exception e) {
            log.error("Capabilities 조회 중 오류 발생", e);
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "Capabilities 조회 중 오류 발생"));
        }
    }

    /**
     * WMS URL 생성
     */
    @Deprecated
    @GetMapping("/wms")
    public ResponseEntity<Map<String, Object>> generateWmsUrl(
            @RequestParam String layerName,
            @RequestParam String bbox,
            @RequestParam(defaultValue = "800") int width,
            @RequestParam(defaultValue = "600") int height) {

        log.info("WMS URL 생성 요청 - 레이어: {}, BBOX: {}", layerName, bbox);

        try {
            String wmsUrl = rstGeoServerService.generateWmsUrl(layerName, bbox, width, height);
            log.info("생성된 WMS URL: {}", wmsUrl);
            return ResponseEntity.ok(Map.of(
                "success", true,
                "wmsUrl", wmsUrl,
                "layerName", layerName
            ));
        } catch (Exception e) {
            log.error("WMS URL 생성 중 오류 발생", e);
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "WMS URL 생성 중 오류 발생"));
        }
    }

    /**
     * WMS 이미지 완전 프록시 (CORS 완전 해결)
     */
    @Deprecated
    @GetMapping("/wms/proxy")
    public ResponseEntity<byte[]> proxyWmsImage(
            @RequestParam String layerName,
            @RequestParam String bbox,
            @RequestParam(defaultValue = "800") int width,
            @RequestParam(defaultValue = "600") int height) {

        log.info("WMS 이미지 완전 프록시 요청 - 레이어: {}, BBOX: {}", layerName, bbox);

        try {
            // GeoServer WMS URL 생성 (EPSG:5186 좌표계 사용)
            String geoServerUrl = rstGeoServerService.generateWmsUrl(layerName, bbox, width, height);

            log.info("GeoServer WMS URL: {}", geoServerUrl);

            // UTF-8 인코딩 헤더 설정
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.set("Accept-Charset", "UTF-8");
            requestHeaders.set("Content-Type", "image/png;charset=UTF-8");

            HttpEntity<String> entity = new HttpEntity<>(requestHeaders);

            // GeoServer에 UTF-8 인코딩으로 요청
            ResponseEntity<byte[]> response = restTemplate.exchange(geoServerUrl, HttpMethod.GET, entity, byte[].class);

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                // Content-Type 헤더만 설정 (CORS는 @CrossOrigin으로 처리)
                HttpHeaders responseHeaders = new HttpHeaders();
                responseHeaders.setContentType(MediaType.IMAGE_PNG);
                responseHeaders.setCacheControl("no-cache");

                return ResponseEntity.ok()
                        .headers(responseHeaders)
                        .body(response.getBody());
            } else {
                log.error("GeoServer WMS 요청 실패: {}", response.getStatusCode());
                return ResponseEntity.status(response.getStatusCode()).build();
            }

        } catch (Exception e) {
            log.error("WMS 이미지 프록시 중 오류 발생", e);
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 사용자 레이어 조회
     */
    @Operation(summary = "레이어 조회", description = "레이어를 조회합니다.")
    @GetMapping("/task/rst/{lclsfCd}")
    public ResponseEntity<List<RstTaskLayerInfoVO>> getUserLayers(@PathVariable String lclsfCd) {
        List<RstTaskLayerInfoVO> response  = rstTaskLyrTreeService.getTaskLyrTreeInfo(lclsfCd);
        return ResponseEntity.ok().body(response);
    }
}
