package com.its.web.service.common;

import com.its.web.dto.common.CodeDto;
import com.its.web.dto.common.ConnStatisticsDto;
import com.its.web.dto.common.TbWwwOrgDto;
import com.its.web.dto.common.YearDto;
import com.its.web.mapper.its.common.CommonMapper;
import com.its.web.util.MultipartFileSender;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Slf4j
@RequiredArgsConstructor
@Service
public class CommonService {
    private final CommonMapper mapper;

    @Value("${image-location}")
    String imageLocation;

    @Value("${video-location}")
    String videoLocation;

    /**
     * 공공기관 사이트 URL
     * @return List<TbWwwOrgDto>
     */
    public List<TbWwwOrgDto> findAllOrganization() {
        return this.mapper.findAllOrganization();
    }

    /**
     * Day Code 리스트
     * @return List<CodeDto>
     */
    public List<CodeDto> findDayList() {
        return this.mapper.findDayList();
    }

    /**
     * 접속자 조회 통계
     * @return List<ConnStatisticsDto>
     */
    public List<ConnStatisticsDto> getConnStatistics(ConnStatisticsDto.ConnStatisticsDtoReq req) {
        String type = req.getType();
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("type", type);
        paramMap.put("fromDate", req.getFromDate());
        paramMap.put("toDate", req.getToDate());
        if ("week".equals(type)) {
            return this.mapper.getConnWeekStatistics(paramMap);
        }
        else if ("month".equals(type)) {
            return this.mapper.getConnMonthStatistics(paramMap);
        }
        else if ("year".equals(type)) {
            return this.mapper.getConnYearStatistics(paramMap);
        }
        return this.mapper.getConnStatistics(paramMap);
    }

    /**
     * 접속자 이력 등록
     * @return DB 등록 수
     */
    public int insertConnHs() { return this.mapper.insertConnHs(); }

    public void getVideo(String fileName, HttpServletRequest req, HttpServletResponse res) {
        String path = videoLocation + "\\" + fileName;
        File file = new File(path);
        try {
            MultipartFileSender.fromFile(file).with(req).with(res).serveResource();
        }
        catch (IOException ex) {
            log.error("Cause IOException");
        }
    }

    public String imageUpload(HttpServletRequest req) {
        String uploadImageInfo = "";
        String fileName = req.getHeader("file-name");
        try {
            fileName = URLDecoder.decode(fileName, "UTF-8");
        }
        catch (UnsupportedEncodingException exception) {
            log.error("Can not Decoding UTF-8");
        }
        String filePath = imageLocation;
        File file = new File(filePath);
        boolean isMkdirs = true;
        if (!file.exists()) {
            file.setExecutable(false, true); /*파일 실행 권한 설정 (파라미터 - 일반, 소유자)*/
            file.setReadable(true); /*파일 읽기 권한 설정*/
            file.setWritable(false, true);
            isMkdirs = file.mkdirs();
        }

        if (isMkdirs) {
            String realFileNm;
            realFileNm = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));
            String rlFileNm = filePath + File.separator + realFileNm;
            OutputStream os = null;
            try (
                    InputStream is = req.getInputStream()
            ) {
                os = new FileOutputStream(rlFileNm);
                int numRead;
                byte[] byteArray = new byte[Integer.parseInt(req.getHeader("file-size"))];
                if (is != null) {
                    while ((numRead = is.read(byteArray, 0, byteArray.length)) != -1) {
                        os.write(byteArray, 0, numRead);
                    }
                }
                os.flush();
            } catch (IOException e) {
                log.error("noticeImgupload() IO Exception");
            } catch (Exception e1) {
                log.error("noticeImgupload() Exception");
            }
            finally {
                if(os != null) {
                    try{
                        os.close();
                    }
                    catch (IOException e) {
                        log.error("Cause IOException...");
                    }
                }
            }
            uploadImageInfo += "&bNewLine=true";
            uploadImageInfo += "&sFileName=" + fileName;
            uploadImageInfo += "&sFileURL=" + "/api/common/upload/" + realFileNm;
        }

        return uploadImageInfo;
    }

    public byte[] upload(String imageName) {
        byte[] image = null;
        File file = new File(imageLocation, imageName);

        int fileSize = (int) file.length();
        if (fileSize > 0) {
            try {
                byte[] byteArray = FileUtils.readFileToByteArray(file);
                if (byteArray.length > 0) {
                    int ii = 0;
                    image = new byte[byteArray.length];
                    for (byte b : byteArray) {
                        image[ii++] = b;
                    }
                }
            } catch (FileNotFoundException e) {
                log.error("Not Found File - {}", imageLocation + imageName);
            } catch (IOException e) {
                log.error("Can Not Send Image Cause IOException - {}", imageLocation + imageName);
            }
        }
        return image;
    }

    public List<YearDto> getYearList() { return this.mapper.getYearList(); }
//    public List<YearDto> getYearList() {
//        List<YearDto> list = new ArrayList<>();
//        for (int ii = 2023; ii <= 2024; ii++) {
//            YearDto dto = new YearDto();
//            dto.setRate(String.valueOf(ii));
//            list.add(dto);
//        }
//        return list;
//    }
}
