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

import com.oqpo.api.enums.DataMessageCode;
import com.oqpo.api.enums.SystemMessageCode;
import com.oqpo.api.service.oper.UserMngService;
import com.oqpo.api.util.CryptoUtil;
import com.oqpo.api.web.dto.request.oper.usermng.*;
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.oper.usermng.UserInfoResponse;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;

@Slf4j
@RestController
@RequestMapping("/api/user")
public class UserMngController {
    @Autowired
    private UserMngService userMngService;

    @Value("${hashed.key}")
    private String hashed;

    /**
     * 설명 : 사용자 그리드 리스트
     *
     * @param userGridRequest
     * @return
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = " 사용자 그리드 리스트")
    @PostMapping("/detail-grid-list")
    public ResponseEntity<GridResponse> detailGridList(@RequestBody @Valid UserGridRequest userGridRequest) throws Exception {
        return ResponseEntity.ok(userMngService.userSearchGridList( userGridRequest.getSAfflShopId(), userGridRequest.getSBrandId(),  userGridRequest.getFromDt(), userGridRequest.getToDt(), userGridRequest.getSUserNm(), userGridRequest.getSUserStatCd(), userGridRequest.getSAuthTpCd(), userGridRequest.toDTO(userGridRequest)));
    }

    /**
     * 설명 : 사용자정보 저장
     *
     * @param userId
     * @param saveUserRequest
     * @return SaveResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "사용자정보 저장")
    @PostMapping("/save-user")
    public ResponseEntity<SaveResponse> saveUser(@ApiIgnore String userId, @RequestBody @Valid SaveUserRequest saveUserRequest) throws Exception {
        userMngService.saveUser(userId, saveUserRequest);
        return ResponseEntity.ok(SaveResponse.toDTO(SystemMessageCode.SAVE_OK));
    }

    /**
     * 설명 : 사용자 헤더 정보
     *
     * @param userId
     * @return SaveResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "userId", value = "사용자ID", required = true, dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "사용자 헤더 정보")
    @GetMapping("/info-user")
    public ResponseEntity<UserInfoResponse> infoUser(@RequestParam(value = "userId") String userId) throws Exception {
        return ResponseEntity.ok(userMngService.selectUserInfo(userId));
    }

    /**
     * 설명 : 사용자권한 그리드 리스트
     *
     * @param userAuthGridRequest
     * @return
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "사용자권한 그리드 리스트")
    @PostMapping("/userauth-grid-list")
    public ResponseEntity<GridResponse> detailGridList(@RequestBody @Valid UserAuthGridRequest userAuthGridRequest) throws Exception {
        return ResponseEntity.ok(userMngService.selectUserAuthGridList(userAuthGridRequest.getUserId(), userAuthGridRequest.toDTO(userAuthGridRequest)));
    }

    /**
     * 설명 : 사용자패스워드 초기화
     *
     * @param userId
     * @param
     * @return SaveResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "userId", value = "사용자ID", required = true, dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "사용자 패스워드 초기화")
    @GetMapping("/inti-userpw")
    public ResponseEntity<SaveResponse> saveUser(@RequestParam(value = "userId") String userId) throws Exception {
        userMngService.updateInitUserPw(userId);
        return ResponseEntity.ok(SaveResponse.toDTO(SystemMessageCode.INIT_PW_OK));
    }


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


    /**
     * 설명 : 사용자 팝업 검색 그리드 리스트
     *
     * @param userPopGridRequest
     * @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> popGridList(@RequestBody @Valid UserPopGridRequest userPopGridRequest) throws Exception {
        return ResponseEntity.ok(userMngService.selectPopUserGridList(userPopGridRequest.getSAfflShopId(), userPopGridRequest.getSBrandId(),  userPopGridRequest.getSUserId(), userPopGridRequest.getSUserNm(), userPopGridRequest.getSUserStatCd(), userPopGridRequest.toDTO(userPopGridRequest)));
    }


    /**
     * 설명 : 사용자정보 저장
     *
     * @param userId
     * @param savePrivateUserRequest
     * @return SaveResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header")
    })
    @ApiOperation(value = "사용자개인정보 저장")
    @PostMapping("/save-private-user")
    public ResponseEntity<SaveResponse> savePrivateUser(@ApiIgnore String userId, @RequestBody @Valid SavePrivateUserRequest savePrivateUserRequest) throws Exception {
        userMngService.updatePrivateUserInfo(userId, savePrivateUserRequest);
        return ResponseEntity.ok(SaveResponse.toDTO(SystemMessageCode.SAVE_OK));
    }

    /**
     * 설명 : 사용자 개인 패스워드 변경
     *
     * @param userId
     * @param
     * @return
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "password", value = "현패스워드", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "chgPassword", value = "변경패스워드", required = true, dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "사용자 개인 패스워드 변경")
    @GetMapping("/chg-pw")
    public ResponseEntity<SaveResponse> updateChpPwUser(@ApiIgnore String userId, @RequestParam(value = "password") String password, @RequestParam(value = "chgPassword") String chgPassword) throws Exception {
        hashed = StringEscapeUtils.unescapeJava(hashed);
        password = CryptoUtil.decrypt(password, hashed);
        chgPassword = CryptoUtil.decrypt(chgPassword, hashed);
        userMngService.updateChpPwUser(userId, password, chgPassword);
        return ResponseEntity.ok(SaveResponse.toDTO(SystemMessageCode.SAVE_OK));
    }

    //
    /**
     * 설명 : 사용자 개인 swagger 패스워드 변경
     *
     * @param userId
     * @param
     * @return SaveResponse
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "X-AUTH-TOKEN", value = "CONN-KEY", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "password", value = "현패스워드", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "chgPassword", value = "변경패스워드", required = true, dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "사용자 개인 swagger 패스워드 변경")
    @GetMapping("/swagger-chg-pw")
    public ResponseEntity<SaveResponse> updateSwaggerChpPwUser(@ApiIgnore String userId, @RequestParam(value = "password") String password, @RequestParam(value = "chgPassword") String chgPassword) throws Exception {
        userMngService.updateChpPwUser(userId, password, chgPassword);
        return ResponseEntity.ok(SaveResponse.toDTO(SystemMessageCode.SAVE_OK));
    }
}
