package cn.datax.service.data.masterdata.service.impl;

import cn.datax.common.core.DataConstant;
import cn.datax.common.exception.DataException;
import cn.datax.service.data.masterdata.api.entity.ModelColumnEntity;
import cn.datax.service.data.masterdata.api.entity.ModelEntity;
import cn.datax.service.data.masterdata.api.dto.ModelDto;
import cn.datax.service.data.masterdata.dao.ModelColumnDao;
import cn.datax.service.data.masterdata.dao.MysqlDynamicDao;
import cn.datax.service.data.masterdata.mapstruct.ModelMapstruct;
import cn.datax.service.data.masterdata.service.ModelService;
import cn.datax.service.data.masterdata.dao.ModelDao;
import cn.datax.common.base.BaseServiceImpl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 主数据模型表 服务实现类
 * </p>
 *
 * @author yuwei
 * @since 2020-08-26
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ModelServiceImpl extends BaseServiceImpl<ModelDao, ModelEntity> implements ModelService {

    @Autowired
    private ModelDao modelDao;

    @Autowired
    private ModelMapstruct modelMapstruct;

    @Autowired
    private ModelColumnDao modelColumnDao;

    @Autowired
    private MysqlDynamicDao dynamicDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ModelEntity saveModel(ModelDto modelDto) {
        ModelEntity model = modelMapstruct.toEntity(modelDto);
        model.setIsSync(DataConstant.TrueOrFalse.FALSE.getKey());
        model.setModelPhysicalTable("dynamic_" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        modelDao.insert(model);
        String modelId = model.getId();
        List<ModelColumnEntity> modelColumns = model.getModelColumns();
        if(CollUtil.isNotEmpty(modelColumns)){
            modelColumns.stream().forEach(c -> {
                c.setModelId(modelId);
                modelColumnDao.insert(c);
            });
        }
        return model;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ModelEntity updateModel(ModelDto modelDto) {
        ModelEntity model = modelMapstruct.toEntity(modelDto);
        modelDao.updateById(model);
        String modelId = model.getId();
        modelColumnDao.delete(Wrappers.<ModelColumnEntity>lambdaQuery()
                .eq(ModelColumnEntity::getModelId, modelId));
        List<ModelColumnEntity> modelColumns = model.getModelColumns();
        if(CollUtil.isNotEmpty(modelColumns)){
            modelColumns.stream().forEach(c -> {
                c.setModelId(modelId);
                modelColumnDao.insert(c);
            });
        }
        return model;
    }

    @Override
    public ModelEntity getModelById(String id) {
        ModelEntity modelEntity = super.getById(id);
        return modelEntity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteModelById(String id) {
        modelColumnDao.delete(Wrappers.<ModelColumnEntity>lambdaQuery()
                .eq(ModelColumnEntity::getModelId, id));
        modelDao.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteModelBatch(List<String> ids) {
        modelColumnDao.delete(Wrappers.<ModelColumnEntity>lambdaQuery()
                .in(ModelColumnEntity::getModelId, ids));
        modelDao.deleteBatchIds(ids);
    }

    @Override
    public void createTable(String id) {
        ModelEntity modelEntity = super.getById(id);
        if (DataConstant.TrueOrFalse.TRUE.getKey().equals(modelEntity.getIsSync())) {
            throw new DataException("重复建模");
        }
        dynamicDao.createTable(modelEntity);
        modelEntity.setIsSync(DataConstant.TrueOrFalse.TRUE.getKey());
        modelDao.updateById(modelEntity);
    }

    @Override
    public void dropTable(String id) {
        ModelEntity modelEntity = super.getById(id);
        String tableName = modelEntity.getModelPhysicalTable();
        dynamicDao.dropTable(tableName);
    }

    @Override
    public Map<String, Object> getTableParamById(String id) {
        ModelEntity modelEntity = super.getById(id);
        String tableName = modelEntity.getModelPhysicalTable();
        List<ModelColumnEntity> modelColumns = modelEntity.getModelColumns();
        // 列表展示字段
        List<Map<String, Object>> columnList = modelColumns.stream().filter(s -> DataConstant.TrueOrFalse.TRUE.getKey().equals(s.getIsList())).map(s -> {
            Map<String, Object> map = new HashMap<>(2);
            map.put("prop", s.getColumnName());
            map.put("label", s.getColumnComment());
            return map;
        }).collect(Collectors.toList());
        // 查询参数字段
        List<Map<String, Object>> queryList = modelColumns.stream().filter(s -> DataConstant.TrueOrFalse.TRUE.getKey().equals(s.getIsQuery())).map(s -> {
            Map<String, Object> map = new HashMap<>(2);
            map.put("column", s.getColumnName());
            map.put("type", s.getQueryType());
            map.put("columnName", s.getColumnComment());
            return map;
        }).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("tableName", tableName);
        map.put("columnList", columnList);
        map.put("queryList", queryList);
        return map;
    }
}
