package incheon.ags.mrb.share.web;

import incheon.ags.mrb.main.dto.RecipeDetailDTO;
import incheon.ags.mrb.share.service.RecipeShrnService;
import incheon.ags.mrb.share.web.dto.RecipeShareDTO;
import incheon.com.cmm.api.DefaultApiResponse;
import incheon.com.security.annotation.RequirePermission;
import incheon.com.security.vo.LoginVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

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

/**
 * 레시피 공유 REST API Controller
 * - 레시피 공유 신청, 승인, 거부, 조회 등의 공유 관련 API 제공
 */
@Slf4j
@Tag(name = "Recipe Share", description = "레시피 공유 API")
@RestController
@RequestMapping("/ags/mrb/recipes/share")
@RequiredArgsConstructor
public class RecipeShrnApiController {

    private final RecipeShrnService recipeShrnService;

    /**
     * 공유받은 레시피 목록 조회
     * 현재 사용자에게 공유된 레시피 목록을 조회합니다.
     *
     * @param pageIndex 페이지 번호
     * @param recordCountPerPage 페이지당 건수
     * @return 공유받은 레시피 목록
     * @throws Exception 조회 실패 시 예외 발생
     */
    @Operation(summary = "공유받은 레시피 목록 조회", description = "현재 사용자에게 공유된 레시피 목록을 조회합니다.")
    @GetMapping
    public ResponseEntity<DefaultApiResponse<List<RecipeDetailDTO>>> getSharedRecipes(
            @Parameter(description = "검색 조건 (0:레시피명, 1:설명, 2:작성자)", example = "0")
            @RequestParam(value = "searchCondition", required = false) String searchCondition,
            @Parameter(description = "검색 키워드", example = "관광")
            @RequestParam(value = "searchKeyword", required = false) String searchKeyword,
            @Parameter(description = "레시피 분류코드 (A:일반, B:전문, C:분석용)", example = "A")
            @RequestParam(value = "recipeClsfCd", required = false) String recipeClsfCd,
            @Parameter(description = "페이지 번호", example = "1")
            @RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
            @Parameter(description = "페이지당 건수", example = "10")
            @RequestParam(value = "recordCountPerPage", required = false, defaultValue = "10") Integer recordCountPerPage,
            @AuthenticationPrincipal LoginVO loginUser) throws Exception {

        String userId = (loginUser != null ? loginUser.getUserId() : null);
        // 서비스로 비즈니스 로직 위임
        Map<String, Object> result = recipeShrnService.getSharedRecipes(userId, searchCondition, searchKeyword, recipeClsfCd, pageIndex, recordCountPerPage);
        
        @SuppressWarnings("unchecked")
        List<RecipeDetailDTO> sharedRecipes = (List<RecipeDetailDTO>) result.get("list");

        log.info("공유받은 레시피 목록 조회 완료 - userId: {}, 총 건수: {}, 조회 건수: {}", 
                userId, result.get("totalCount"), sharedRecipes.size());

        DefaultApiResponse<List<RecipeDetailDTO>> response = DefaultApiResponse.success(
                sharedRecipes, "공유받은 레시피 목록 조회 성공");
        response.addMeta("totalCount", result.get("totalCount"));
        response.addMeta("pageIndex", result.get("pageIndex"));
        response.addMeta("recordCountPerPage", result.get("recordCountPerPage"));
        response.addMeta("totalPages", result.get("totalPages"));

        return ResponseEntity.ok(response);
    }

    
    /**
     * 레시피 공유 신청
     * 선택한 공유 대상에게 레시피를 공유 신청합니다.
     *
     * HTTP 상태 코드:
     * - 201 Created: 공유 신청 성공
     * - 400 Bad Request: 유효성 검증 실패
     * - 500 Internal Server Error: 저장 실패
     *
     * @param shareDTO 공유 신청 정보
     * @return 공유 신청 결과
     * @throws Exception 신청 실패 시 예외 발생
     */
    @Operation(summary = "레시피 공유 신청", description = "레시피를 다른 사용자에게 공유 신청합니다.")
    @PostMapping
    public ResponseEntity<DefaultApiResponse<Integer>> createShareRequest(
            @Parameter(description = "공유 신청 정보", required = true)
            @RequestBody RecipeShareDTO shareDTO,
            @AuthenticationPrincipal LoginVO loginUser) throws Exception {

        // 서비스로 모든 로직 위임 (권한 체크 포함)
        Integer shrnId = recipeShrnService.createShareRequest(shareDTO.getRecipeId(),shareDTO.getShareTargets(), loginUser);

        log.info("레시피 공유 신청 완료 - shrnId: {}, recipeId: {}, userId: {}, 공유 대상 수: {}",
                shrnId, shareDTO.getRecipeId(), loginUser.getUserId(),shareDTO.getShareTargets().size());

        return ResponseEntity
                .status(HttpStatus.CREATED)
                .body(DefaultApiResponse.success(shrnId, "레시피 공유 신청이 완료되었습니다."));
    }

