package com.oqpo.api.web.controller.system;

import com.oqpo.api.entity.oper.MenuEntity;
import com.oqpo.api.enums.DataMessageCode;
import com.oqpo.api.enums.SystemMessageCode;
import com.oqpo.api.service.system.MenuService;
import com.oqpo.api.web.dto.request.menu.AuthMenuRequest;
import com.oqpo.api.web.dto.request.menu.MenuPopSearchGridRequest;
import com.oqpo.api.web.dto.request.menu.SaveMenuRequest;
import com.oqpo.api.web.dto.response.DataResponse;
import com.oqpo.api.web.dto.response.GridResponse;
import com.oqpo.api.web.dto.response.SaveResponse;
import com.oqpo.api.web.dto.response.menu.MenuAuthListResponse;
import com.oqpo.api.web.dto.response.menu.MenuInfoResponse;
import com.oqpo.api.web.dto.response.menu.MenuSearchListResponse;
import com.oqpo.api.web.dto.response.menu.TopMenuListResponse;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/menu")
public class MenuController {

    @Autowired
    private MenuService menuService;

    /**
     * 설명 : 메뉴 중복 체크
     *
     * @param menuId
     * @return
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "menuId", value = "메뉴ID", required = true, dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "메뉴 중복 체크")
    @GetMapping("/check-duplicate")
    public ResponseEntity<DataResponse> checkDuplicate(@RequestParam(value = "menuId") String menuId) throws Exception {
        String dupYn = menuService.selectMenuIdDupYn(menuId);
        DataMessageCode message = null;
        if ("Y".equals(dupYn)) {
            message = DataMessageCode.DUPLICATE_YES;
        } else {
            message = DataMessageCode.DUPLICATE_NO;
        }
        return ResponseEntity.ok(DataResponse.toDTO(message));
    }

    /**
     * 설명 : 메뉴 전체 리스트
     *
     * @return
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "메뉴 전체 리스트")
    @GetMapping("/menu-search")
    public ResponseEntity<MenuSearchListResponse> selectAllMenuList() throws Exception {
        return ResponseEntity.ok(menuService.selectAllMenuList());
    }

    /**
     * 설명 : 메뉴 헤더 정보
     *
     * @param menuNo
     * @return MenuInfoResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "menuNo", value = "메뉴번호", required = true, dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "메뉴 정보")
    @GetMapping("/info-menu")
    public ResponseEntity<MenuInfoResponse> infoMenu(@RequestParam(value = "menuNo") String menuNo) throws Exception {
        return ResponseEntity.ok(menuService.selectMenuInfo(menuNo));
    }

    /**
     * 설명 : 메뉴정보 저장
     *
     * @param userId
     * @param saveMenuRequest
     * @return SaveResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "메뉴정보 저장")
    @PostMapping("/save-menu")
    public ResponseEntity<SaveResponse> saveMenu(@ApiIgnore String userId, @RequestBody @Valid SaveMenuRequest saveMenuRequest) throws Exception {
        menuService.saveMenu(userId, saveMenuRequest);
        return ResponseEntity.ok(SaveResponse.toDTO(SystemMessageCode.SAVE_OK));
    }


    /**
     * 설명 : 메뉴정보 삭제
     *
     * @param menuNo
     * @return SaveResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "menuNo", value = "메뉴번호", required = true, dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "메뉴정보 삭제")
    @GetMapping("/del-menu")
    public ResponseEntity<SaveResponse> delMenu(@RequestParam(value = "menuNo") String menuNo) throws Exception {
        menuService.delMenu(menuNo);
        return ResponseEntity.ok(SaveResponse.toDTO(SystemMessageCode.DELETE_OK));
    }


    /**
     * 설명 : 상위메뉴리스트
     *
     * @param
     * @return TopMenuListResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "상위 메뉴 리스트")
    @GetMapping("/list-topmenu")
    public ResponseEntity<List<TopMenuListResponse>> topMenuList() throws Exception {
        List<MenuEntity> entities = menuService.selectTopMenuList() ;
        return ResponseEntity.ok(
                entities.stream()
                    .map(entity -> TopMenuListResponse.toDTO(entity))
                    .collect(Collectors.toList())
        ) ;

    }


    /**
     * 설명 : 권한메뉴리스트
     *
     * @param  authMenuRequest
     * @return TopMenuListResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "권한 메뉴 리스트")
    @PostMapping("/list-authmenu")
    public ResponseEntity<List<MenuAuthListResponse>> selectBottomMenuList(@RequestBody @Valid AuthMenuRequest authMenuRequest) throws Exception {

        List<MenuEntity> entities = menuService.selectBottomMenuList(authMenuRequest.getTopMenuNo(), authMenuRequest.getAuthNo()) ;
        return ResponseEntity.ok(
                entities.stream()
                        .map(entity -> MenuAuthListResponse.toDTO(entity))
                        .collect(Collectors.toList())
        ) ;

    }


    /**
     * 설명 : 메뉴 팝업 검색 그리드 리스트
     *
     * @param authSearchGridRequest
     * @return
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "메뉴 팝업 검색 그리드 리스트")
    @PostMapping("/pop-grid-list")
    public ResponseEntity<GridResponse> detailGridList(@RequestBody @Valid MenuPopSearchGridRequest menuPopSearchGridRequest) throws Exception {
        return ResponseEntity.ok(menuService.selectPopMenuList(menuPopSearchGridRequest.getSTopMenuNo(), menuPopSearchGridRequest.getSMenuNm(),  menuPopSearchGridRequest.toDTO(menuPopSearchGridRequest)));
    }

}
