package com.dbnt.faisp.main.fpiMgt.affairResult.service;


import com.dbnt.faisp.config.BaseService;
import com.dbnt.faisp.config.FileInfo;
import com.dbnt.faisp.main.fpiMgt.affairResult.mapper.ResultMapper;
import com.dbnt.faisp.main.fpiMgt.affairResult.model.*;
import com.dbnt.faisp.main.fpiMgt.affairResult.repository.*;
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.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class ResultService extends BaseService { // 월간계획
  private final UserAlarmService userAlarmService;
  private final ClearInfoRepository clearInfoRepository;
  private final ResultApprvRepository resultApprvRepository;
  private final ResultBoardRepository resultBoardRepository;
  private final ResultFileRepository resultFileRepository;
  private final ResultInfoRepository resultInfoRepository;
  private final ResultToAffairRepository resultToAffairRepository;
  private final ResultToPlanRepository resultToPlanRepository;
  private final ResultMapper resultMapper;

  public List<ResultBoard> selectResultBoardList(ResultBoard resultBoard) {
    return resultMapper.selectResultBoardList(resultBoard);
  }

  public Integer selectResultBoardListCnt(ResultBoard resultBoard) {
    return resultMapper.selectResultBoardListCnt(resultBoard);
  }

  public ResultBoard selectResultBoard(Integer resultKey) {
    ResultBoard savedResult = resultBoardRepository.findById(resultKey).orElse(null);
    if (savedResult != null) {
      savedResult.setFileList(resultFileRepository.findByResultKey(resultKey));
      savedResult.setApprvList(resultApprvRepository.findByResultKey(resultKey));
      savedResult.setClearInfoList(clearInfoRepository.findByResultKey(resultKey));
      savedResult.setResultInfoList(resultInfoRepository.findByResultKey(resultKey));
      savedResult.setAffairBoardList(resultMapper.selectAffairToResultKey(resultKey));
    }
    return savedResult;
  }

  @Transactional
  public Integer saveResultBoard(ResultBoard resultBoard, List<Integer> deleteFileSeq) {
    Integer resultKey = resultBoardRepository.save(resultBoard).getResultKey();
    if(deleteFileSeq != null && deleteFileSeq.size()>0){
      deleteResultFile(resultKey, deleteFileSeq);
    }
    if(resultBoard.getMultipartFileList()!=null){
      saveUploadFiles(resultKey, resultBoard.getMultipartFileList());
    }
    if (resultBoard.getClearInfoList() != null){
      saveClearInfoList(resultKey, resultBoard.getClearInfoList());
    }
    if (resultBoard.getResultInfoList() != null){
      saveResultInfoList(resultKey, resultBoard.getResultInfoList());
    }
    if (resultBoard.getAffairList() != null){
      saveResultToAffair(resultKey, resultBoard.getAffairList());
    }
    if(resultBoard.getResultState().equals("DST002")){
      //작성완료일 때 계장 결재 사용자에게 알림 발송.
      userAlarmService.sendAlarmToApprvUser(resultKey, resultBoard.getWrtOrgan(), "APC003", 31, "청산보고서에 결재대기 문서가 있습니다.");
      userAlarmService.sendAlarmToApprvUser(resultKey, resultBoard.getWrtOrgan(), "APC004", 31, "청산보고서에 결재대기 문서가 있습니다.");
    }
    return resultKey;
  }

  public FileInfo selectResultFile(Integer resultKey, Integer fileSeq) {
    return resultFileRepository.findById(new ResultFile.ResultFileId(resultKey, fileSeq)).orElse(null);
  }

  @Transactional
  public Integer resultStateChange(ResultApprv apprv) {
    ResultBoard savedResult = resultBoardRepository.findById(apprv.getResultKey()).orElse(null);
    savedResult.setResultState(apprv.getState());
    ResultApprv lastApprv = resultApprvRepository.findTopByResultKeyOrderByApprvSeqDesc(apprv.getResultKey()).orElse(null);
    apprv.setApprvSeq(lastApprv==null?1:lastApprv.getApprvSeq()+1);
    resultApprvRepository.save(apprv);

    switch (apprv.getState()){
      case "DST004":
        // 계장승인시 부장 결재권자에게 알림 발송.
        userAlarmService.sendAlarmToApprvUser(savedResult.getResultKey(), savedResult.getWrtOrgan(), "APC001", 31, "청산보고서에 결재대기 문서가 있습니다.");
        userAlarmService.sendAlarmToApprvUser(savedResult.getResultKey(), savedResult.getWrtOrgan(), "APC002", 31, "청산보고서에 결재대기 문서가 있습니다.");
        break;
      case "DST003":
      case "DST005":
        // 반려시 작성자에게 반려 알림 발송
        userAlarmService.sendAlarmToWrtUser(savedResult.getResultKey(), savedResult.getWrtUserSeq(), 31, savedResult.getResultTitle()+" 문서가 반려되었습니다.");
        break;
      case "DST006":
        // 부장승인시 작성자에게 승인 알림 발송
        userAlarmService.sendAlarmToWrtUser(savedResult.getResultKey(), savedResult.getWrtUserSeq(), 31, savedResult.getResultTitle()+" 문서가 승인되었습니다.");
        break;
    }
    return apprv.getApprvSeq();
  }

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

      String originalFilename = file.getOriginalFilename();
      int extnIdx = originalFilename.lastIndexOf(".");
      ResultFile fileInfo = new ResultFile();
      fileInfo.setResultKey(resultKey);
      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);
      resultFileRepository.save(fileInfo);
    }
  }

  private void deleteResultFile(Integer resultKey, List<Integer> deleteFileSeq) {
    List<ResultFile> resultFileList = resultFileRepository.findByResultKey(resultKey);
    for(ResultFile file: resultFileList){
      if(deleteFileSeq.contains(file.getFileSeq())){
        deleteStoredFile(new File(file.getSavePath(), file.getConvNm()));
        resultFileRepository.delete(file);
      }
    }
  }


  private void saveClearInfoList(Integer resultKey, List<ClearInfo> clearInfoList) {
    clearInfoRepository.deleteByResultKey(resultKey);
    for(ClearInfo info: clearInfoList){
      info.setResultKey(resultKey);
    }
    clearInfoRepository.saveAll(clearInfoList);
  }

  private void saveResultInfoList(Integer resultKey, List<ResultInfo> resultInfoList){
    resultInfoRepository.deleteByResultKey(resultKey);
    for(ResultInfo info: resultInfoList){
      info.setResultKey(resultKey);
    }
    resultInfoRepository.saveAll(resultInfoList);
  }

  private void saveResultToAffair(Integer resultKey, List<ResultToAffair> resultToAffairList){
    resultToAffairRepository.deleteByResultKey(resultKey);
    for(ResultToAffair relation: resultToAffairList){
      relation.setResultKey(resultKey);
    }
    resultToAffairRepository.saveAll(resultToAffairList);
  }
}
