package com.dbnt.faisp.main.faRpt.service;

import com.dbnt.faisp.config.BaseService;
import com.dbnt.faisp.config.FileInfo;
import com.dbnt.faisp.main.faRpt.mapper.FaRptMapper;
import com.dbnt.faisp.main.faRpt.model.FaRptBoard;
import com.dbnt.faisp.main.faRpt.model.FaRptFile;
import com.dbnt.faisp.main.faRpt.model.FaRptReadUser;
import com.dbnt.faisp.main.faRpt.model.HashTagLinkFaRpt;
import com.dbnt.faisp.main.faRpt.repository.FaRptBoardRepository;
import com.dbnt.faisp.main.faRpt.repository.FaRptFileRepository;
import com.dbnt.faisp.main.faRpt.repository.FaRptReadUserRepository;
import com.dbnt.faisp.main.faRpt.repository.HashTagLinkFaRptRepository;
import com.dbnt.faisp.main.hashTag.service.HashTagService;
import com.dbnt.faisp.main.userInfo.model.UserAlarm;
import com.dbnt.faisp.main.userInfo.service.UserAlarmService;
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.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


@Service
@RequiredArgsConstructor
public class FaRptService extends BaseService {
  private final HashTagService hashTagService;
  private final UserAlarmService userAlarmService;
  private final FaRptBoardRepository faRptBoardRepository;
  private final FaRptFileRepository faRptFileRepository;
  private final FaRptReadUserRepository faRptReadUserRepository;
  private final HashTagLinkFaRptRepository hashTagLinkFaRptRepository;
  private final FaRptMapper faRptMapper;


  public List<FaRptBoard> selectFaRptList(FaRptBoard faRptBoard) {
    return faRptMapper.selectFaRptList(faRptBoard);
  }

  public Integer selectFaRptCnt(FaRptBoard faRptBoard) {
    return faRptMapper.selectFaRptCnt(faRptBoard);
  }

  @Transactional
  public Integer saveFaRptBoard(FaRptBoard faRptBoard, List<Integer> deleteFileSeq) {
    Integer faRptKey = faRptBoardRepository.save(faRptBoard).getFaRptKey();
    if(deleteFileSeq!=null && deleteFileSeq.size()>0){
      deleteFaRptFile(faRptKey, deleteFileSeq);
    }
    if(faRptBoard.getMultipartFileList() != null){
      saveUploadFiles(faRptKey, faRptBoard.getMultipartFileList());
    }
    if(faRptBoard.getReadUserList() != null){
      saveFaRptReadUser(faRptKey, faRptBoard.getReadUserList());
    }
    if(!faRptBoard.getHashTags().isEmpty()){
      saveHashTagLink(faRptKey, faRptBoard.getHashTags().split(" "));
    }
    return faRptKey;
  }

  @Transactional
  public FaRptBoard selectFaRptBoard(Integer faRptKey, Integer userSeq) {
    FaRptBoard faRptBoard = faRptBoardRepository.findById(faRptKey).orElse(null);
    if(faRptBoard != null){
      faRptBoard.setFileList(faRptFileRepository.findByFaRptKey(faRptKey));
      faRptBoard.setHashTags(faRptMapper.selectHashTags(faRptKey));
      faRptBoard.setReadUserList(faRptReadUserRepository.findByFaRptKey(faRptKey));
      if(faRptBoard.getStatus().equals("DST007")){
        for(FaRptReadUser readUser: faRptBoard.getReadUserList()){
          if(readUser.getUserSeq().equals(userSeq)){
            readUser.setReadYn("T");
            faRptReadUserRepository.save(readUser);
          }
        }
      }
    }
    return faRptBoard;
  }



  private void saveFaRptReadUser(Integer faRptKey, List<FaRptReadUser> readUserList) {
    faRptReadUserRepository.deleteByFaRptKey(faRptKey);
    List<UserAlarm> alarmList = new ArrayList<>();
    LocalDateTime dateTime = LocalDateTime.now();
    for(FaRptReadUser readUser: readUserList){
      readUser.setFaRptKey(faRptKey);
      UserAlarm alarm = userAlarmService.makeUserAlarm
          (dateTime, readUser.getUserSeq(), faRptKey, 1, "외사정보보고에 수신 문서가 있습니다.");
      alarmList.add(alarm);
    }
    userAlarmService.saveAlarmList(alarmList);
    faRptReadUserRepository.saveAll(readUserList);
  }

  private void saveUploadFiles(Integer faRptKey, List<MultipartFile> multipartFileList) {
    FaRptFile lastFile = faRptFileRepository.findTopByFaRptKeyOrderByFileSeq(faRptKey).orElse(null);
    int fileSeq = lastFile==null?1:(lastFile.getFileSeq()+1);
    for(MultipartFile file: multipartFileList){
      String saveName = UUID.randomUUID().toString();
      String path = locationPath+File.separator+"faRpt"+File.separator;
      saveFile(file, new File(path+File.separator+saveName));

      String originalFilename = file.getOriginalFilename();
      int extnIdx = originalFilename.lastIndexOf(".");
      FaRptFile fileInfo = new FaRptFile();
      fileInfo.setFaRptKey(faRptKey);
      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);
      faRptFileRepository.save(fileInfo);
    }
  }

  private void deleteFaRptFile(Integer faRptKey, List<Integer> deleteFileSeq) {
    List<FaRptFile> fileList = faRptFileRepository.findByFaRptKey(faRptKey);
    for(FaRptFile file: fileList){
      if(deleteFileSeq.contains(file.getFileSeq())){
        deleteStoredFile(new File(file.getSavePath(), file.getConvNm()));
        faRptFileRepository.delete(file);
      }
    }
  }

  private void saveHashTagLink(Integer faRptKey, String[] hashTagAry){
    hashTagLinkFaRptRepository.deleteByFaRptKey(faRptKey);
    for(String tagNm: hashTagAry){
      HashTagLinkFaRpt hashTagLink = new HashTagLinkFaRpt();
      hashTagLink.setFaRptKey(faRptKey);
      hashTagLink.setTagKey(hashTagService.selectTagKey(tagNm));
      hashTagLinkFaRptRepository.save(hashTagLink);
    }
  }

  public FileInfo selectFaRptFile(Integer faRptKey, Integer fileSeq) {
    return faRptFileRepository.findById(new FaRptFile.FaRptFileId(faRptKey, fileSeq)).orElse(null);
  }
}