package com.takensoft.cms.codeManage.web;

import com.takensoft.cms.codeManage.service.CodeManageService;
import com.takensoft.cms.codeManage.vo.CodeManageVO;
import com.takensoft.common.util.ResponseData;
import com.takensoft.common.HierachyVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.*;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author  : takensoft
 * @since   : 2024.04.09
 *
 * 공통코드 정보 관련 컨트롤러
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/admin/code")
public class CodeManageController {

    private final CodeManageService codeManageService;

    /**
     * @author takensoft
     * @since 2024.04.09
     * @param codeManageVO
     * @return
     * @throws Exception
     *
     * 공통코드 등록
     */
    @PostMapping("/saveProc.json")
    public ResponseEntity<?> saveProc(@RequestBody CodeManageVO codeManageVO) throws Exception {
        // 코드 중복 검사
        boolean isExistence = codeManageService.findByCheckCd(codeManageVO);

        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();

        if(isExistence) {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("이미 존재하는 코드입니다.");
            log.error("이미 존재하는 코드입니다.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        // 코드 등록
        int result = codeManageService.cdSave(codeManageVO);
        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 takensoft
     * @since 2024.04.09
     * @param
     * @return
     * @throws Exception
     *
     * 공통코드 목록 조회 (관리자용)
     */
    @GetMapping(value = "/findAll.json")
    public ResponseEntity<?> findAll() throws Exception {
        // Tree용
        List<HierachyVO> hierachyList = codeManageService.findByTopNode();

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("hierachyList", hierachyList);
        result.put("newCode", new CodeManageVO());

        // 응답 처리
        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 takensoft
     * @since 2024.04.09
     * @param codeManageVO
     * @return
     * @throws Exception
     *
     * 공통코드 상세 조회 (관리자용)
     */
    @PostMapping("/findByCd.json")
    public ResponseEntity<?> findByCd(@RequestBody CodeManageVO codeManageVO) throws Exception {
        // 공통코드 조회
        CodeManageVO code = codeManageService.findByCd(codeManageVO.getCd());

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", code);

        // 응답 처리
        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 takensoft
     * @since 2024.04.15
     * @param codeManageVO
     * @return
     * @throws Exception
     *
     * 공통코드 수정
     */
    @PostMapping("/updateProc.json")
    public ResponseEntity<?> updateProc(@RequestBody CodeManageVO codeManageVO) throws Exception {

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();

        // 코드의 변경 사항이 있을 때만 코드 중복 검사 진행
        if(codeManageVO.getOriginCd() != null && !codeManageVO.getOriginCd().equals("") && !codeManageVO.getOriginCd().equals(codeManageVO.getCd())) {
            // 코드 중복 검사
            boolean isExistence = codeManageService.findByCheckCd(codeManageVO);
            if(isExistence) {
                responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
                responseData.setMessage("이미 존재하는 코드입니다.");
                log.error("이미 존재하는 코드입니다.");
                return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
            }
        }
        // 코드 수정
        int result = codeManageService.cdUpdate(codeManageVO);

        // 응답 처리
        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 takensoft
     * @since 2024.04.15
     * @param codeManageVO
     * @return
     * @throws Exception
     *
     * 공통코드 삭제
     */
    @PostMapping("/deleteProc.json")
    public ResponseEntity<?> deleteProc(@RequestBody CodeManageVO codeManageVO) throws Exception {
        // 공통 코드 삭제(하위 항목 모두)
        int result = codeManageService.cdDelete(codeManageVO.getCd());

        // 응답 처리
        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 takensoft
     * @since 2024.04.09
     * @param codeManageVO
     * @return
     * @throws Exception
     *
     * 특정 공통 목록 코드 조회(시스템 처리용)
     */
    @PostMapping("/findByCdSystem.json")
    public ResponseEntity<?> findByCdSystem(@RequestBody CodeManageVO codeManageVO) throws Exception {
        // 메뉴 조회
        CodeManageVO code = codeManageService.findByCdSystem(codeManageVO.getCd());

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", code);

        // 응답 처리
        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.05.10
     * @param codeList
     * @return
     * @throws Exception
     *
     * 공통 코드 목록 수정
     */
    @PostMapping(value = "/updateListProc.json")
    public ResponseEntity<?> updateListProc(@RequestBody List<HierachyVO> codeList) throws Exception {
        // 공통 코드 목록 수정
        int result = codeManageService.updateList(codeList);

        // 응답 처리
        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);
        }
    }
}