package cn.stylefeng.team.generator.api.factory;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.team.generator.api.enums.GeneratorResultFileTypeEnum;
import cn.stylefeng.team.generator.api.pojo.generator.result.CommonGenerateResult;
import cn.stylefeng.team.generator.api.pojo.result.CodeTreeStructure;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;

import java.util.ArrayList;
import java.util.List;

public class CodeTreeStructureFactory {

    public static List<CodeTreeStructure> buildTree(List<CommonGenerateResult> commonGenerateResultList) {

        List<CodeTreeStructure> resultStructure = new ArrayList<>();

        for (CommonGenerateResult commonGenerateResult : commonGenerateResultList) {
            buildStructureByPath(commonGenerateResult, 0, resultStructure);
        }

        return resultStructure;
    }

    private static void buildStructureByPath(CommonGenerateResult currentResult, int currentSectionIndex,
                                             List<CodeTreeStructure> currentSectionList) {

        String currentFilePath = StrUtil.removePrefix(currentResult.getFilePath(), "/");

        String[] currentFoldersAndFile = currentFilePath.split("/");

        if (currentSectionIndex >= currentFoldersAndFile.length) {
            return;
        }

        String currentSectionFileFolderOrFileName = currentFoldersAndFile[currentSectionIndex];

        boolean haveAlreadyExisted = false;
        CodeTreeStructure alreadyStructure = null;

        for (CodeTreeStructure codeTreeStructure : currentSectionList) {
            if (codeTreeStructure.getFileName().equals(currentSectionFileFolderOrFileName)) {
                haveAlreadyExisted = true;
                alreadyStructure = codeTreeStructure;
            }
        }

        if (haveAlreadyExisted) {
            buildStructureByPath(currentResult, currentSectionIndex + 1, alreadyStructure.getSubFileList());
            return;
        }

        CodeTreeStructure codeTreeStructure = new CodeTreeStructure();
        codeTreeStructure.setId(IdWorker.getId());
        codeTreeStructure.setFileName(currentSectionFileFolderOrFileName);
        codeTreeStructure.setGenResultFileType(
                getFileTypeByFileName(currentResult, currentSectionIndex, currentSectionFileFolderOrFileName));
        if (currentSectionIndex == currentFoldersAndFile.length - 1) {
            codeTreeStructure.setFileContent(currentResult.getFileContent());
        } else {
            codeTreeStructure.setFileContent(null);
        }

        List<CodeTreeStructure> subFileObjects = new ArrayList<>();
        buildStructureByPath(currentResult, currentSectionIndex + 1, subFileObjects);
        codeTreeStructure.setSubFileList(subFileObjects);

        currentSectionList.add(codeTreeStructure);
    }

    public static int getFileTypeByFileName(CommonGenerateResult currentResult, int currentSectionIndex, String currentName) {

        String currentFilePath = StrUtil.removePrefix(currentResult.getFilePath(), "/");
        String[] currentFoldersAndFile = currentFilePath.split("/");

        if (currentSectionIndex != currentFoldersAndFile.length - 1) {
            return GeneratorResultFileTypeEnum.FOLDER.getCode();
        }

        if (currentName.endsWith(".java")) {
            return GeneratorResultFileTypeEnum.JAVA.getCode();
        } else if (currentName.endsWith(".xml")) {
            return GeneratorResultFileTypeEnum.XML.getCode();
        } else if (currentName.endsWith(".js")) {
            return GeneratorResultFileTypeEnum.JS.getCode();
        } else if (currentName.endsWith(".vue")) {
            return GeneratorResultFileTypeEnum.VUE.getCode();
        } else if (currentName.endsWith(".sql")) {
            return GeneratorResultFileTypeEnum.SQL.getCode();
        }

        return GeneratorResultFileTypeEnum.NONE_TYPE.getCode();
    }

    public static void mergeFolders(CodeTreeStructure currentFile) {
        if (currentFile == null) {
            return;
        }
        if (ObjectUtil.isEmpty(currentFile.getSubFileList())) {
            return;
        }

        if (currentFile.getSubFileList().size() == 1) {
            CodeTreeStructure subOnlyFile = currentFile.getSubFileList().get(0);
            if (subOnlyFile.getGenResultFileType().equals(GeneratorResultFileTypeEnum.FOLDER.getCode())) {
                currentFile.setFileName(currentFile.getFileName() + "." + subOnlyFile.getFileName());
                currentFile.setSubFileList(subOnlyFile.getSubFileList());
                mergeFolders(currentFile);
            }
        }

        if (currentFile.getSubFileList().size() > 1) {
            for (CodeTreeStructure codeTreeStructure : currentFile.getSubFileList()) {
                mergeFolders(codeTreeStructure);
            }
        }
    }

}
