package com.bocloud.ims.service.topology;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.entity.topology.*;
import com.bocloud.ims.interfaces.topology.PropertyService;
import com.bocloud.ims.repository.topology.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 模型属性 service 实现层
 *
 * @author lyy
 * @Version 1.0
 * @since 2017年10月16日
 */
@Service("propertyService")
public class PropertyServiceImpl implements PropertyService {
    private static final Logger logger = LoggerFactory.getLogger(PropertyServiceImpl.class);
    @Autowired
    private PropertyGroupRepository propertyGroupRepository;
    @Autowired
    private PropertyRepository propertyRepository;
    @Autowired
    private PropertyItemRepository propertyItemRepository;
    @Autowired
    private ModuleRepository moduleRepository;
    @Autowired
    private ModuleRelationRepository moduleRelationRepository;
    @Autowired
    private RelationCategoryRepository relationCategoryRepository;
    @Autowired
    private RelationRepository relationRepository;
    @Autowired
    private RegularExpressionRepository regularExpressionRepository;

    @Override
    public BocloudResult save(JSONObject object, Long moduleId) {
        try {
            // 数据库查询Property数据处理
            List<Property> queryProperty = propertyRepository.queryByModuleId(moduleId);
            HashMap<Long, Property> queryPropertyMap = Maps.newHashMap();
            for (Property property : queryProperty) {
                queryPropertyMap.put(property.getId(), property);
            }
            // 数据库查询item数据处理
            List<PropertyItem> queryPropertyItem = propertyItemRepository.queryByModuleId(moduleId);
            HashMap<Long, PropertyItem> queryPropertyItemMap = Maps.newHashMap();
            for (PropertyItem propertyItem : queryPropertyItem) {
                queryPropertyItemMap.put(propertyItem.getId(), propertyItem);
            }
            // 数据库查询group数据处理
            List<PropertyGroup> queryGroup = propertyGroupRepository.queryByModuleId(moduleId);
            HashMap<Long, PropertyGroup> queryPropertyGroupMap = Maps.newHashMap();
            for (PropertyGroup propertyGroup : queryGroup) {
                queryPropertyGroupMap.put(propertyGroup.getId(), propertyGroup);
            }
            // 前端传入数据处理
            // 传入的Property数据
            JSONArray properties = object.getJSONArray("properties");
            List<Property> newPorperty = properties.toJavaList(Property.class);
            // 编码校验
            validate(newPorperty);
            // 传入的group数据
            JSONArray groups = object.getJSONArray("groups");
            List<PropertyGroup> newGroup = groups.toJavaList(PropertyGroup.class);
            // 同步数据
            for (Property property : newPorperty) {
                // 如果前端传入的property没有id且property对象内没有item对象，直接走新增
                if (null == property.getId()) {
                    if (null == property.getItem()) {
                        Property code = propertyRepository.queryByCode(property.getCode(), property.getModuleId());
                        if (null != code) {
                            return new BocloudResult(false, "传参格式有误,属性:【" + property.getName() + "】中code值:【" + property.getCode() + "】已存在！");
                        }
                        propertyRepository.save(property);
                    } else {
                        // 没有property的id但有item对象，直接新增
                        propertyRepository.save(property);
                        List<PropertyItem> item = property.getItem();
                        for (PropertyItem propertyItem : item) {
                            propertyItem.setModuleId(property.getModuleId());
                            propertyItem.setPropertyId(property.getId());
                            if (property.isTable() && "".equals(String.valueOf(propertyItem.getValue()))) {
                                Integer maxcol = propertyItemRepository.queryMaxDisplaytocol(property.getModuleId(),
                                        property.getId());
                                if (maxcol == null) {
                                    propertyItem.setValue("desc1");
                                } else {
                                    propertyItem.setValue("desc" + (maxcol + 1));
                                }
                            }
                            propertyItemRepository.save(propertyItem);
                        }
                    }
                } else {
                    // 前端传入的property有id但没有item，更新数据库数据
                    if (null == property.getItem()) {
                        propertyRepository.update(property);
                        queryPropertyMap.remove(property.getId());
                    } else {
                        // 传入的数据有property的id，有item对象，更新数据库
                        List<PropertyItem> item = property.getItem();
                        for (PropertyItem propertyItem : item) {
                            propertyItem.setModuleId(property.getModuleId());
                            propertyItem.setPropertyId(property.getId());
                            if (property.isTable() && "".equals(String.valueOf(propertyItem.getValue()))) {
                                Integer maxcol = propertyItemRepository.queryMaxDisplaytocol(property.getModuleId(),
                                        property.getId());
                                if (maxcol == null) {
                                    propertyItem.setValue("desc1");
                                } else {
                                    propertyItem.setValue("desc" + (maxcol + 1));
                                }
                            }
                            if (propertyItem.getId() == null) {
                                propertyItemRepository.save(propertyItem);
                                continue;
                            }
                            propertyItemRepository.update(propertyItem);
                            queryPropertyItemMap.remove(propertyItem.getId());
                        }
                        propertyRepository.update(property);
                        queryPropertyMap.remove(property.getId());
                    }

                }
            }
            // 同步更新分组数据库数据，有group的id就更新，没有就新增
            for (PropertyGroup propertyGroup : newGroup) {
                if (null == propertyGroup.getId()) {
                    propertyGroupRepository.save(propertyGroup);
                } else {
                    propertyGroupRepository.update(propertyGroup);
                    queryPropertyGroupMap.remove(propertyGroup.getId());
                }
            }
            // 同步删除不存在的数据
            Iterator<Property> property = queryPropertyMap.values().iterator();
            while (property.hasNext()) {
                propertyRepository.delete(property.next().getId());
            }
            Iterator<PropertyGroup> group = queryPropertyGroupMap.values().iterator();
            while (group.hasNext()) {
                propertyGroupRepository.delete(group.next().getId());
            }
            Iterator<PropertyItem> item = queryPropertyItemMap.values().iterator();
            while (item.hasNext()) {
                propertyItemRepository.delete(item.next().getId());
            }
        } catch (Exception e) {
            logger.error("save data error:", e);
            return new BocloudResult(false, "保存失败," + e.getMessage());
        }
        return new BocloudResult(true, "保存成功");
    }

