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


import com.dbnt.faisp.config.BaseService;
import com.dbnt.faisp.config.FileInfo;
import com.dbnt.faisp.main.authMgt.service.AuthMgtService;
import com.dbnt.faisp.main.fpiMgt.affairPlan.mapper.PlanMapper;
import com.dbnt.faisp.main.fpiMgt.affairPlan.model.PlanApprv;
import com.dbnt.faisp.main.fpiMgt.affairPlan.model.PlanBoard;
import com.dbnt.faisp.main.fpiMgt.affairPlan.model.PlanFile;
import com.dbnt.faisp.main.fpiMgt.affairPlan.model.PlanMainInfo;
import com.dbnt.faisp.main.fpiMgt.affairPlan.repository.PlanApprvRepository;
import com.dbnt.faisp.main.fpiMgt.affairPlan.repository.PlanBoardRepository;
import com.dbnt.faisp.main.fpiMgt.affairPlan.repository.PlanFileRepository;
import com.dbnt.faisp.main.fpiMgt.affairPlan.repository.PlanMainInfoRepository;
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.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class PlanService extends BaseService { // 월간계획
  private final UserAlarmService userAlarmService;
  private final PlanBoardRepository planBoardRepository;
  private final PlanFileRepository planFileRepository;
  private final PlanMainInfoRepository planMainInfoRepository;
  private final PlanApprvRepository planApprvRepository;
  private final PlanMapper planMapper;

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

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

  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);//요약 summary
    savePlanMainInfos(planKey, infoSeq, "D", detailPlanInfos);//상세 detail
    if(deleteFileSeq != null && deleteFileSeq.size()>0){
      deletePlanFile(planKey, deleteFileSeq);
    }
    if(planBoard.getMultipartFileList()!=null){
      saveUploadFiles(planKey, planBoard.getMultipartFileList());
    }
    if(planBoard.getPlanState().equals("DST002")){
      //작성완료일 때 계장 결재 사용자에게 알림 발송.
      userAlarmService.sendAlarmToApprvUser(planKey, planBoard.getWrtOrgan(), "APC003", 29, "월간계획에 결재대기 문서가 있습니다.");
      userAlarmService.sendAlarmToApprvUser(planKey, planBoard.getWrtOrgan(), "APC004", 29, "월간계획에 결재대기 문서가 있습니다.");
    }
    return planKey;
  }

  public FileInfo selectPlanFile(Integer planKey, Integer fileSeq) {
    return planFileRepository.findById(new PlanFile.PlanFileId(planKey, 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);

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

  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;
  }

  private void saveUploadFiles(Integer planKey, List<MultipartFile> multipartFileList){
    PlanFile lastFileInfo = planFileRepository.findTopByPlanKeyOrderByFileSeqDesc(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;
      saveFile(file, new File(path+File.separator+saveName));

      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);
    }
  }

  private 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);
      }
    }
  }
}
