package com.dbnt.faisp.fpiMgt.monthPlan.service;


import com.dbnt.faisp.config.BaseService;
import com.dbnt.faisp.config.FileInfo;
import com.dbnt.faisp.fpiMgt.monthPlan.mapper.MonthPlanMapper;
import com.dbnt.faisp.fpiMgt.monthPlan.model.PlanApprv;
import com.dbnt.faisp.fpiMgt.monthPlan.model.PlanBoard;
import com.dbnt.faisp.fpiMgt.monthPlan.model.PlanFile;
import com.dbnt.faisp.fpiMgt.monthPlan.model.PlanMainInfo;
import com.dbnt.faisp.fpiMgt.monthPlan.repository.PlanApprvRepository;
import com.dbnt.faisp.fpiMgt.monthPlan.repository.PlanBoardRepository;
import com.dbnt.faisp.fpiMgt.monthPlan.repository.PlanFileRepository;
import com.dbnt.faisp.fpiMgt.monthPlan.repository.PlanMainInfoRepository;
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.io.IOException;
import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class MonthPlanService extends BaseService {
  private final PlanBoardRepository planBoardRepository;
  private final PlanFileRepository planFileRepository;
  private final PlanMainInfoRepository planMainInfoRepository;
  private final PlanApprvRepository planApprvRepository;
  private final MonthPlanMapper monthPlanMapper;

  public PlanBoard selectPlanBoard(Integer planKey) {
    PlanBoard savedPlan = planBoardRepository.findById(planKey).orElse(null);
    if (savedPlan != null) {
      savedPlan.setFileList(planFileRepository.findByPlanKey(planKey));
      savedPlan.setMainInfoList(planMainInfoRepository.findByPlanKey(planKey));
      savedPlan.setApprvList(planApprvRepository.findByPlanKey(planKey));
    }
    return savedPlan;
  }

  @Transactional
  public Integer savePlanBoard(PlanBoard planBoard, List<String> planInfos, List<String> detailPlanInfos, List<Integer> deleteFileSeq) {
    Integer planKey = planBoardRepository.save(planBoard).getPlanKey();
    Integer infoSeq = savePlanMainInfos(planKey,0, "S", planInfos);//요약 summery
    savePlanMainInfos(planKey, infoSeq, "D", detailPlanInfos);//상세 detail
    if(deleteFileSeq != null && deleteFileSeq.size()>0){
      deletePlanFile(planKey, deleteFileSeq);
    }
    if(planBoard.getMultipartFileList()!=null){
      saveUploadFiles(planKey, planBoard.getMultipartFileList());
    }
    return planKey;
  }

  private Integer savePlanMainInfos(Integer planKey, Integer planSeq, String infoType, List<String> infoList){
    for(String info: infoList){
      PlanMainInfo planMainInfo = new PlanMainInfo();
      planMainInfo.setPlanKey(planKey);
      planMainInfo.setPlanSeq(++planSeq);
      planMainInfo.setPlanType(infoType);
      planMainInfo.setPlanInfo(info);
      planMainInfoRepository.save(planMainInfo);
    }
    return planSeq;
  }

  public List<PlanBoard> selectPlanBoardList(PlanBoard planBoard) {
    return monthPlanMapper.selectPlanBoardList(planBoard);
  }

  public Integer selectPlanBoardListCnt(PlanBoard planBoard) {
    return monthPlanMapper.selectPlanBoardListCnt(planBoard);
  }

  private void saveUploadFiles(Integer planKey, List<MultipartFile> multipartFileList){
    PlanFile lastFileInfo = planFileRepository.findByPlanKeyOrderByFileSeqDesc(planKey).orElse(null);
    int fileSeq = lastFileInfo==null?1:(lastFileInfo.getFileSeq()+1);
    for(MultipartFile file : multipartFileList){
      String saveName = UUID.randomUUID().toString();
      String path = locationPath+File.separator+"monthPlan"+File.separator;

      File saveFile = new File(path+File.separator+saveName);
      if(file.getSize()!=0){ // 저장될 파일 확인
        if(!saveFile.exists()){ // 저장될 경로 확인
          if(saveFile.getParentFile().mkdirs()){
            try{
              saveFile.createNewFile();
            }catch (IOException e){
              e.printStackTrace();
            }
          }
        }
        try {
          file.transferTo(saveFile);
        }catch (IllegalStateException | IOException e){
          e.printStackTrace();
        }
      }

      String originalFilename = file.getOriginalFilename();
      int extnIdx = originalFilename.lastIndexOf(".");
      PlanFile fileInfo = new PlanFile();
      fileInfo.setPlanKey(planKey);
      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);
      planFileRepository.save(fileInfo);
    }
  }

  public void deletePlanFile(Integer planKey, List<Integer> deleteFileSeq) {
    List<PlanFile> planFileList = planFileRepository.findByPlanKey(planKey);
    for(PlanFile file: planFileList){
      if(deleteFileSeq.contains(file.getFileSeq())){
        deleteStoredFile(new File(file.getSavePath(), file.getConvNm()));
        planFileRepository.delete(file);
      }
    }
  }

  public FileInfo selectPlanFile(Integer parentKey, Integer fileSeq) {
    return planFileRepository.findById(new PlanFile.PlanFileId(parentKey, fileSeq)).orElse(null);
  }

  @Transactional
  public Integer planStateChange(PlanApprv apprv) {
    PlanBoard savedPlan = planBoardRepository.findById(apprv.getPlanKey()).orElse(null);
    savedPlan.setPlanState(apprv.getState());
    PlanApprv lastApprv = planApprvRepository.findTopByPlanKeyOrderByApprvSeqDesc(apprv.getPlanKey()).orElse(null);
    apprv.setApprvSeq(lastApprv==null?1:lastApprv.getApprvSeq()+1);
    planApprvRepository.save(apprv);
    return apprv.getApprvSeq();
  }
}
