package net.srt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import net.srt.convert.DataOdsConvert;
import net.srt.dao.DataOdsDao;
import net.srt.entity.DataOdsEntity;
import net.srt.framework.common.config.Config;
import net.srt.framework.common.page.PageResult;
import net.srt.framework.common.utils.BeanUtil;
import net.srt.framework.common.utils.SqlUtils;
import net.srt.framework.mybatis.service.impl.BaseServiceImpl;
import net.srt.query.DataOdsQuery;
import net.srt.service.DataOdsService;
import net.srt.vo.ColumnDescriptionVo;
import net.srt.vo.DataOdsVO;
import net.srt.vo.SchemaTableDataVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import srt.cloud.framework.dbswitch.common.type.ProductTypeEnum;
import srt.cloud.framework.dbswitch.common.util.StringUtil;
import srt.cloud.framework.dbswitch.core.model.ColumnDescription;
import srt.cloud.framework.dbswitch.core.model.SchemaTableData;
import srt.cloud.framework.dbswitch.core.service.IMetaDataByJdbcService;
import srt.cloud.framework.dbswitch.core.service.impl.MetaDataByJdbcServiceImpl;

import java.util.List;

/**
 * 数据集成-贴源数据
 *
 * @author zrx 985134801@qq.com
 * @since 1.0.0 2022-11-07
 */
@Service
@AllArgsConstructor
public class DataOdsServiceImpl extends BaseServiceImpl<DataOdsDao, DataOdsEntity> implements DataOdsService {

	private final Config config;

	@Override
	public PageResult<DataOdsVO> page(DataOdsQuery query) {
		IPage<DataOdsEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
		return new PageResult<>(DataOdsConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
	}

	private LambdaQueryWrapper<DataOdsEntity> getWrapper(DataOdsQuery query) {
		LambdaQueryWrapper<DataOdsEntity> wrapper = Wrappers.lambdaQuery();
		wrapper.like(StringUtil.isNotBlank(query.getTableName()), DataOdsEntity::getTableName, query.getTableName());
		wrapper.like(StringUtil.isNotBlank(query.getRemarks()), DataOdsEntity::getRemarks, query.getRemarks());
		wrapper.eq(query.getProjectId() != null, DataOdsEntity::getProjectId, query.getProjectId());
		dataScopeWithoutOrgId(wrapper);
		return wrapper;
	}

	@Override
	public void save(DataOdsVO vo) {
		DataOdsEntity entity = DataOdsConvert.INSTANCE.convert(vo);

		baseMapper.insert(entity);
	}

	@Override
	public void update(DataOdsVO vo) {
		DataOdsEntity entity = DataOdsConvert.INSTANCE.convert(vo);

		updateById(entity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(List<Long> idList) {
		removeByIds(idList);
	}

	@Override
	public DataOdsEntity getByTableName(Long projectId, String tableName) {
		LambdaQueryWrapper<DataOdsEntity> wrapper = new LambdaQueryWrapper<>();
		return baseMapper.selectOne(wrapper.eq(DataOdsEntity::getTableName, tableName).eq(DataOdsEntity::getProjectId, projectId));
	}

	@Override
	public List<ColumnDescriptionVo> getColumnInfo(Long id, String tableName) {
		//DataOdsEntity dataOdsEntity = baseMapper.selectById(id);
		IMetaDataByJdbcService service = new MetaDataByJdbcServiceImpl(ProductTypeEnum.getByIndex(getProject().getDbType()));
		List<ColumnDescription> columnDescriptions = service.queryTableColumnMeta(getProject().getDbUrl(), getProject().getDbUsername(), getProject().getDbPassword(), getProject().getDbName(), tableName);
		List<String> pks = service.queryTablePrimaryKeys(getProject().getDbUrl(), getProject().getDbUsername(), getProject().getDbPassword(), getProject().getDbName(), tableName);
		return BeanUtil.copyListProperties(columnDescriptions, ColumnDescriptionVo::new, (oldItem, newItem) -> {
			newItem.setFieldName(StringUtil.isNotBlank(newItem.getFieldName()) ? newItem.getFieldName() : newItem.getLabelName());
			if (pks.contains(newItem.getFieldName())) {
				newItem.setPk(true);
			}
		});
	}

	@Override
	public SchemaTableDataVo getTableData(Long id, String tableName) {
		IMetaDataByJdbcService service = new MetaDataByJdbcServiceImpl(ProductTypeEnum.getByIndex(getProject().getDbType()));
		SchemaTableData schemaTableData = service.queryTableDataBySql(getProject().getDbUrl(), getProject().getDbUsername(), getProject().getDbPassword(), String.format("SELECT * FROM %s LIMIT 50", tableName), 50);
		return SchemaTableDataVo.builder().columns(SqlUtils.convertColumns(schemaTableData.getColumns())).rows(SqlUtils.convertRows(schemaTableData.getColumns(), schemaTableData.getRows())).build();
	}
}
