package cn.ibizlab.core.extensions.service;

import cn.ibizlab.core.lite.domain.MetaEntity;
import cn.ibizlab.core.lite.domain.MetaField;
import cn.ibizlab.core.lite.domain.MetaRelationship;
import cn.ibizlab.core.lite.extensions.domain.SysModel;
import cn.ibizlab.core.lite.service.IMetaEntityService;
import cn.ibizlab.core.lite.service.IMetaFieldService;
import cn.ibizlab.core.lite.service.IMetaRelationshipService;
import cn.ibizlab.core.lite.service.impl.DstSystemServiceImpl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.core.lite.domain.DstSystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * 实体[系统] 自定义服务对象
 */
@Slf4j
@Primary
@Service("DstSystemExService")
public class DstSystemExService extends DstSystemServiceImpl {

    @Autowired
    @Lazy
    IMetaEntityService entityService;

    @Autowired
    @Lazy
    IMetaFieldService fieldService;

    @Autowired
    @Lazy
    IMetaRelationshipService relationService;

    @Override
    protected Class currentModelClass() {
        return com.baomidou.mybatisplus.core.toolkit.ReflectionKit.getSuperClassGenericType(this.getClass().getSuperclass(), 1);
    }

    @Override
    public boolean create(DstSystem et) {
        SysModel structure=et.getSysstructure();
        if(!super.create(et))
            return false;
        et.setSysstructure(structure);
        syncSysModel(et);

        return true;
    }

    @Override
    public boolean update(DstSystem et) {
        SysModel structure=et.getSysstructure();
        Object ignoreSyncSysModel=et.get("ignoreSyncSysModel");
        if(!super.update(et))
            return false;
        if(ignoreSyncSysModel==null||ignoreSyncSysModel.equals(false)){
            et.setSysstructure(structure);
            syncSysModel(et);
        }
        return true;
    }

    /**
     * 自定义行为[SyncSysModel]用户扩展
     * @param system
     * @return
     */
    @Override
    @Transactional
    public DstSystem syncSysModel(DstSystem system) {
        if(StringUtils.isEmpty(system.getPssystemid())||system.getSysstructure()==null)
            return system;
        Object ignoreSyncSysModel=system.get("ignoreSyncSysModel");
        if(ignoreSyncSysModel!=null&&ignoreSyncSysModel.equals(true))
            return system;

        syncDE(system);
        syncDEField(system);
        syncDERelation(system);
        return super.syncSysModel(system);
    }

    /**
     * 同步实体
     * @param system
     */
    private void syncDE(DstSystem system) {
        Map<String,Integer> delDE = new HashMap<>();
        entityService.list(new QueryWrapper<MetaEntity>().select("entityid").eq("systemid",system.getPssystemid())).forEach(entity -> delDE.put(entity.getEntityId(),1));
        Set<MetaEntity> list = system.getSysstructure().getEntity();
        list.forEach(entity -> {
            delDE.remove(entity.getEntityId());
        });
        //移除无效资源
        if(delDE.size()>0)
            entityService.removeBatch(delDE.keySet());
        //存储或更新资源saveOrUpdate
        if(list.size()>0)
            entityService.saveBatch(list);
    }

    /**
     * 同步实体属性
     * @param system
     */
    private void syncDEField(DstSystem system) {
        Map<String,Integer> delField = new HashMap<>();
        Map param=new HashMap();
        param.put("id",system.getPssystemid());
        List<JSONObject> oldField=fieldService.select("select fieldid from ibzfield t inner join ibzentity t1 on t.entityid =t1.entityid where t1.systemid = #{et.id}",param);
        for(JSONObject field: oldField){
            delField.put(field.getString("FIELDID"),1);
        }
        Set<MetaField> list = system.getSysstructure().getField();
        list.forEach(field -> {
            delField.remove(field.getFieldId());
        });
        //移除无效资源
        if(delField.size()>0)
            fieldService.removeBatch(delField.keySet());
        //存储或更新资源saveOrUpdate
        if(list.size()>0)
            fieldService.saveBatch(list);
    }

    /**
     * 同步实体关系
     * @param system
     */
    private void syncDERelation(DstSystem system) {
        Map<String,Integer> delRelation = new HashMap<>();
        Map param=new HashMap();
        param.put("id",system.getPssystemid());
        List<JSONObject> oldRelation=relationService.select("select distinct(relationid) from ibzrelation t inner join ibzentity t1 on t.entityid=t1.entityid or t.refentityid=t1.entityid where t1.systemid=#{et.id} ",param);
        for(JSONObject relation: oldRelation){
            delRelation.put(relation.getString("RELATIONID"),1);
        }
        Set<MetaRelationship> list = system.getSysstructure().getRelation();
        list.forEach(relation -> {
            delRelation.remove(relation.getId());
        });
        //移除无效资源
        if(delRelation.size()>0)
            relationService.removeBatch(delRelation.keySet());
        //存储或更新资源saveOrUpdate
        if(list.size()>0)
            relationService.saveBatch(list);
    }
}

