package com.dbnt.kcgfilemanager.service;

import com.dbnt.kcgfilemanager.model.Board;
import com.dbnt.kcgfilemanager.model.BoardCategory;
import com.dbnt.kcgfilemanager.model.CategoryRole;
import com.dbnt.kcgfilemanager.model.ContentPosition;
import com.dbnt.kcgfilemanager.repository.BoardCategoryRepository;
import com.dbnt.kcgfilemanager.repository.BoardRepository;
import com.dbnt.kcgfilemanager.repository.CategoryRoleRepository;
import com.dbnt.kcgfilemanager.repository.ContentPositionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class BoardCategoryService {

  private final FileInfoService fileInfoService;

  private final BoardRepository boardRepository;
  private final BoardCategoryRepository boardCategoryRepository;
  private final CategoryRoleRepository categoryRoleRepository;
  private final ContentPositionRepository contentPositionRepository;


  public List<BoardCategory> selectBoardCategory(Integer parentSeq, Integer depth) {
    return boardCategoryRepository.findByParentSeqAndDepthOrderBySortCntDesc(parentSeq, depth);
  }

  public List<BoardCategory> selectBoardCategoryAll(Integer parentSeq, Integer depth){
    List<BoardCategory> categoryList = boardCategoryRepository.findByParentSeqAndDepthOrderBySortCntDesc(parentSeq, depth);
    for(BoardCategory category: categoryList){
      category.setChildCategoryList(selectBoardCategoryAll(category.getCategorySeq(), depth+1));
    }
    return categoryList;
  }

  public List<BoardCategory> selectBoardCategoryListToFindAll(){
    List<BoardCategory> categoryList = boardCategoryRepository.findAll();
    categoryList.sort(Comparator.comparing(BoardCategory::getSortCnt).reversed());
    return categoryList;
  }

  @Transactional
  public void insertBoardCategory(List<BoardCategory> categoryList){
    boardCategoryRepository.saveAll(categoryList);
    Integer parentSeq = categoryList.get(0).getParentSeq();
    List<CategoryRole> categoryRoleList = categoryRoleRepository.findByCategorySeq(parentSeq);
    List<CategoryRole> addRoleList = new ArrayList<>();
    for(CategoryRole role: categoryRoleList){
      for(BoardCategory category: categoryList){
        CategoryRole categoryRole = new CategoryRole();
        categoryRole.setUserSeq(role.getUserSeq());
        categoryRole.setCategorySeq(category.getCategorySeq());
        categoryRole.setCategoryRole("T");
        addRoleList.add(categoryRole);
      }
    }
    categoryRoleRepository.saveAll(addRoleList);
  }

  public void deleteBoardCategory(Integer categorySeq, Integer depth) {
    deleteChildCategory(selectBoardCategoryAll(categorySeq, depth+1));
    BoardCategory boardCategory = new BoardCategory();
    boardCategory.setCategorySeq(categorySeq);
    boardCategoryRepository.delete(boardCategory);
  }

  private void deleteChildCategory(List<BoardCategory> childList){
    for(BoardCategory category: childList){
      deleteChildCategory(category.getChildCategoryList());
    }
    boardCategoryRepository.deleteAll(childList);
  }

  public String getPageTitle(Integer categorySeq) {
    BoardCategory category = boardCategoryRepository.findById(categorySeq).orElse(null);
    if(category.getParentSeq()==null){
      return category.getCategoryName();
    }
    return getPageTitle(category.getParentSeq())+" > "+category.getCategoryName();
  }

  public String getDepth4PageTitle(Integer categorySeq) {
    ContentPosition contentPosition = contentPositionRepository.findById(categorySeq).orElse(null);
    return contentPosition.getCategoryName();
  }
  public String makeFilePath(Integer categorySeq){
    BoardCategory category = boardCategoryRepository.findById(categorySeq).orElse(null);
    if(category.getParentSeq()==null){
      return File.separator+category.getCategoryName();
    }
    return makeFilePath(category.getParentSeq())+File.separator+category.getCategoryName();
  }

  @Transactional
  public void saveBoardCategory(List<BoardCategory> categoryList) {
    for(BoardCategory category: categoryList){
      switch (category.getStatus()){
        case "deleted":
          deleteContentToCategorySeq(category.getCategorySeq());
          boardCategoryRepository.delete(category);
          break;
        case "modified":
          boardCategoryRepository.save(category);
          break;
        case "added":
          category.setTempSeq(category.getCategorySeq());
          category.setCategorySeq(null);
          if(category.getDepth()!=1){
            for(BoardCategory temp : categoryList){
              if(Objects.equals(temp.getTempSeq(), category.getParentSeq())){
                category.setParentSeq(temp.getCategorySeq());
                break;
              }
            }
          }
          boardCategoryRepository.saveAndFlush(category);
          break;
      }
    }
  }

  private void deleteContentToCategorySeq(Integer categorySeq) {
    List<Board> deleteContentList = boardRepository.findByCategorySeq(categorySeq);
    for(Board deleteContent: deleteContentList){
      fileInfoService.deleteFileInfoAll(deleteContent.getContentSeq());
      boardRepository.delete(deleteContent);
    }
  }
}
