package com.takensoft.cms.mber.web;

import com.takensoft.cms.mber.dto.AdmMbrDTO;
import com.takensoft.cms.mber.dto.JoinDTO;
import com.takensoft.cms.mber.dto.PasswordDTO;
import com.takensoft.cms.mber.service.AdmMbrService;
import com.takensoft.cms.mber.service.MberService;
import com.takensoft.cms.mber.vo.MberVO;
import com.takensoft.common.exception.IdDuplicationException;
import com.takensoft.common.util.ResponseData;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @author  : 박정하
 * @since   : 2024.06.21
 *
 * 회원정보 관련 컨트롤러
 */
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/mbr")
public class AdmMbrController {
    private final AdmMbrService admMbrService;
    private final MberService mbrService;

    /**
     * @author 박정하
     * @since 2024.06.21
     * @param params
     * @return
     * @throws Exception
     *
     * 회원정보 목록 조회
     */
    @PostMapping(value = "/listProc.json")
    public ResponseEntity<?> listProc(@RequestBody HashMap<String, String> params) throws Exception {
        HashMap<String, Object> result = admMbrService.mbrList(params);

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        responseData.setStatus(HttpStatus.OK);
        responseData.setMessage("정상적으로 조회가 처리되었습니다.");
        responseData.setData(result);
        return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
    }

    /**
     * @author 박정하
     * @since 2024.06.21
     * @param resetPswd, admMbrDTO
     * @return
     * @throws Exception
     *
     * 회원정보 비밀번호 초기화
    */
    @PostMapping(value = "/pswdResetProc.json")
    public ResponseEntity<?> pswdResetProc(@Value("${password.reset}") String resetPswd, @RequestBody AdmMbrDTO admMbrDTO) throws  Exception {
        PasswordDTO passwordDTO = new PasswordDTO();
        passwordDTO.setMbrId(admMbrDTO.getMbrId());
        passwordDTO.setPswd(admMbrDTO.getPswd());
        passwordDTO.setNewPswd(resetPswd);

        // 비밀번호 변경
        int result = mbrService.updatePassword(passwordDTO);

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        if(result > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 초기화 처리되었습니다.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("초기화에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * @author 박정하
     * @since 2024.06.21
     * @param admMbrDTO
     * @return
     * @throws Exception
     *
     * 회원정보 상세 조회
     */
    @PostMapping(value = "/detailProc.json")
    public ResponseEntity<?> detailProc(@RequestBody AdmMbrDTO admMbrDTO) throws Exception {
        // 상세 조회
        AdmMbrDTO result = admMbrService.mbrDetail(admMbrDTO.getMbrId());

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        responseData.setStatus(HttpStatus.OK);
        responseData.setMessage("정상적으로 회원정보 상세 조회가 처리되었습니다.");
        responseData.setData(result);
        return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
    }

    /**
     * @author 박정하
     * @since 2024.06.21
     * @param admMbrDTO
     * @return
     * @throws Exception
     *
     * 회원정보 수정
     */
    @PostMapping(value = "/updateProc.json")
    public ResponseEntity<?> updateProc(@RequestBody AdmMbrDTO admMbrDTO) throws Exception {
        int result = admMbrService.updateMbr(admMbrDTO);

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        if(result > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 수정되었습니다.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("수정에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * @author 박정하
     * @since 2024.06.21
     * @param admMbrDTO
     * @return
     * @throws Exception
     *
     * 회원정보 삭제
     */
    @PostMapping(value = "/deleteProc.json")
    public ResponseEntity<?> deleteProc(@RequestBody AdmMbrDTO admMbrDTO) throws Exception {
        admMbrDTO.setUseYn("N"); // 회원정보 삭제
        int result = admMbrService.updateMbr(admMbrDTO);

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        if(result > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 삭제되었습니다.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("삭제에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * @author 박정하
     * @since 2024.06.21
     * @param req, joinDTO
     * @return
     * @throws Exception
     *
     * 회원정보 등록
     */
    @PostMapping(value = "/joinProc.json")
    public ResponseEntity<?> joinProc(HttpServletRequest req, @RequestBody @Valid JoinDTO joinDTO) throws Exception {
        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();

        // 아이디 중복 검사
        boolean isExistence = mbrService.findByCheckLoginId(joinDTO.getLgnId());
        if(isExistence) {
//            throw new IdDuplicationException("이미 존재하는 아이디입니다.");
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("이미 존재하는 아이디입니다.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        // 회원 가입 진행
        HashMap<String, Object> result = admMbrService.mbrInsert(req, joinDTO);
        int insertResult = (int) result.get("insertResult");

        if(insertResult > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 회원가입 처리되었습니다.");
            responseData.setData(result);
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("회원가입에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * @author 박정하
     * @since 2024.07.03
     * @param mbrVO
     * @return
     * @throws Exception
     *
     * 아이디 찾기
     */
    @PostMapping(value = "/searchIdProc.json")
    public ResponseEntity<?> searchIdProc(@RequestBody MberVO mbrVO) throws Exception {
        String result = admMbrService.lgnIdSearch(mbrVO);

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        if(result != null) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 조회 처리되었습니다.");
            responseData.setData(result);
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("입력하신 정보와 일치하는 회원이 존재하지 않습니다.\n다시 시도하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * @author 박정하
     * @since 2024.07.03
     * @param admMbrDTO
     * @return
     * @throws Exception
     *
     * 비밀번호 초기화
     */
    @PostMapping(value = "/resetPswdProc.json")
    public ResponseEntity<?> resetPswdProc(@Value("${password.reset}") String resetPswd, @RequestBody AdmMbrDTO admMbrDTO) throws Exception {
        int result = admMbrService.mbrIdSearch(resetPswd, admMbrDTO);

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        if(result > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 조회 처리되었습니다.");
            responseData.setData(result);
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("입력하신 정보와 일치하는 회원이 존재하지 않습니다.\n다시 시도하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}