package com.dbnt.kcscbackend.admin.contents.popUp.service.impl;


import com.dbnt.kcscbackend.admin.contents.popUp.model.CreatePopupVO;
import com.dbnt.kcscbackend.admin.contents.popUp.model.FileVO;
import com.dbnt.kcscbackend.admin.contents.popUp.model.UpdatePopupVO;
import com.dbnt.kcscbackend.admin.contents.popUp.repository.TnPopupMngRepositoryWithoutPopupContents;
import com.dbnt.kcscbackend.admin.contents.popUp.service.PopUpApiService;
import com.dbnt.kcscbackend.file.entity.TnAttachFile;
import com.dbnt.kcscbackend.file.repository.TnAttachFileRepository;
import com.dbnt.kcscbackend.file.service.EgovFileMngUtil;
import com.dbnt.kcscbackend.auth.entity.LoginVO;
import com.dbnt.kcscbackend.commonCode.entity.TnPopupMng;
import com.dbnt.kcscbackend.commonCode.repository.TnPopupMngRepository;
import com.dbnt.kcscbackend.config.common.ResponseCode;
import com.dbnt.kcscbackend.config.common.ResultVO;
import com.dbnt.kcscbackend.file.service.FileService;
import com.dbnt.kcscbackend.util.NetworkUtil;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service("popUpApiService")
@RequiredArgsConstructor
public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopUpApiService {

	private final TnPopupMngRepository tnPopupMngRepository;
	private final TnPopupMngRepositoryWithoutPopupContents tnPopupMngRepositoryWithoutPopupContents;

	private final FileService fileService;


	@Override
	public ResultVO contentsApiPopUpManageList(ResultVO resultVO, HttpServletRequest request, LoginVO user, Pageable pageable) throws Exception {

		System.out.println(
			"\n--------------------------------------------------------------\n" +
			request.getRequestURI() + " IN:" +
			"\n--------------------------------------------------------------\n" +
			"user.getEmail():" + "\n" +
			user.getEmail() + "\n" +
			"\n--------------------------------------------------------------\n"
		);


		Long totalRecordCount 	= tnPopupMngRepositoryWithoutPopupContents.count();
		AtomicInteger index = new AtomicInteger();
		//List<Map<String, Object>> listPopup = tnPopupMngRepositoryWithoutPopupContents.findAll(Sort.by(Sort.Direction.DESC, "popupSeq"))
		List<Map<String, Object>> listPopup = tnPopupMngRepositoryWithoutPopupContents.findAll(pageable)
				.stream()
				.map(item -> {
					Map<String, Object> codeMap = new HashMap<>();
					codeMap.put("number", totalRecordCount - (long) pageable.getPageNumber() * pageable.getPageSize() - index.getAndIncrement());
					codeMap.put("seq", item.getPopupSeq());
					codeMap.put("popupTitle", item.getPopupTitle());
					codeMap.put("startDate", item.getPopupStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
					codeMap.put("endDate", item.getPopupEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
					codeMap.put("createUserId", item.getFrstCrtId());
					codeMap.put("updateUserId", item.getLastChgId());
					codeMap.put("fileGrpId", item.getFileGrpId());
					codeMap.put("contents", null);
					codeMap.put("useYn", item.getUseYn());
					codeMap.put("createDate", item.getFrstCrtDt());
					codeMap.put("updateDate", item.getLastChgDt());
					codeMap.put("base64String", null);
					return codeMap;
				})
				.collect(Collectors.toList());

		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(pageable.getPageNumber()+1);
		paginationInfo.setRecordCountPerPage(pageable.getPageSize());
		paginationInfo.setPageSize(5);//hard coded
		paginationInfo.setTotalRecordCount(totalRecordCount.intValue());//hard coded

		Map<String, Object> dto = new HashMap<String, Object>();
		dto.put("listPopup", listPopup);
		dto.put("paginationInfo", paginationInfo);
		resultVO.setResult(dto);
		resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
		resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());

		return resultVO;
	}





	@Override
	public ResultVO contentsApiPopUpManageCreate(ResultVO resultVO, HttpServletRequest request, LoginVO user, final MultipartHttpServletRequest multiRequest, CreatePopupVO createPopupVO, MultipartFile[] files) throws Exception {

		System.out.println(
				"\n--------------------------------------------------------------\n" +
						request.getRequestURI() + " IN:" +
						"\n--------------------------------------------------------------\n" +
						"user.getEmail():" + "\n" +
						user.getEmail() + "\n" +
						"\n--------------------------------------------------------------\n"
		);


		String fileGrpId = fileService.addTnAttachFile(request, user, files, this.getMiddlePath());

		Map<String, Object> response = tnPopupMngRepository.spAddTnPopupMng(
				createPopupVO.getTitle(),
				createPopupVO.getStartDate(),
				createPopupVO.getEndDate(),
				fileGrpId,
				createPopupVO.getContents(),
				"kcsc_admin",
				null,
				null,
				null,
				null
		);


		Map<String, Object> dto = new HashMap<String, Object>();
		dto.put("popupSeq", response.get("_popup_seq") );

		resultVO.setResult(dto);
		resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
		resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());

		return resultVO;
	}


	@Override
	public ResultVO contentsApiPopUpManageRead(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long popupId) throws Exception {

		System.out.println(
			"\n--------------------------------------------------------------\n" +
			request.getRequestURI() + " IN:" +
			"\n--------------------------------------------------------------\n" +
			"user.getEmail():" + "\n" +
			user.getEmail() + "\n" +
			"popupId:" + "\n" +
			popupId + "\n" +
			"\n--------------------------------------------------------------\n"
		);


		int isValid = tnPopupMngRepository.spIsValidTnPopupMngId( popupId.intValue() );

		if( isValid == 0 ) {
			throw new Exception("대상이 존재하지 않습니다.");
		}

		TnPopupMng tnPopupMng 				= tnPopupMngRepository.findByPopupSeq(popupId);


		Map<String, Object> dto 			= new HashMap<String, Object>();
		dto.put("title", tnPopupMng.getPopupTitle());																					// 팝업 제목
		dto.put("contents", tnPopupMng.getPopupContents());																				// 팝업 내용
		dto.put("schdulBgnde", tnPopupMng.getPopupStartDate().plusHours(9).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));		// 날짜/시간의 시작 일시 - yyyyMMddHHmmss
		dto.put("schdulEndde", tnPopupMng.getPopupEndDate().plusHours(9).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));		// 날짜/시간의 종료 일시 - yyyyMMddHHmmss

		//첨부파일명을 가져온다.
		List<TnAttachFile> tnAttachFileList = fileService.findByFileGrpId(tnPopupMng.getFileGrpId());

		if( tnAttachFileList != null ) {
			List<Map<String, Object>> files = new ArrayList<Map<String, Object>>();
			for (TnAttachFile item : tnAttachFileList) {
				Map<String, Object> fileDto = new HashMap<String, Object>();
				fileDto.put("seq", item.getFileSeq());
				fileDto.put("name", item.getFileOldName());
				files.add(fileDto);
			}
			dto.put("files", files);
		} else {
			dto.put("files", null);
		}





		resultVO.setResult(dto);
		resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
		resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());

		return resultVO;
	}

	@Override
	public ResultVO contentsApiPopUpManageUpdate(ResultVO resultVO, HttpServletRequest request, LoginVO user, UpdatePopupVO updatePopupVO, MultipartFile[] files, long[] survivingFiles, Long popupSeq) throws Exception {
		System.out.println(
				"\n--------------------------------------------------------------\n" +
				request.getRequestURI() + " IN:" +
				"\n--------------------------------------------------------------\n" +
				"updatePopupVO:" + "\n" +
				updatePopupVO.toString() + "\n" +
				"popupSeq:" + "\n" +
				popupSeq + "\n" +
				"\n--------------------------------------------------------------\n"
		);

		// 유효성 검사 실시
		int isValid = tnPopupMngRepository.spIsValidTnPopupMngId( popupSeq.intValue() );

		if( isValid == 0 ) {
			throw new Exception("대상이 존재하지 않습니다.");
		}

 		if( Long.parseLong(updatePopupVO.getStartDate()) > Long.parseLong(updatePopupVO.getEndDate()) ) {
			throw new Exception("종료일시는 시작일시보다 앞 설 수 없습니다.");
		}

		// 기존 첨부된 file이 있다면 기존 fileGrpId을 활용한다.
		TnPopupMng tnPopupMng = tnPopupMngRepository.findByPopupSeq(popupSeq);

		String fileGrpId = tnPopupMng.getFileGrpId();
		List<TnAttachFile> tnAttachFileList = fileService.findByFileGrpId(tnPopupMng.getFileGrpId());

		if( survivingFiles == null ) {

			//기존 file을 모두 삭제한다.
			if( fileGrpId != null ) {
				if( tnAttachFileList != null ) {
					for (TnAttachFile item : tnAttachFileList) {
						fileService.deleteTnAttachFile(request, user, item.getFileSeq().longValue());
					}
				}
				fileGrpId = null;
			}
		} else {
			// 살아남은 file을 제외한 나머지 file을 삭제한다.
			if( tnAttachFileList != null ) {
				boolean isFound = false;
				for (TnAttachFile item : tnAttachFileList) {
					for( long oldFileSeq : survivingFiles) {
						if( oldFileSeq == item.getFileSeq() ) {
							isFound = true;
							break;
						}
					}
					if( !isFound ) {
						fileService.deleteTnAttachFile(request, user, item.getFileSeq().longValue());
					}
					isFound = false;
				}
			}

		}

		fileGrpId = fileService.addTnAttachFile(request, user, files, this.getMiddlePath(), fileGrpId);


		Map<String, Object> response = tnPopupMngRepository.spUpdateTnPopupMng(
			popupSeq.intValue(),
			updatePopupVO.getTitle(),
			updatePopupVO.getStartDate(),
			updatePopupVO.getEndDate(),
			fileGrpId,
			updatePopupVO.getContents(),
				user.getId(),
			null,
			null,
			null
		);


		Map<String, Object> dto = new HashMap<String, Object>();
		dto.put("errorMessage", response.get("_error_message") );
		dto.put("popupId",  popupSeq);

		resultVO.setResult(dto);
		resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
		resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());

		return resultVO;
	}


	@Override
	public ResultVO contentsApiPopUpManageDelete(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long popupId) throws Exception {
		System.out.println(
			"\n--------------------------------------------------------------\n" +
			request.getRequestURI() + " IN:" +
			"\n--------------------------------------------------------------\n" +
			"popupId:" + "\n" +
			popupId + "\n" +
			"\n--------------------------------------------------------------\n"
		);





		Map<String, Object> dto = new HashMap<String, Object>();

		if( false ) {
			// 삭제 procedure가 삭제가 아닌 비활성화만 시키므로 해당 프로시저 사용 안 함.
			Map<String, Object> response = tnPopupMngRepository.spDeleteTnPopupMng(
					popupId.intValue(),
					"admin",
					null,
					null,
					null
			);
			dto.put("errorMessage", response.get("_error_message") );
		} else {
			tnPopupMngRepository.deleteById(popupId);
		}


		dto.put("popupId", popupId );

		resultVO.setResult(dto);
		resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
		resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());

		return resultVO;
	}

	@Override
	public ResultVO contentsApiPopUpManageUpdateActivationSwitch(ResultVO resultVO, HttpServletRequest request, LoginVO user, String checked, Long popupId) throws Exception {
		System.out.println(
				"\n--------------------------------------------------------------\n" +
						request.getRequestURI() + " IN:" +
						"\n--------------------------------------------------------------\n" +
						"checked:" + "\n" +
						checked + "\n" +
						"popupId:" + "\n" +
						popupId + "\n" +
						"\n--------------------------------------------------------------\n"
		);



		// 유효성 검사 실시
		int isValid = tnPopupMngRepository.spIsValidTnPopupMngId( popupId.intValue() );

		if( isValid == 0 ) {
			throw new Exception("대상이 존재하지 않습니다.");
		}

		TnPopupMng tnPopupMng = tnPopupMngRepository.findByPopupSeq(popupId);
		if( Boolean.parseBoolean(checked) ) {
			tnPopupMng.setUseYn("Y");
		} else {
			tnPopupMng.setUseYn("N");
		}

		tnPopupMngRepository.saveAndFlush(tnPopupMng);


		Map<String, Object> dto = new HashMap<String, Object>();
		dto.put("popupId",  popupId);

		resultVO.setResult(dto);
		resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
		resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());

		return resultVO;
	}

	@Override
	public ResultVO deleteFileContentsApiPopUpManage(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long fileSeq) throws Exception {
		System.out.println(
			"\n--------------------------------------------------------------\n" +
			request.getRequestURI() + " IN:" +
			"\n--------------------------------------------------------------\n" +
			"fileSeq:" + "\n" +
			fileSeq + "\n" +
			"\n--------------------------------------------------------------\n"
		);

		Map<String, Object> dto = new HashMap<String, Object>();

		fileService.deleteTnAttachFile(request, user, fileSeq);

		resultVO.setResult(dto);
		resultVO.setResultCode(ResponseCode.SUCCESS.getCode());
		resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage());

		return resultVO;
	}


	/**
	 * 파일이 저장될 중간 경로를 생성한다.
	 * D:/kcscUploadFiles/XXXX/abc.jpg XXXX에 해당하는 경로다.
	 * @return 중간 경로
	 */
	private String getMiddlePath() {
		//파일이 저장될 경로를 생성한다.
		String domainPath = "popup";
		Date nowDate = new Date();
		String strNowYyyy = new SimpleDateFormat("yyyy").format(nowDate);
		String strNowYyyyMmdd = new SimpleDateFormat("yyyyMMdd").format(nowDate);
		String middlePath = domainPath + "/" +  strNowYyyy + "/" + strNowYyyyMmdd + "/";

		return middlePath;
	}





}