    /**
     * 레시피 공유 신청 처리 현황 조회
     * recipe_shrn과 recipe_shrn_dtl, task_lyr 조합하여 조회
     *
     * @param recipeId 레시피 ID
     * @return 공유 신청 처리 현황 목록
     * @throws Exception 조회 실패 시 예외 발생
     */
    @Operation(summary = "레시피 공유 신청 처리 현황 조회", description = "레시피의 공유 신청 현황을 조회합니다.")
    @GetMapping("{recipeId}")
    public ResponseEntity<DefaultApiResponse<List<RecipeShareDTO>>> getShareStatus(
            @Parameter(description = "레시피 ID", required = true) @PathVariable Integer recipeId,
            @AuthenticationPrincipal LoginVO loginUser) throws Exception {

        // 서비스로 비즈니스 로직 위임
        List<RecipeShareDTO> shareList = recipeShrnService.getShareStatusList(recipeId, loginUser);

        log.info("레시피 공유 신청 처리 현황 조회 완료 - recipeId: {}, 조회 건수: {}", recipeId, shareList.size());

        return ResponseEntity.ok(DefaultApiResponse.success(shareList, "공유 신청 처리 현황 조회 성공"));
    }

    /**
     * 레시피 공유 상세 정보 조회
     *
     * @param shareId 공유 ID
     * @return 공유 상세 정보
     * @throws Exception 조회 실패 시 예외 발생
     */
    @Operation(summary = "레시피 공유 상세 정보 조회", description = "공유 신청의 상세 정보를 조회합니다.")
    @GetMapping("detail/{shareId}")
    public ResponseEntity<DefaultApiResponse<RecipeShareDTO>> getShareDetail(
            @Parameter(description = "공유 ID", required = true) @PathVariable Integer shareId) throws Exception {

        // 서비스로 모든 로직 위임
        RecipeShareDTO shareDetail = recipeShrnService.getShareDetail(shareId);

        log.info("레시피 공유 상세 정보 조회 완료 - shareId: {}", shareId);

        return ResponseEntity.ok(DefaultApiResponse.success(shareDetail, "공유 상세 정보 조회 성공"));
    }

    /**
     * 레시피 공유 신청 삭제
     *
     * @param shareId 공유 ID
     * @return 삭제 결과 응답
     * @throws Exception 삭제 실패 시 예외 발생
     */
    @Operation(summary = "레시피 공유 신청 삭제", description = "대기 상태의 공유 신청을 삭제합니다.")
    @DeleteMapping("{recipeId}/{shareId}")
    public ResponseEntity<DefaultApiResponse<Void>> deleteShareRequest(
            @Parameter(description = "레시피 ID", required = true) @PathVariable Integer recipeId,
            @Parameter(description = "공유 ID", required = true) @PathVariable Integer shareId,
            @AuthenticationPrincipal LoginVO loginUser) throws Exception {

        // 서비스로 모든 로직 위임 (권한 체크 포함)
        recipeShrnService.deleteRecipeShrn(recipeId, loginUser, shareId);

        log.info("레시피 공유 신청 삭제 완료 - recipeId: {}, shareId: {}", recipeId, shareId);

        return ResponseEntity.ok(DefaultApiResponse.success(null, "공유 신청 삭제 성공"));
    }