    /**
     * 属性编码不能喝instance的列名相同
     *
     * @param newPorperty
     * @throws Exception
     */
    private void validate(List<Property> newPorperty) throws Exception {
        if (ListTool.isEmpty(newPorperty)) {
            return;
        }
        for (Property property : newPorperty) {
            String code = property.getCode().toLowerCase();
            if (code == null || "".equals(code)) {
                throw new Exception("属性编码不能为空");
                // } else if (code.contains("_")) {
                // throw new Exception("属性编码不能含有[_],下划线为关键字");
            } else if (code.equals("id") || code.equals("b_name") || code.equals("is_deleted")
                    || code.equals("module_id") || code.equals("auditflag") || code.equals("gmt_create")
                    || code.equals("gmt_modify") || code.equals("creater_id") || code.equals("mender_id")
                    || code.equals("title")) {
                throw new Exception("属性编码[" + code + "]为关键字，不允许使用。");
            }
            if (!property.isInteger() && !property.isFloat()) {
                property.setMaxValue(0);
                property.setMinValue(0);
            }
            if (property.getRequired() == null) {
                property.setRequired(false);
            }
            if (property.getUniqued() == null) {
                property.setUniqued(false);
            }
            if (property.getReserved() == null) {
                property.setReserved(false);
            }
            if (property.getAutoDiscovery() == null) {
                property.setAutoDiscovery(false);
            }
            if (property.getTitle() == null) {
                property.setTitle(false);
            }
        }

    }

    @Override
    public BocloudResult detail(Long id, String code) {
        try {
            if (null != code) {
                Module module = moduleRepository.queryByCode(code);
                id = module.getId();
            }
            ArrayList<PropertyGroup> ciPropertyGroupLists = (ArrayList<PropertyGroup>) propertyGroupRepository
                    .queryByModuleId(id);
            //查询检验规则
            Map<Long, RegularExpression> regularMap = Maps.newHashMap();
            List<RegularExpression> expressions = regularExpressionRepository.listall();
            for (RegularExpression expression : expressions) {
                regularMap.put(expression.getId(), expression);
            }
            ArrayList<Property> ciPropertyLists = (ArrayList<Property>) propertyRepository.queryByModuleId(id);
            for (Property property : ciPropertyLists) {
                if (property.isSelect() || property.isRedio() || property.isCheckBox() || property.isTable()) {
                    ArrayList<PropertyItem> ciPropertyItemList = (ArrayList<PropertyItem>) propertyItemRepository
                            .queryByPropertyId(property.getId());
                    property.setItem(ciPropertyItemList);
                }
                //存在校验规则的属性返回建议规则
                if (property.getRequired()) {
                    RegularExpression regularExpression = regularMap.get(property.getRegexpId());
                    if (null != regularExpression) {
                        property.setExpression(regularExpression.getExpression());
                        property.setMessage(regularExpression.getMessage());
                    }
                }
            }
            HashMap<Object, Object> maps = Maps.newHashMap();
            maps.put("moduleId", id);
            maps.put("groups", ciPropertyGroupLists);
            maps.put("properties", ciPropertyLists);
            return new BocloudResult(true, maps, "查询成功");
        } catch (Exception e) {
            logger.error("query detail error:", e);
            return new BocloudResult(false, "查询失败");
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public BocloudResult queryProperties(JSONObject params) {
        try {
            Module module = moduleRepository.queryProperties(params);
            // 获取模型所有的属性
            BocloudResult result = this.detail(module.getId(), null);
            HashMap<Object, Object> data = (HashMap<Object, Object>) result.getData();
            data.put("moduleName", module.getName());
            // 查询模型创建的所有关系（全部维度）
            List<HashMap<String, List<Object>>> relations = Lists.newArrayList();
            List<ModuleRelation> moduleRelations = moduleRelationRepository.queryByModuleIdEnable(module.getId());
            List<RelationCategory> list = relationCategoryRepository.list();
            HashMap<String, List<Object>> map = null;
            for (RelationCategory relationCategory : list) {
                List<Object> categoryList = Lists.newArrayList();
                map = Maps.newHashMap();
                for (ModuleRelation moduleRelation : moduleRelations) {
                    // 查询所有的关系维度
                    if (moduleRelation.getCategoryId().equals(relationCategory.getId())) {
                        // 汉化模型之间的关系
                        moduleRelation.setRelationName(relationRepository.query(moduleRelation.getRelationId()).getName());
                        categoryList.add(moduleRelation);
                    }
                }
                map.put(relationCategory.getName(), categoryList);
                relations.add(map);
            }
            data.put("relations", relations);
            return new BocloudResult(true, data, "查询成功");
        } catch (Exception e) {
            logger.error("query detail error:", e);
            return new BocloudResult(false, "查询失败");
        }
    }

}
