package com.takensoft.cms.bbs.web;

import com.takensoft.cms.bbs.service.BbsCnService;
import com.takensoft.cms.bbs.service.BbsMngService;
import com.takensoft.cms.bbs.service.CmntService;
import com.takensoft.cms.bbs.vo.BbsCnVO;
import com.takensoft.cms.bbs.vo.BbsMngVO;
import com.takensoft.cms.bbs.vo.CmntVO;
import com.takensoft.common.file.service.FileService;
import com.takensoft.common.file.vo.FileVO;
import com.takensoft.common.util.ResponseData;
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 org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author  : 하석형
 * @since   : 2024.05.09
 *
 * 게시판 내용 관련 컨트롤러
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping(value="/sys/bbsCn")
public class BbsCnController {

    private final BbsCnService bbsCnService;
    private final BbsMngService bbsMngService;
    private final FileService fileService;

    /**
     * @author  하석형
     * @since   2024.05.09
     * @param   bbsCnVO
     * @return
     * @throws  Exception
     *
     * 게시판 내용 등록
     */
//    @PostMapping("/saveProc.json")
//    public ResponseEntity<?> saveProc(@RequestBody BbsCnVO bbsCnVO) throws Exception {
//        // 응답 처리
//        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
//        ResponseData responseData = new ResponseData();
//
//        // 게시판 내용 등록
//        int result = bbsCnService.saveBbsCn(bbsCnVO);
//        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);
//        }
//    }
    /**
     * @author 방선주
     * @since 2024.05.21
     * @param bbsCn, multipartFileList
     * @return
     * @throws Exception
     *
     * 게시판 내용 등록
     */
    @PostMapping(path = "/saveBbsCn.file")
    public ResponseEntity<?> saveBbsCn(@RequestPart BbsCnVO bbsCn, List<MultipartFile> multipartFileList, List<MultipartFile> multipartImgList) throws Exception {

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

        // 게시판 내용 등록
        HashMap<String, Object> result = bbsCnService.saveBbsCn(bbsCn, multipartFileList, multipartImgList);
        int insertResult = (int) result.get("result");

        if (insertResult > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 등록되었습니다.");
            responseData.setData(result);
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else if (insertResult == -1){
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("아래의 금지어가 포함되어 있습니다.\n* " + result.get("word"));
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);

        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("등록에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * @author  하석형
     * @since   2024.05.09
     * @param   params
     * @return
     * @throws  Exception
     *
     * 게시판 내용 목록 조회
     */
    @PostMapping("/findAll.json")
    public ResponseEntity<?> findAll(@RequestBody HashMap<String, String> params) throws Exception {
        // 게시판 내용 목록 조회
        Map<String, Object> result = bbsCnService.findAllBbsCn(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.05.09
     * @param  bbsCnVO
     * @return
     * @throws Exception
     *
     * 게시판 내용 상세 조회
     */
    @PostMapping("/findByBbsCn.json")
    public ResponseEntity<?> findByBbsCn(@RequestBody BbsCnVO bbsCnVO) throws Exception {

        // 게시판 관리 정보 조회
        BbsMngVO bbsMng = bbsMngService.findByBbsMngId(bbsCnVO.getBbsMngId());
        // 게시판 내용 상세 조회
        BbsCnVO bbsCn = bbsCnService.findByBbsId(bbsCnVO.getBbsId());
        // 첨부파일 목록 조회
        String fileMngId = bbsCn.getAtchFileMngId();
        List<HashMap<String,Object>> fileList = bbsCnService.fileListPathChange(fileMngId);
        //이미지 파일 목록 조회
        String imgFileMngId = bbsCn.getImgFileMngId();
        List<HashMap<String,Object>> imgFileList = bbsCnService.fileListPathChange(imgFileMngId);


        // 이전글 다음글 조회
        BbsCnVO prevBbsCn = bbsCnService.findPrevBbsCn(bbsCnVO);
        BbsCnVO nextBbsCn = bbsCnService.findNextBbsCn(bbsCnVO);

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("bbsMng", bbsMng);
        result.put("bbsCn", bbsCn);
        result.put("fileList", fileList);
        result.put("imgFileList", imgFileList);
        result.put("prevBbsCn", prevBbsCn);
        result.put("nextBbsCn", nextBbsCn);

        // 응답 처리
        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.09
//     * @param  bbsCnVO
//     * @return
//     * @throws Exception
//     *
//     * 게시판 내용 수정
//     */
//    @PostMapping("/updateProc.json")
//    public ResponseEntity<?> updateProc(@RequestBody BbsCnVO bbsCnVO) throws Exception {
//        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
//        ResponseData responseData = new ResponseData();
//
//        // 게시판 내용 수정
//        int result = bbsCnService.updateBbsCn(bbsCnVO);
//
//        // 응답 처리
//        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.05.21
     * @param params, multipartFileList
     * @return
     * @throws Exception
     *
     * 게시판 내용 수정
     */
    @PostMapping(path = "/updateBbsCn.file")
    public ResponseEntity<?> updateBbsCn(@RequestPart HashMap<String, Object> params, @RequestPart List<HashMap<String, Object>> deleteFileList, List<MultipartFile> multipartFileList, @RequestPart List<HashMap<String, Object>> deleteImgFileList, List<MultipartFile> multipartImgList) throws Exception {

        // 게시판 내용 수정
        HashMap<String, Object> result = bbsCnService.updateBbsCn(params, deleteFileList, multipartFileList, deleteImgFileList, multipartImgList);

        int updateResult = (int) result.get("result");
        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        if (updateResult > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 게시글이 수정 되었습니다.");
            responseData.setData(params.get("bbsId"));
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else if (updateResult == -1){
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("아래의 금지어가 포함되어 있습니다.\n* " + result.get("word"));
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);

        } else {
            responseData.setStatus(HttpStatus.BAD_REQUEST);
            responseData.setMessage("게시글 수정에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * @author 하석형
     * @since  2024.05.09
     * @param  bbsCnVO
     * @return
     * @throws Exception
     *
     * 게시판 내용 삭제
     */
    @PostMapping("/deleteProc.json")
    public ResponseEntity<?> deleteProc(@RequestBody BbsCnVO bbsCnVO) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();

        // 게시판 내용 수정
        int result = bbsCnService.deleteBbsCn(bbsCnVO);

        // 응답 처리
        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.05.22
     * @param  params
     * @return
     * @throws Exception
     *
     * 조회수 증가
     */
    @PostMapping("/updateVwCnt.json")
    public ResponseEntity<?> updateVwCnt(@RequestBody HashMap<String, Object> params) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();
        
        // 조회수 증가
        int result = bbsCnService.updateVwCnt(params);

        // 응답 처리
        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.05.21
     * @param  fileId
     * @return
     * @throws Exception
     *
     * 게시판 첨부 파일 다운로드
     */
    @PostMapping("/fileDownload.json")
    public void fileDownload(@RequestBody int fileId, HttpServletResponse response) throws Exception {

        // 파일 정보 조회
        FileVO file = fileService.fileSelectOne(fileId);
        File downloadFile = null;
        // 받은 파일 정보로 파일 다운로드 생성
        if(file != null){
            String filePath = file.getAbsltPath();
            downloadFile = new File(filePath);

            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(file.getFileNm(), "UTF-8") + "\"");
            response.setHeader("Content-Transfer-Encoding", "binary");

            try (OutputStream out = response.getOutputStream(); FileInputStream fis = new FileInputStream(downloadFile)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
            }
        }
    }


    /********* 질의형 게시판 **********/

    /**
     * @author  방선주
     * @since   2024.05.31
     * @param   bbsCnVO
     * @return
     * @throws  Exception
     *
     * 질의형 게시판 답변 등록
     */
    @PostMapping("/ansSaveProc.json")
    public ResponseEntity<?> ansSaveProc(@RequestBody BbsCnVO bbsCnVO) throws Exception {
        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();

//        int result = 1;
        HashMap<String, Object> result = bbsCnService.saveAnswer(bbsCnVO);
        int insertResult = (int) result.get("result");


        if(insertResult > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 등록 처리되었습니다.");
            responseData.setData(result);
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else if (insertResult == -1){
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("아래의 금지어가 포함되어 있습니다.\n* " + result.get("word"));
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);

        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("등록에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    /**
     * @author  방선주
     * @since   2024.05.31
     * @param   bbsCnVO
     * @return
     * @throws  Exception
     *
     * 질의형 게시판 답변 수정
     */
    @PostMapping("/ansUpdateProc.json")
    public ResponseEntity<?> ansUpdateProc(@RequestBody BbsCnVO bbsCnVO) throws Exception {
        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();

//        int result = 1;
        HashMap<String, Object> result = bbsCnService.updateAnswer(bbsCnVO);
        int updateResult = (int) result.get("result");

        if(updateResult > 0) {
            responseData.setStatus(HttpStatus.OK);
            responseData.setMessage("정상적으로 수정 처리되었습니다.");
            responseData.setData(result);
            return new ResponseEntity<>(responseData, headers, HttpStatus.OK);
        } else if (updateResult == -1){
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("아래의 금지어가 포함되어 있습니다.\n* " + result.get("word"));
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);

        } else {
            responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
            responseData.setMessage("수정에 실패하였습니다.\n담당자에게 문의하세요.");
            return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    /**
     * @author  방선주
     * @since   2024.06.07
     * @param   bbsCnVO
     * @return
     * @throws  Exception
     *
     * 질의형 게시판 답변 삭제
     */
    @PostMapping("/ansDeleteProc.json")
    public ResponseEntity<?> ansDeleteProc(@RequestBody BbsCnVO bbsCnVO) throws Exception {
        // 응답 처리
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
        ResponseData responseData = new ResponseData();

//        int result = 1;
        int result = bbsCnService.deleteAns(bbsCnVO);

        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);
        }
    }
    /**
     * @author  방선주
     * @since   2024.06.13
     * @param
     * @return
     * @throws  Exception
     *
     * 공지사항 최신 5개 조회
     */
    @PostMapping("/findFiveNotice.json")
    public ResponseEntity<?> findFiveNotice(@RequestBody BbsCnVO bbsCn) throws Exception {
        // 공지사항 최신 5개 조회
        List<BbsCnVO> result = bbsCnService.findFiveNotice(bbsCn);

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