package com.dbnt.sims.publicBoard.service;

import com.dbnt.sims.config.BaseService;
import com.dbnt.sims.config.FileInfo;
import com.dbnt.sims.publicBoard.mapper.PublicBoardMapper;
import com.dbnt.sims.publicBoard.model.PublicBoard;
import com.dbnt.sims.publicBoard.model.PublicComment;
import com.dbnt.sims.publicBoard.model.PublicFile;
import com.dbnt.sims.publicBoard.repository.PublicBoardRepository;
import com.dbnt.sims.publicBoard.repository.PublicCommentRepository;
import com.dbnt.sims.publicBoard.repository.PublicFileRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.List;
import java.util.UUID;


@Service
@RequiredArgsConstructor
public class PublicBoardService extends BaseService {
  private final PublicBoardRepository publicBoardRepository;
  private final PublicCommentRepository publicCommentRepository;
  private final PublicFileRepository publicFileRepository;
  private final PublicBoardMapper publicBoardMapper;

  public List<PublicBoard> selectContentList(PublicBoard publicBoard) {
    return publicBoardMapper.selectContentList(publicBoard);
  }

  public Integer selectContentListCnt(PublicBoard publicBoard) {
    return publicBoardMapper.selectContentListCnt(publicBoard);
  }

  public PublicBoard selectPublicBoard(Integer publicKey) {
    PublicBoard publicBoard = publicBoardRepository.findById(publicKey).orElse(null);
    publicBoard.setFileList(publicFileRepository.findByPublicKey(publicKey));
    List<PublicComment> commentList = publicCommentRepository.findByPublicKeyAndParentCommentOrderByCommentKeyAsc(publicKey, null);
    for(PublicComment comment: commentList){
      comment.setChildCommentList(publicCommentRepository.findByPublicKeyAndParentCommentOrderByCommentKeyAsc(publicKey, comment.getCommentKey()));
    }
    publicBoard.setCommentList(commentList);
    return publicBoard;
  }

  @Transactional
  public Integer saveContent(PublicBoard publicBoard, List<Integer> deleteFileSeq) {
    Integer publicKey = publicBoardRepository.save(publicBoard).getPublicKey();
    if(deleteFileSeq!=null && deleteFileSeq.size()>0){
      deletePublicFile(publicKey, deleteFileSeq);
    }
    if(publicBoard.getMultipartFileList()!= null){
      saveUploadFiles(publicKey, publicBoard.getMultipartFileList());
    }
    return publicKey;
  }

  private void saveUploadFiles(Integer publicKey, List<MultipartFile> multipartFileList) {
    PublicFile lastFileInfo = publicFileRepository.findTopByPublicKeyOrderByFileSeq(publicKey).orElse(null);
    int fileSeq = lastFileInfo==null?1:(lastFileInfo.getFileSeq()+1);
    for(MultipartFile file : multipartFileList){
      String saveName = UUID.randomUUID().toString();
      String path = locationPath+File.separator+"publicFile"+File.separator;
      saveFile(file, new File(path+File.separator+saveName));

      String originalFilename = file.getOriginalFilename();
      int extnIdx = originalFilename.lastIndexOf(".");
      PublicFile fileInfo = new PublicFile();
      fileInfo.setPublicKey(publicKey);
      fileInfo.setFileSeq(fileSeq++);
      fileInfo.setOrigNm(originalFilename.substring(0, extnIdx));
      fileInfo.setFileExtn(originalFilename.substring(extnIdx+1));
      fileInfo.setConvNm(saveName);
      fileInfo.setFileSize(calculationSize(file.getSize()));
      fileInfo.setSavePath(path);
      publicFileRepository.save(fileInfo);
    }
  }

  private void deletePublicFile(Integer publicKey, List<Integer> deleteFileSeq) {
    List<PublicFile> publicFileList = publicFileRepository.findByPublicKey(publicKey);
    for(PublicFile file: publicFileList){
      if(deleteFileSeq.contains(file.getFileSeq())){
        deleteStoredFile(new File(file.getSavePath(), file.getConvNm()));
        publicFileRepository.delete(file);
      }
    }
  }

  public Integer saveComment(PublicComment comment) {
    PublicComment lastComment = publicCommentRepository
        .findTopByPublicKeyOrderByCommentKeyDesc(comment.getPublicKey()).orElse(null);
    comment.setCommentKey(lastComment==null?1:(lastComment.getCommentKey()+1));
    return publicCommentRepository.save(comment).getCommentKey();
  }

  @Transactional
  public void deleteComment(Integer publicKey, Integer commentKey) {
    List<PublicComment> childList = publicCommentRepository.findByPublicKeyAndParentCommentOrderByCommentKeyAsc(publicKey, commentKey);
    publicCommentRepository.deleteAll(childList);
    publicCommentRepository.deleteById(new PublicComment.PublicCommentId(publicKey, commentKey));
  }

  public FileInfo selectPublicFile(Integer publicKey, Integer fileSeq){
    return publicFileRepository.findById(new PublicFile.PublicFileId(publicKey, fileSeq)).orElse(null);
  }
}