package egovframework.com.its.web.server.controller;

import egovframework.com.its.web.server.service.AdminService;
import egovframework.com.its.web.server.service.NoticeService;
import egovframework.com.its.web.server.util.PageCriteria;
import egovframework.com.its.web.server.util.SHA256;
import egovframework.com.its.web.server.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@RequiredArgsConstructor
@Controller
@RequestMapping("/ptatms")
public class AdminController {

    private final AdminService adminService;
    private final NoticeService adminNoticeService;
//    @Autowired
//    CommonPath commonPath;
//    private final String IMAGE_FILE_PATH   = commonPath.getImageUploadPath();
    private PageCriteria criteria;

    @PostConstruct
    void init() {
        this.criteria = new PageCriteria();
    }

    @RequestMapping(value = "/index.do", method = RequestMethod.GET)
    public String index(Model model, HttpServletRequest request, HttpServletResponse response) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        if (request.getSession().getAttribute("userId") != null) {
            return "redirect:/ptatms/noticeList.do";
        }
        model.addAttribute("subTitle", "로그인");
        return "admin/index.tiles";
    }

    @ResponseBody
    @RequestMapping(value = "/login.do", method = RequestMethod.POST,	produces = {"application/json; charset=utf8"})
    public Map<String,Object> login(Model model, @RequestBody Map<String,Object> paramMap, HttpSession session){
        model.addAttribute("siteSubInfo", "sub ptatms");
        Map<String, Object> resultMap = adminService.loginCheck(paramMap, session);
        return resultMap;
    }

    @RequestMapping(value = "/logout.do", method = RequestMethod.GET)
    public String logout(Model model, HttpServletRequest request, HttpServletResponse response) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        HttpSession session = request.getSession(false);
        if (session.getAttribute("userId") != null) {
            this.adminService.adminLogoutMake(null);
            request.getSession().removeAttribute("userId");
        }
        return "redirect:/ptatms/index.do";
    }

    @RequestMapping(value = "/modifyInfo.do", method = RequestMethod.GET)
    public String pwChange(Model model, HttpServletRequest request) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "계정 정보변경");
        model.addAttribute("id", request.getSession().getAttribute("userId"));
        return "admin/modiAdmin.tiles";
    }

    @RequestMapping(value = "/popupList.do", method = RequestMethod.GET)
    public String popup(Model model) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "팝업창 관리");
        SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.KOREA);
        Date currentTime = new Date();
        String mTime = mSimpleDateFormat.format(currentTime);
        List<PopupVO> popupList = this.adminService.getPopupList(null);

        SimpleDateFormat transFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
        for (PopupVO vo : popupList) {
            Date date;
            try {
                date = transFormat.parse(vo.getRegdate());
                vo.setRegdate(format.format(date));
                date = transFormat.parse(vo.getPost_from());
                vo.setPost_from(format2.format(date));
                date = transFormat.parse(vo.getPost_to());
                vo.setPost_to(format2.format(date));
            } catch (ParseException e) {
                log.error("/ptatms/popupList.do, can not transFormat Date Data...");
            }
        }

        model.addAttribute("popupList", popupList);
        model.addAttribute("mTime", mTime);

        return "admin/popupList.tiles";
    }


    @RequestMapping(value = {"/noticeList.do", "/noticeList/{page}.do"}, method = RequestMethod.GET)
    public String getNoticeList(Model model, @PathVariable(required = false) String page) {
        HashMap <String, String> paramMap = new HashMap<>();
        if(page != null) {
            paramMap.put("page", page);
        }
        return setNoticeList(model, paramMap, "공지사항 관리", "1", "noticeList");
    }

    public String setNoticeList(Model model, HashMap<String, String> paramMap, String subTitle, String boardId, String page) {
        paramMap.put("boardId", boardId);
        Map<String, Object> resultMap = this.adminNoticeService.selectBoardList(paramMap, this.criteria);
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("noticeList", resultMap.get("noticeList"));
        model.addAttribute("pageMaker", resultMap.get("pageMaker"));
        model.addAttribute("subTitle", subTitle);
        return "admin/"+page+".tiles";
    }

    @RequestMapping(value = "/noticeView/{boardNo}.do", method = RequestMethod.GET)
    public String view(Model model, @PathVariable HashMap<String, String> paramMap) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "공지사항 관리");
        paramMap.put("boardId", "1");
        this.adminNoticeService.updateNoticeReadCount(paramMap);

        NoticeVO result = this.adminNoticeService.selectBoardView(paramMap);
        model.addAttribute("notice", result);
        return "admin/noticeView.tiles";
    }

    @RequestMapping(value = "/noticeWrite.do", method = RequestMethod.GET)
    public String write(Model model) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "공지사항 글쓰기");
        return "admin/noticeWrite.tiles";
    }

    @RequestMapping(value = "/addNotice.do", method = RequestMethod.POST)
    public String addNotice(HttpServletRequest request,
                               @RequestParam List<MultipartFile> attatchFile,
                               @RequestParam Map<String, String> paramMap,
                               @Value("${attach_path}") String attachPath,
                               @Value("${upload_path}") String uploadPath) {
        paramMap.put("boardId", "1");
        String userId = (String)request.getSession().getAttribute("userId");
        this.adminNoticeService.addBoard(attatchFile, userId, paramMap, attachPath, uploadPath);
        return "redirect:/ptatms/noticeList.do";
    }

    @RequestMapping(value = "/removeNotice/{boardNo}.do", method = RequestMethod.GET)
    public String noticeDelete(Model model, @PathVariable HashMap<String, Object> paramMap) {
        paramMap.put("boardId", "1");
        this.adminNoticeService.deleteNotice(paramMap);
        return "redirect:/ptatms/noticeList.do";
    }

    @RequestMapping(value = "/editNotice/{boardNo}.do", method = RequestMethod.GET)
    public String noticeEdit(Model model, @PathVariable HashMap<String, String> paramMap) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "공지사항 수정");
        paramMap.put("boardId", "1");
        model.addAttribute("noticeEdit", this.adminNoticeService.selectBoardView(paramMap));
        return "admin/noticeEdit.tiles";
    }

    @RequestMapping(value = "/modifyNotice.do", method = RequestMethod.POST)
    public String updateNotice(Model model, HttpServletRequest request, HttpServletResponse response,
                               @RequestParam Map<String, String> paramMap,
                               @RequestParam List<MultipartFile> attachFile,
                               @RequestParam List<String> attachFileName,
                               @Value("${attach_path}") String attachPath,
                               @Value("${upload_path}") String uploadPath
                               ) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        paramMap.put("boardId", "1");
        this.adminNoticeService.updateBoard(attachFile, paramMap, attachFileName, attachPath, uploadPath);
        if (request.getParameter("boardNo") != null) {
            String boardNo = request.getParameter("boardNo");
            return "redirect:/ptatms/noticeView/" + boardNo + ".do";
        }
        else {
            return "redirect:/ptatms/noticeList.do";
        }
    }

    @RequestMapping(value = {"/archiveList.do", "/archiveList/{page}.do"}, method = RequestMethod.GET)
    public String archiveListPage(Model model, @PathVariable(required = false) String page) {
        HashMap<String, String> paramMap = new HashMap<>();
        if (page != null) {
            paramMap.put("page", page);
        }
        return setNoticeList(model, paramMap, "자료실 관리", "2", "archiveList");
    }

    @RequestMapping(value = "/archiveView/{boardNo}.do", method = RequestMethod.GET)
    public String archiveView(Model model, @PathVariable HashMap<String, String> paramMap) {

        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "자료실 관리");
        paramMap.put("boardId", "2");

        NoticeVO result = this.adminNoticeService.selectBoardView(paramMap);
        model.addAttribute("notice", result);

        return "admin/archiveView.tiles";
    }

    @RequestMapping(value = "/archiveWrite.do", method = RequestMethod.GET)
    public String archiveWrite(Model model) {
        model.addAttribute("subTitle", "자료실 글쓰기");
        model.addAttribute("siteSubInfo", "sub ptatms");
        return "admin/archiveWrite.tiles";
    }

    @RequestMapping(value = "/archiveEdit/{boardNo}.do", method = RequestMethod.GET)
    public String archiveEdit(Model model, @PathVariable HashMap<String, String> paramMap) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "자료실 수정");
        paramMap.put("boardId", "2");
        model.addAttribute("noticeEdit", this.adminNoticeService.selectBoardView(paramMap));
        return "admin/archiveEdit.tiles";
    }

    @RequestMapping(value = "/addArchive.do", method = RequestMethod.POST)
    public String addArchive(HttpServletRequest request,
                               @RequestParam List<MultipartFile> attatchFile,
                               @RequestParam Map<String, String> paramMap,
                               @Value("${attach_path}") String attachPath,
                               @Value("${upload_path}") String uploadPath) {
        paramMap.put("boardId", "2");
        String userId = (String)request.getSession().getAttribute("userId");
        this.adminNoticeService.addBoard(attatchFile, userId, paramMap, attachPath, uploadPath);
        return "redirect:/ptatms/archiveList.do";
    }

    @RequestMapping(value = "/modifyArchive.do", method = RequestMethod.POST)
    public String updateArchive(Model model, HttpServletRequest request,
                                @RequestParam Map<String, String> paramMap,
                                @RequestParam List<MultipartFile> attachFile,
                                @RequestParam List<String> attachFileName,
                                @Value("${attach_path}") String attachPath,
                                @Value("${upload_path}") String uploadPath
                                ) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        paramMap.put("boardId", "2");
        this.adminNoticeService.updateBoard(attachFile, paramMap, attachFileName, attachPath, uploadPath);

        if (request.getParameter("boardNo") != null) {
            String boardNo = request.getParameter("boardNo");
            return "redirect:/ptatms/archiveView/" + boardNo + ".do";
        }
        else {
            return "redirect:/ptatms/archiveList.do";
        }
    }

    @RequestMapping(value = "/removeArchive/{boardNo}.do", method = RequestMethod.GET)
    public String deleteArchive(Model model, @PathVariable HashMap<String, Object> paramMap) {
        paramMap.put("boardId", "2");
        this.adminNoticeService.deleteNotice(paramMap);
        return "redirect:/ptatms/archiveList.do";
    }

    @RequestMapping(value = "/editPopup.do", method = RequestMethod.POST)
    public String editPopup(Model model, @RequestParam Map<String, Object> paramMap) {
        model.addAttribute("subTitle", "팝업창 관리");
        model.addAttribute("siteSubInfo", "sub ptatms");
        List<PopupVO> popup = this.adminService.getPopupList(paramMap);
        popup.get(0).setPost_from(popup.get(0).getPost_from().substring(0, 10));
        popup.get(0).setPost_to(popup.get(0).getPost_to().substring(0, 10));
        model.addAttribute("popup", popup.get(0));
        return "admin/editPopup.tiles";
    }

    @RequestMapping(value = "/popupAdd.do", method = RequestMethod.POST)
    public String popupadd(Model model, HttpServletRequest request, HttpServletResponse response,
                              @RequestParam("popupImg") MultipartFile file,
                              @RequestParam Map<String, Object> paramMap,
                              @Value("${attach_path}") String attachPath,
                              @Value("${upload_path}") String uploadPath
                              ) {
        Map<String, Object> resultMap = this.adminNoticeService.uploadFiles(file, true, attachPath, uploadPath);
        Boolean isWriteSuccess = (Boolean) resultMap.get("isWriteSuccess");
        String fileUuid = (String) resultMap.get("fileId");
        String fileName = (String) resultMap.get("fileName");

        if (isWriteSuccess) {
            paramMap.put("postFrom", paramMap.get("postFrom").toString().replace("-", ""));
            paramMap.put("postTo", paramMap.get("postTo").toString().replace("-", ""));
            paramMap.put("imgId", fileUuid);
            paramMap.put("imgName", fileName);

            this.adminService.addPopup(paramMap);
        }

        return "redirect:/ptatms/popupList.do";
    }

    @RequestMapping(value = "/modifyPopupUseYN.do", method = RequestMethod.POST)
    public String updatePopupUseYN(Model model, @RequestParam Map<String, Object> paramMap) {
        this.adminService.updatePopupUseYN(paramMap);
        return "redirect:/ptatms/popupList.do";
    }

    @RequestMapping(value = "/removePopup.do", method = RequestMethod.POST)
    public String removePopup(Model model, HttpServletRequest request, @RequestParam Map<String, Object> paramMap,
                              @Value("${upload_path}") String IMAGE_FILE_PATH) {
        List<PopupVO> listVo = this.adminService.getPopupList(paramMap);
        String imgFileName = listVo.get(0).getImg_id();

        if (!"".equals(imgFileName) && imgFileName != null) {
            String imguploadPath = IMAGE_FILE_PATH;
            File tempImgFile = new File(imguploadPath, imgFileName);
            tempImgFile.setExecutable(false, true);
            tempImgFile.setReadable(true);
            tempImgFile.setWritable(false, true);
            if (tempImgFile.exists()) {
                tempImgFile.delete();
            }
        }

        this.adminService.deletePopup(paramMap);

        return "redirect:/ptatms/popupList.do";

    }

    @RequestMapping(value = "/modifyPopup.do", method = RequestMethod.POST)
    public String updatePopup(Model model, HttpServletRequest request,
                              @RequestParam Map<String, Object> paramMap,
                              @RequestParam("popupImg") MultipartFile file,
                              @Value("${attach_path}") String attachPath,
                              @Value("${upload_path}") String uploadPath
                              ) {
        List<PopupVO> popup = this.adminService.getPopupList(paramMap);
        PopupVO vo = popup.get(0);
        boolean isWriteSuccess = true;
        String fileUuid = "";
        String fileName = "";
        
        if (vo.getImg_name() != null && vo.getImg_name().equals(paramMap.get("img_name"))) {
            fileUuid = vo.getImg_id();
            fileName =  vo.getImg_name();
        }
        else {
            Map<String, Object> resultMap = this.adminNoticeService.uploadFiles(file, true, attachPath, uploadPath);
            isWriteSuccess = (Boolean) resultMap.get("isWriteSuccess");
            fileUuid = (String) resultMap.get("fileId");
            fileName = (String) resultMap.get("fileName");

        }
        if (isWriteSuccess) {
            paramMap.put("imgId", fileUuid);
            paramMap.put("imgName", fileName);
            this.adminService.updatePopup(paramMap);
        }
        return "redirect:/ptatms/popupList.do";
    }

    @ResponseBody
    @RequestMapping(value = "/checkPrePw.do", method = RequestMethod.POST)
    public AdminInfoVO checkPrePw(@RequestParam Map<String, Object> paramMap) {
        String pw = paramMap.get("pw").toString();
        if (pw != null) {
            pw = pw.replaceAll("<", "&lt;");
            pw = pw.replaceAll(">", "&gt;");
        }
        String encodePassword = SHA256.encrypt(pw);//원본

        paramMap.put("prePw", encodePassword);
        return this.adminService.checkPrePw(paramMap);
    }

    @RequestMapping(value = "/pwUpdate.do", method = RequestMethod.POST)
    public String pwUpdate(Model model, HttpServletRequest request, @RequestParam Map<String, Object> paramMap) {

        paramMap.put("pwd", SHA256.encrypt(paramMap.get("afterPw").toString()));//원본

        this.adminService.updatePw(paramMap);
        HttpSession session = request.getSession();
        session.invalidate();
        return "redirect:/ptatms/index.do";
    }

    @RequestMapping(value = "/status.do", method = RequestMethod.GET)
    public String stats(Model model, HttpServletRequest request, HttpServletResponse response) {
        model.addAttribute("siteSubInfo", "sub ptatms");
        model.addAttribute("subTitle", "접속통계");
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumIntegerDigits(2);

        Calendar cal = Calendar.getInstance();

        model.addAttribute("thisYear", Integer.toString(cal.get(Calendar.YEAR)));
        model.addAttribute("thisMonth", nf.format(cal.get(Calendar.MONTH) + 1));
        model.addAttribute("thisDate", nf.format(cal.get(Calendar.DATE)));
        model.addAttribute("lastDate", "31");
        model.addAttribute("thisHour", nf.format(cal.get(Calendar.HOUR_OF_DAY)));
        return "admin/status.tiles";
    }

    @RequestMapping(value = "/getStatsList.do", method = RequestMethod.POST)
    public @ResponseBody List<StatsVO> getStatsList(@RequestParam Map<String, Object> paramMap) {
        List<StatsVO> result = null;
        if (paramMap.get("date") != null) {
            String date     = (String)paramMap.get("date");
            paramMap.put("statDate", date);
            result = this.adminService.getHHStatus(paramMap);
        }
        return result;
    }

    @RequestMapping(value = "/getYearStatsList.do", method = RequestMethod.POST)
    public @ResponseBody List<PeriodStatVO> getYearStatsList(@RequestParam Map<String, Object> paramMap) {
        return this.adminService.getYearStatsList(paramMap);
    }

    @RequestMapping(value = "/getMonthStatsList.do", method = RequestMethod.POST)
    public @ResponseBody List<PeriodStatVO> getMonthStatsList(@RequestParam Map<String, Object> paramMap) {
        return this.adminService.getMonthStatsList(paramMap);
    }

    @RequestMapping(value = "/getHourStatsList.do", method = RequestMethod.POST)
    public @ResponseBody List<PeriodStatVO> getHourStatsList(@RequestParam Map<String, Object> paramMap) {
        return this.adminService.getHourStatsList(paramMap);
    }

    /* Naver editor 사진첨부하기 설정*/
    @RequestMapping(value = "/noticeImgupload.do", method = RequestMethod.POST)
    public @ResponseBody String noticeImgUpload(
            Model model,
            HttpServletRequest request,
            HttpServletResponse response,
            @Value("${upload_path}") String IMAGE_FILE_PATH
    ) {
        String sFileInfo = "";
        String filename = request.getHeader("file-name");

        String filePath = IMAGE_FILE_PATH;
        File file = new File(filePath);
        file.setExecutable(false, true);
        file.setReadable(true);
        file.setWritable(false, true);

        if (!file.exists()) {
            file.mkdirs();
        }

        String realFileNm;
        realFileNm = UUID.randomUUID().toString().replace("-", "") + filename.substring(filename.lastIndexOf("."));
        String rlFileNm = filePath + File.separator + realFileNm;
        InputStream is = null;
        OutputStream os = null;
        try {
            is = request.getInputStream();
            os = new FileOutputStream(rlFileNm);
            int numRead;
            byte b[] = new byte[Integer.parseInt(request.getHeader("file-size"))];
            if (is != null) {
                while ((numRead = is.read(b, 0, b.length)) != -1) {
                    os.write(b, 0, numRead);
                }
            }
            os.flush();
        } catch (IOException e) {
            log.error("noticeImgupload() IO Exception");
        } catch (Exception e1) {
            log.error("noticeImgupload() Exception");
        }
        finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            }
            catch (IOException i) {
                log.error("noticeImgupload() IO Exception");
            }
        }

        sFileInfo += "&bNewLine=true";
        sFileInfo += "&sFileName=" + filename;
        sFileInfo += "&sFileURL=" + "/upload/" + realFileNm;

        return sFileInfo;
    }

    @RequestMapping(value = "/noticeImguploadSingle.do", method = RequestMethod.POST)
    public String noticeImguploadSingle(
            Model model,
            HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam("Filedata") MultipartFile file,
            @Value("${upload_path}") String IMAGE_FILE_PATH
    ) {

        String callback = request.getParameter("callback");
        String callbackFunc = request.getParameter("callback_func");

        File uploadFileHome = new File(IMAGE_FILE_PATH);
        uploadFileHome.setExecutable(false, true);
        uploadFileHome.setReadable(true);
        uploadFileHome.setWritable(false, true);

        String fileName;
        String fileUuid;
        String fileResult = "";
        fileName = file.getOriginalFilename();
        if (!"".equals(fileName) && fileName != null) {
            if (fileName.endsWith(".jsp") || fileName.endsWith(".js") || fileName.endsWith(".html") || fileName.endsWith(".htm")) {
                log.error("/ptatms/addNotice.do, Check the file types....");
                fileResult = "&errstr=error";
            }
            else {
                String fileExe = fileName.substring(fileName.lastIndexOf("."));

                fileUuid = UUID.randomUUID().toString().replace("-", "") + fileExe;

                File uploadImgFile = new File(uploadFileHome, fileUuid);
                if (uploadImgFile != null) {
                    fileResult = "&bNewLine=true&sFileName=" + fileName + "&sFileURL=/upload/" + fileUuid;

                    try {
                        if (file.getSize() <= 200000000) {
                            file.transferTo(uploadImgFile);
                        } else {
                            log.error("/ptatms/noticeImguploadSingle.do, PopupImage is Too Large Size(Limit Size 200000000)");
                        }
                    } catch (IllegalStateException | IOException e) {
                        log.error("/ptatms/noticeImguploadSingle.do, can not transfetTo uploadImgFile...");
                    }
                }
            }
        } else{
            fileResult = "&errstr=error";
        }

        return "redirect:" + callback + "?callback_func=" + callbackFunc + fileResult;
    }

}