package cn.ibizlab.codegen.model;

import cn.ibizlab.codegen.utils.Inflector;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.app.IPSApplication;
import net.ibizsys.model.app.codelist.IPSAppCodeList;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class AppModel extends BaseModel{

    public AppModel(IPSApplication application)
    {
        this.opt=application;
        this.setCodeName(application.getCodeName());
        this.setName(application.getName());
        if(getApplication().getAllPSAppDataEntities()!=null)
        {
            getApplication().getAllPSAppDataEntities().forEach(item->{
                appEntitiesMap.put(item.getCodeName(),new AppEntityModel(this,item));
            });
        }
        if(getApplication().getAllPSAppViews()!=null)
        {
            getApplication().getAllPSAppViews().forEach(item->{
                if(item.getRefFlag()) {
                    pagesMap.put(item.getCodeName(), new PageModel(this, item));
                }
            });
        }

        // 初始化应用实体资源数据Map
        if(getApplication().getAllPSAppDataEntities()!=null)
        {
            getApplication().getAllPSAppDataEntities().forEach(appDataEntity ->{

                if(appDataEntity.getMinorPSAppDERSs() != null){
                    appDataEntity.getMinorPSAppDERSs().forEach(appDERS ->{
                        JSONObject tempObj = new JSONObject();
                        String majorCodeName = appDERS.getMajorPSAppDataEntity().getCodeName();
                        String minorCodeName = appDERS.getMinorPSAppDataEntity().getCodeName();
                        String path = String.format("%1$s/:%2$s?/%3$s/:%4$s?",Inflector.getInstance().pluralize(majorCodeName),majorCodeName,Inflector.getInstance().pluralize(minorCodeName),minorCodeName).toLowerCase();
                        tempObj.put("majorCodeName",majorCodeName.toLowerCase());
                        tempObj.put("curCodeName",minorCodeName.toLowerCase());
                        tempObj.put("path",path);
                        tempObj.put("appDataEntity",appDataEntity);
                        appEntityResourceMap.put(String.format("%1$s:%2$s",majorCodeName,minorCodeName),tempObj);
                    });
                }
                JSONObject tempObj = new JSONObject();
                tempObj.put("curCodeName",appDataEntity.getCodeName().toLowerCase());
                tempObj.put("path",String.format("%1$s/:%2$s?",Inflector.getInstance().pluralize(appDataEntity.getCodeName()),appDataEntity.getCodeName()).toLowerCase());
                tempObj.put("appDataEntity",appDataEntity);
                appEntityResourceMap.put(appDataEntity.getCodeName(),tempObj);
            });
        }

    }


    private SystemModel system;

    public IPSApplication getApplication()
    {
        return (IPSApplication)opt;
    }

    private Map<String,AppEntityModel> appEntitiesMap=new LinkedHashMap<>();

    private Map<String,PageModel> pagesMap=new LinkedHashMap<>();

    private Map<String,CtrlModel> ctrlsMap=new LinkedHashMap<>();


    public Collection<AppEntityModel> getAppEntities() {
        return appEntitiesMap.values();
    }

    public Collection<PageModel> getPages() {
        return pagesMap.values();
    }

    public Collection<CtrlModel> getCtrls() {
        return ctrlsMap.values();
    }


    public PageModel getPage(String codeName)
    {
        if(pagesMap!=null)
            return pagesMap.get(codeName);
        return null;
    }

    public AppEntityModel getAppEntity(String codeName)
    {
        if(appEntitiesMap!=null)
            return appEntitiesMap.get(codeName);
        return null;
    }

    /**
     * 应用实体资源数据Map
     */
    private Map<String, JSONObject> appEntityResourceMap =new LinkedHashMap<>();

    /**
     * 获取应用实体资源数据
     * @return
     */
    public Collection<JSONObject> getAppEntityResources(){
        if(appEntityResourceMap!=null)
            return appEntityResourceMap.values();
        return new ArrayList<>();
    }

    private Set<String> refServiceIds;

    public Set<String> getRefServiceIds()
    {
        if(refServiceIds==null)
        {
            refServiceIds=new HashSet<>();
            getAppEntities().forEach(appEntityModel -> {
                String serviceId=appEntityModel.getServiceId();
                if(!StringUtils.isEmpty(serviceId))
                {
                    refServiceIds.add(serviceId);
                }
            });
        }
        return refServiceIds;

    }

    private Map<String,Catalog> dictMaps;
    public Map<String,Catalog> getDictMaps() {
        return getDictMaps(system.getModelFolderPath());
    }
    public Collection<Catalog> getDicts() {
        return getDictMaps().values();
    }
    public Map<String,Catalog> getDictMaps(String rootPath) {
        if(dictMaps==null)
        {
            dictMaps=new LinkedHashMap<>();
            Map<String,Catalog> catalogs= new LinkedHashMap<>();
            if(!ObjectUtils.isEmpty(rootPath))
            {
                java.nio.file.Path path = Paths.get(rootPath,"PSSYSAPPS","/ALLCODELIST.json");
                if(Files.exists(path))
                {
                    try {
                        JSON.parseArray(new String(Files.readAllBytes(path), Charsets.UTF_8),Catalog.class).forEach(catalog -> {
                            if(StringUtils.isEmpty(catalog.getName()))
                            {
                                IPSAppCodeList codeList=getApplication().getPSAppCodeList(catalog.getCode(),true);
                                if(codeList!=null)
                                    catalog.setName(codeList.getLogicName());
                                catalogs.put(catalog.getCode(),catalog);
                            }

                        });
                    } catch (IOException e) {
                        //e.printStackTrace();
                    }
                }
            }

            if(this.getApplication().getAllPSAppCodeLists()!=null)
            {
                this.getApplication().getAllPSAppCodeLists().forEach(codeList->{
                    Catalog catalog=catalogs.get(codeList.getCodeName());
                    if(catalog!=null)
                    {
                        catalog.setName(codeList.getName());
                        catalog.setCodeName(codeList.getCodeName());
                    }
                    else
                    {
                        catalog=new Catalog().setCode(codeList.getCodeName()).setName(codeList.getName());
                        catalog.setCodeName(codeList.getCodeName());
                        if(!ObjectUtils.isEmpty(codeList.getPSCodeItems()))
                        {
                            catalog.setCodeItem(codeList.getPSCodeItems());
                        }
                    }
                    if(!ObjectUtils.isEmpty(catalog.getOptions())) {
                        catalog.setOpt(codeList);
                        dictMaps.put(catalog.getCodeName(), catalog);
                    }
                });
            }
        }


        return dictMaps;
    }


}