    /**
     * 관리자용 공유 승인 대기 목록 조회
     * 모든 사용자의 공유 승인 대기 요청 목록을 조회합니다. (관리자 전용)
     *
     * @param pageIndex 페이지 번호
     * @param recordCountPerPage 페이지당 건수
     * @return 승인 대기 목록
     * @throws Exception 조회 실패 시 예외 발생
     */
    @Operation(summary = "관리자용 공유 승인 대기 목록 조회", description = "모든 사용자의 공유 승인 대기 요청 목록을 조회합니다. (관리자 전용)")
    @GetMapping("/approvals")
    @RequirePermission(system = "AGS", permissions = "PERM_FUNC_SHARE_MANAGE")
    public ResponseEntity<DefaultApiResponse<List<RecipeShareDTO>>> getApprovalRequests(
            @Parameter(description = "검색 키워드", example = "관광")
            @RequestParam(value = "searchKeyword", required = false) String searchKeyword,
            @Parameter(description = "검색 조건 (0:제목, 2:작성자, 3:공유인)", example = "0")
            @RequestParam(value = "searchCondition", required = false, defaultValue = "0") String searchCondition,
            @Parameter(description = "레시피 분류코드 (A:일반, B:전문, C:분석용)", example = "A")
            @RequestParam(value = "recipeClsfCd", required = false) String recipeClsfCd,
            @Parameter(description = "페이지 번호", example = "1")
            @RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
            @Parameter(description = "페이지당 건수", example = "10")
            @RequestParam(value = "recordCountPerPage", required = false, defaultValue = "10") Integer recordCountPerPage,
            @AuthenticationPrincipal LoginVO loginUser) throws Exception {

        String userId = (loginUser != null ? loginUser.getUserId() : null);
        // 서비스로 비즈니스 로직 위임
        Map<String, Object> result = recipeShrnService.getApprovalRequests(searchCondition, searchKeyword, recipeClsfCd, pageIndex, recordCountPerPage, userId);
        
        @SuppressWarnings("unchecked")
        List<RecipeShareDTO> approvalList = (List<RecipeShareDTO>) result.get("list");

        log.info("관리자용 공유 승인 대기 목록 조회 완료 - userId: {}, 조회 건수: {}", userId, approvalList.size());

        DefaultApiResponse<List<RecipeShareDTO>> response = DefaultApiResponse.success(
                approvalList, "승인 대기 목록 조회 성공");
        response.addMeta("totalCount", result.get("totalCount"));
        response.addMeta("pageIndex", result.get("pageIndex"));
        response.addMeta("recordCountPerPage", result.get("recordCountPerPage"));
        response.addMeta("totalPages", result.get("totalPages"));

        return ResponseEntity.ok(response);
    }

    /**
     * 공유 승인 처리
     * 관리자가 공유 요청을 승인합니다.
     *
     * @param shareId 공유 ID
     * @return 승인 처리 결과
     * @throws Exception 처리 실패 시 예외 발생
     */
    @Operation(summary = "공유 승인 처리", description = "관리자가 공유 요청을 승인합니다.")
    @PostMapping("/{shareId}/approve")
    @RequirePermission(system = "AGS", permissions = "PERM_FUNC_SHARE_MANAGE")
    public ResponseEntity<DefaultApiResponse<Void>> approveShare(
            @Parameter(description = "공유 ID", required = true) @PathVariable Integer shareId,
            @AuthenticationPrincipal LoginVO loginUser) throws Exception {

        String userId = (loginUser != null ? loginUser.getUserId() : null);

        // 서비스로 비즈니스 로직 위임 (검증 포함)
        recipeShrnService.approveShare(shareId, userId);

        log.info("공유 승인 처리 완료 - shareId: {}, userId: {}", shareId, userId);
        return ResponseEntity.ok(DefaultApiResponse.success(null, "공유 요청이 승인되었습니다."));
    }

    /**
     * 공유 거부 처리
     * 관리자가 공유 요청을 거부합니다.
     *
     * @param shareId 공유 ID
     * @return 거부 처리 결과
     * @throws Exception 처리 실패 시 예외 발생
     */
    @Operation(summary = "공유 거부 처리", description = "관리자가 공유 요청을 거부합니다.")
    @PostMapping("/{shareId}/reject")
    @RequirePermission(system = "AGS", permissions = "PERM_FUNC_SHARE_MANAGE")
    public ResponseEntity<DefaultApiResponse<Void>> rejectShare(
            @Parameter(description = "공유 ID", required = true) @PathVariable Integer shareId,
            @AuthenticationPrincipal LoginVO loginUser) throws Exception {

        String userId = (loginUser != null ? loginUser.getUserId() : null);
        // 서비스로 비즈니스 로직 위임 (검증 포함)
        recipeShrnService.rejectShare(shareId, userId);

        log.info("공유 거부 처리 완료 - shareId: {}, userId: {}", shareId, userId);
        return ResponseEntity.ok(DefaultApiResponse.success(null, "공유 요청이 거부되었습니다."));
    }

}
