package egovframework.controller;

import egovframework.service.impl.NoticeServiceImpl;
import egovframework.utill.CommonPath;
import egovframework.utill.PageCriteria;
import egovframework.utill.PageMaker;
import egovframework.vo.NoticeVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@RequiredArgsConstructor
@Controller
public class NoticeController {

    private final NoticeServiceImpl noticeService;
    private final String ATTATCH_FILE_PATH = CommonPath.getFilePath();
    private final String IMAGE_FILE_PATH = CommonPath.getImageUploadPath();
    private PageCriteria criteria;

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

    //MAIN 페이지의 공지사항
    @RequestMapping(value = "/notice/noticeList.do", method = RequestMethod.GET)
    public String noticeList(Model model, @RequestParam HashMap<String, String> paramMap) {
        if (paramMap.get("page") != null) {
            this.criteria.setPage(Integer.parseInt(paramMap.get("page")));
        }
        model.addAttribute("siteSubInfo", "sub notice");
        model.addAttribute("subTitle", "공지사항");

        if (paramMap.get("searchText") != null) {
            this.criteria.setSearchType(paramMap.get("searchType"));
            this.criteria.setSearchText(paramMap.get("searchText"));

//			String searchText =new String(paramMap.get("searchText").getBytes("8859_1"), "UTF-8");
//			this.criteria.setSearchText(searchText);
        } else {
            this.criteria.setSearchText("");
        }

        PageMaker pageMaker = new PageMaker();
        pageMaker.setCriteria(this.criteria);
        pageMaker.setTotalCount(this.noticeService.getNoticeTotalCount(paramMap));

        List<NoticeVO> noticeList = this.noticeService.getNoticeList(this.criteria);
        SimpleDateFormat transFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm");
        for (NoticeVO vo : noticeList) {
            Date date = null;
            try {
                date = transFormat.parse(vo.getRegDate());
            } catch (ParseException e) {
                throw new RuntimeException();
            }
            if (date != null) {
                vo.setRegDate(format.format(date));
            }
        }
        model.addAttribute("noticeList", noticeList);
        model.addAttribute("pageMaker", pageMaker);

        return "notice/noticeListNew.tiles";
    }

    @RequestMapping(value = "/notice/noticeView.do", method = RequestMethod.GET)
    public String view(Model model, HttpServletRequest request, HttpServletResponse response,
                       @RequestParam HashMap<String, String> paramMap) {
        model.addAttribute("siteSubInfo", "sub notice");
        model.addAttribute("subTitle", "공지사항 상세페이지");
        this.noticeService.updateNoticeReadCount(paramMap);
        NoticeVO result = this.noticeService.getNotice(paramMap);
        String attatchFile = result.getAttachFile();
        String attatchFileId = result.getAttachFileId();
        if (!attatchFile.equals(null) && !attatchFile.isEmpty()) {
            String[] fileArr = attatchFile.split("[|]", -1);
            List<String> attatchFiles = new ArrayList<>();
            if (fileArr.length > 0) {
                for (String file : fileArr) {
                    attatchFiles.add(file);
                }
            }
            result.setAttatchFiles(attatchFiles);
        }

        if (!attatchFileId.equals(null) && !attatchFileId.isEmpty()) {
            String[] idArr = attatchFileId.split("[|]", -1);
            List<String> attatchFileIds = new ArrayList<>();
            if (idArr.length > 0) {
                for (String id : idArr) {
                    attatchFileIds.add(id);
                }
            }
            result.setAttatchFileIds(attatchFileIds);
        }

        SimpleDateFormat transFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date date = null;
        try {
            date = transFormat.parse(result.getRegDate());
        } catch (ParseException e) {
            log.error("ParseException : /notice/noticeView.do, can not parse date");
        }

        if (date != null) {
            result.setRegDate(format.format(date));
        }

        model.addAttribute("notice", result);

        return "notice/noticeViewNew.tiles";
    }

    @RequestMapping(value = "/notice/getFile.do", method = RequestMethod.GET, produces = "text/plain; charset=UTF8")
    public void getFile(Model model, HttpServletRequest request, HttpServletResponse response, @RequestParam Map<String, Object> paramMap) {
        //request.setCharacterEncoding("UTF-8");
        //System.out.println(paramMap.get("fileName"));

        String CHARSET = "euc-kr";
        File uploadFileHome = new File(ATTATCH_FILE_PATH);

        //String fileName = new String(paramMap.get("fileName").toString().getBytes("8859_1"),"UTF-8");
        String fileName = paramMap.get("fileName").toString();
        String fileId   = paramMap.get("fileId").toString();
        String filtered_name = "";

        if (fileName != null && !"".equals(fileName)) {
            filtered_name = fileName.replaceAll("/", "").replaceAll("&", "").replaceAll("\r", "").replaceAll("\n", "");
        }

        File downloadFile = new File(uploadFileHome, fileId);
        FileInputStream inStream = null;
        OutputStream outStream = null;
        try {
            if (downloadFile != null) inStream = new FileInputStream(downloadFile);

            // obtains ServletContext
            ServletContext context = request.getSession().getServletContext();

            // gets MIME type of the file
            String mimeType = context.getMimeType(downloadFile.getAbsolutePath());
            String filtered_mimeType = "";

            if (mimeType == null) {
                filtered_mimeType = "application/octet-stream";
            } else {
                filtered_mimeType = mimeType.replaceAll("\r", "").replaceAll("\n", "");
            }

            response.setContentType(filtered_mimeType);
            response.setContentLength((int) downloadFile.length());

            String userAgent = request.getHeader("User-Agent");

            if (userAgent != null && userAgent.indexOf("MSIE 5.5") > -1) {// MS IE 5.5

                response.setHeader("Content-Disposition", "filename=" + URLEncoder.encode(filtered_name, "UTF-8") + ";");
            } else if (userAgent != null && userAgent.indexOf("MSIE") > -1) {// MS IE ()
                response.setHeader("Content-Disposition", "attachment; filename="
                        + java.net.URLEncoder.encode(fileName, "UTF-8") + ";");
            } else {
                response.setHeader("Content-Disposition", "attachment; filename="
                        + new String(filtered_name.getBytes(CHARSET), "latin1") + ";");
            }

            // obtains response's output stream
            outStream = response.getOutputStream();

            byte[] buffer = new byte[4096];
            int bytesRead = -1;

            if (inStream != null && inStream.available() > 0) {
                while ((bytesRead = inStream.read(buffer)) != -1) {
                    if (outStream != null) {
                        outStream.write(buffer, 0, bytesRead);
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException();
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }

                if (outStream != null) {
                    outStream.close();
                }
            } catch (IOException e) {
                log.error("IOException : /notice/getFile.do, can not close inStream or outStream");
                throw new RuntimeException();
            }
        }
    }

}