package incheon.ags.mrb.pub.web;

import incheon.ags.ias.comCd.service.ComCdService;
import incheon.ags.ias.comCd.vo.ComCdVO;
import incheon.ags.mrb.chart.web.ChartApiController;
import incheon.ags.mrb.chart.web.dto.ChartQueryParams;
import incheon.ags.mrb.main.service.BoardObjectService;
import incheon.ags.mrb.main.service.RecipeService;
import incheon.ags.mrb.main.vo.BoardObjectVO;
import incheon.ags.mrb.main.dto.RecipeDetailDTO;
import incheon.ags.mrb.style.web.RecipeLayerStyleApiController;
import incheon.ags.mrb.style.web.dto.RecipeStyleDTO;
import incheon.com.cmm.api.DefaultApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 외부 공개 레시피 컨트롤러
 * - 로그인 없이 접근 가능한 공개 페이지
 */
@Controller
@RequestMapping("/ags/mrb/pub")
@RequiredArgsConstructor
public class MrbPublicController {

    private final static Logger logger = LoggerFactory.getLogger(MrbPublicController.class);

    private final RecipeService recipeService;
    private final BoardObjectService boardObjectService;
    private final RecipeLayerStyleApiController recipeLayerStyleApiController;
    private final ChartApiController chartApiController;
    private final ComCdService comCdService;

    /**
     * 외부 공개 지도 레시피 메인 페이지
     */
    @GetMapping("/main.do")
    public String index(@RequestParam(value = "id", required = true) Integer id, Model model) throws Exception {
        recipeService.updateRecipeViewInfo(id);
        if (!isPublicRecipe(id)) {
            throw new SecurityException("외부 공개 나의 지도 레시피가 아닙니다.");
        }

        model.addAttribute("recipeId", id);
        model.addAttribute("isPublic", true);

        return "ags/mrb/main/main";
    }

    /**
     * 외부 공개 레시피 상세 조회
     *
     * @param recipeId 레시피 ID
     * @return 외부 공개 레시피 상세 정보 응답
     * @throws Exception 조회 실패 시 예외 발생
     */
    @Validated
    @Operation(summary = "외부 공개 레시피 상세 조회", description = "레시피 ID로 레시피 상세 정보를 조회합니다. 조회수는 페이지 로드 시 증가합니다.")
    @GetMapping("/recipes/{recipeId}")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<RecipeDetailDTO>> getPublicRecipeDetail(
            @Parameter(description = "레시피 ID", required = true) @PathVariable Integer recipeId) throws Exception {

        if (!isPublicRecipe(recipeId)) {
            throw new SecurityException("외부 공개 나의 지도 레시피가 아닙니다.");
        }

        RecipeDetailDTO recipeDetail = recipeService.getPublicRecipeDetail(recipeId);

        List<BoardObjectVO> boardObjectList = boardObjectService.selectBoardObjectListByRecipeId(recipeId);
        recipeDetail.setBoardObjectList(boardObjectList);

        return ResponseEntity.ok(DefaultApiResponse.success(recipeDetail, "레시피 상세 조회 성공"));
    }

    /**
     * 외부 공개 레시피 레이어 스타일 상세 조회
     *
     * @param styleId 스타일 ID
     * @return 외부 공개 레시피 레이어 스타일 상세 정보 응답
     * @throws Exception 조회 실패 시 예외 발생
     */
    @Operation(summary = "레시피 레이어 스타일 상세 조회", description = "스타일 ID로 레시피 레이어 스타일 상세 정보를 조회합니다. 작성자/수정자 정보는 제외됩니다.")
    @GetMapping("/layers/styles/{styleId}")
    public ResponseEntity<DefaultApiResponse<RecipeStyleDTO>> getRecipeLayerStyle(
            @Parameter(description = "스타일 ID", required = true) @PathVariable Long styleId) throws Exception {
        return recipeLayerStyleApiController.getRecipeLayerStyle(styleId);
    }

    @GetMapping("/chart/api/columns/by-layer")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<List<Map<String, Object>>>> getTableColumnsByLayerId(
            @RequestParam String layerId,
            @RequestParam String layerType) {
        return chartApiController.getTableColumnsByLayerId(layerId, layerType);
    }

    @PostMapping("/chart/api/data.do")
    @ResponseBody
    public ResponseEntity<List<Map<String, Object>>> getChartData(@RequestBody ChartQueryParams params) {
        return chartApiController.getChartData(params);
    }

    private boolean isPublicRecipe(Integer id) throws Exception {
        List<ComCdVO> cdList = comCdService.getComCdByGroupCd("MRB_RECIPE_PUBLIC_ID");
        boolean isPublic = false;
        for (ComCdVO cd : cdList) {
            if (cd.getCd().equalsIgnoreCase(Integer.toString(id))) {
                isPublic = true;
                break;
            }
        }
        return isPublic;
    }

    @GetMapping("/layers/styles/random")
    public ResponseEntity<DefaultApiResponse<RecipeStyleDTO>> getRandomStyle(
            @Parameter(description = "공간 타입", required = true) @RequestParam String spceTy,
            @Parameter(description = "스타일 번호", required = true) @RequestParam int styleNumber) throws Exception {
        return recipeLayerStyleApiController.getRandomStyle(spceTy, styleNumber);
    }
}
