package cn.ibizlab.core.data.service;

import cn.ibizlab.core.data.domain.DOModel;
import cn.ibizlab.core.data.lite.*;
import cn.ibizlab.core.data.model.PojoSchema;
import cn.ibizlab.core.data.model.TransUtils;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.Inflector;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ModelService {

    @Value("${ibiz.model.path:/app/file/model/}")
    private String modelPath;

    public String getModelPath()
    {
        if(modelPath.equals(File.separator))
            return modelPath.substring(0,modelPath.length()-1);
        return modelPath;
    }

    @Autowired
    private IDOModelService doModelService;

    @Autowired
    private LiteModelFeignClient liteService;

    @Autowired
    @Lazy
    private DynamicModelService dynamicService;

    @Autowired
    @Lazy
    private ModelService proxy;


    public DOModel getDOModel(String system,String entity)
    {
        return doModelService.get(system+".domain."+entity);
    }



    @Cacheable( value="syspssystem",key = "'row:sys-dst-sys-models'")
    public Map<String, DstSystemModel> getAllSystemModels()
    {
        Map<String,DstSystemModel> models=dynamicService.findAllDynamicModel();

        try
        {
            List<DstSystemModel> liteSystems=liteService.getSysApps();
            if(!ObjectUtils.isEmpty(liteSystems))
            {
                liteSystems.forEach(dstSystemModel->{
                    String system=dstSystemModel.getPssystemid();
                    if(!models.containsKey(system))
                        models.put(system, dstSystemModel);
                    if ((!system.toLowerCase().equals(system))&&(!models.containsKey(system.toLowerCase())))
                        models.put(system.toLowerCase(), dstSystemModel);
                });
            }
        }
        catch (Exception ex)
        {
            log.error("dst接口访问异常",ex);
        }


        File modelDir=new File(getModelPath());
        if(modelDir.exists())
        {
            for(File sysDir:modelDir.listFiles())
            {
                if(Files.exists(Paths.get(sysDir.getAbsolutePath(),"repo","domain")))
                {
                    String system=sysDir.getName();
                    DstSystemModel dstSystemModel=new DstSystemModel().setPssystemid(system).setPssystemname(system);
                    if(!models.containsKey(system))
                        models.put(system, dstSystemModel);
                    if ((!system.toLowerCase().equals(system))&&(!models.containsKey(system.toLowerCase())))
                        models.put(system.toLowerCase(), dstSystemModel);
                }
            }
        }
        return models;
    }



    @Cacheable( value="meta-entities", key = "'system:keymap-'+#p0")
    public Map<String,String> getEntitiyIdsBySystem(String system) throws Exception {
        DstSystemModel dstSystemModel=proxy.getAllSystemModels().get(system);
        if(dstSystemModel==null)
            throw new BadRequestAlertException("未找到对应的系统模型","DstSystem",system);

        system = dstSystemModel.getPssystemid();

        Map<String, String> entities = new HashMap<>();
        Map<String, MetaEntityModel> entityModels = dynamicService.getEntities(system);
        entityModels.entrySet().forEach(entity->{
            String id=entity.getValue().getSystemId().concat(".domain.").concat(entity.getValue().getEntityName());
            entities.put(entity.getKey(),id);
        });

        try{
            List<MetaEntityModel> liteEntities=liteService.getEntityModel(system);
            if(!ObjectUtils.isEmpty(liteEntities))
            {
                liteEntities.forEach(metaEntityModel->{
                    String id=metaEntityModel.getSystemId().concat(".domain.").concat(metaEntityModel.getEntityName());

                    if(!entities.containsKey(metaEntityModel.getCodeName()))
                        entities.put(metaEntityModel.getCodeName(),id);
                    if(!entities.containsKey(metaEntityModel.getCodeName().toLowerCase()))
                        entities.put(metaEntityModel.getCodeName().toLowerCase(),id);
                    if(!entities.containsKey(metaEntityModel.getEntityName())) {
                        entities.put(metaEntityModel.getEntityName(), id);
                    }
                    if(!entities.containsKey(metaEntityModel.getEntityName().toLowerCase())) {
                        entities.put(metaEntityModel.getEntityName().toLowerCase(), id);
                    }
                    String pluralize= Inflector.getInstance().pluralize(metaEntityModel.getCodeName()).toLowerCase();
                    if(!entities.containsKey(pluralize)) {
                        entities.put(pluralize, id);
                    }

                });
            }
        }
        catch (Exception ex)
        {
            log.error("dst接口访问异常",ex);
        }


        File dir=Paths.get(getModelPath(),system,"repo","domain").toFile();
        if(dir.exists())
        {
            for(File file:dir.listFiles())
            {
                if(!file.getName().endsWith(".json"))
                    continue;
                String entityName=file.getName().replace(".json","");
                String id=system.concat(".domain.").concat(entityName);

                if(!entities.containsKey(entityName.toLowerCase()))
                    entities.put(entityName.toLowerCase(),id);
            }
        }

        return entities;
    }


    public EntityModel getEntityModel(String system,String entity)
    {

        EntityModel entityModel = null;

        try {
            entityModel = dynamicService.getDynamicEntity(system,entity);
        } catch (Exception exception) {

        }
        try{
            if(entityModel==null)
                entityModel = liteService.getProxyEntityModel(system,entity);
        }
        catch (Exception ex)
        {
            log.error("dst接口访问异常",ex);
        }


        return entityModel;
    }



}
