package com.xunhong.erp.turbo.infra.infrastructure.gateway;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xunhong.erp.turbo.api.infra.dto.cmd.DictionaryCreateCmd;
import com.xunhong.erp.turbo.api.infra.dto.cmd.DictionaryDestroyCmd;
import com.xunhong.erp.turbo.api.infra.dto.cmd.DictionaryUpdateCmd;
import com.xunhong.erp.turbo.api.infra.dto.qry.DictionaryListQry;
import com.xunhong.erp.turbo.api.infra.dto.qry.DictionaryPageQry;
import com.xunhong.erp.turbo.api.infra.dto.qry.DictionaryShowQry;
import com.xunhong.erp.turbo.infra.domain.entity.Dictionary;
import com.xunhong.erp.turbo.infra.domain.gateway.DictionaryGateway;
import com.xunhong.erp.turbo.infra.infrastructure.convert.DictionaryConvert;
import com.xunhong.erp.turbo.infra.infrastructure.entity.DictionaryDO;
import com.xunhong.erp.turbo.infra.infrastructure.mapper.DictionaryMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author shenyifei
 */
@Repository
@RequiredArgsConstructor
public class DictionaryGatewayImpl implements DictionaryGateway {
	private final DictionaryMapper dictionaryMapper;
	private final DictionaryConvert dictionaryConvert;

	@Override
	public Dictionary save(DictionaryCreateCmd dictionaryCreateCmd) {
		DictionaryDO dictionaryDO = dictionaryConvert.toDictionaryDO(dictionaryCreateCmd);
		dictionaryMapper.insert(dictionaryDO);

		return dictionaryConvert.toDictionary(dictionaryDO);
	}

	@Override
	public IPage<Dictionary> page(DictionaryPageQry dictionaryPageQry) {
		LambdaQueryWrapper<DictionaryDO> queryWrapper = Wrappers.lambdaQuery(DictionaryDO.class);
		queryWrapper.eq(!StrUtil.isBlankIfStr(dictionaryPageQry.getType()), DictionaryDO::getType, dictionaryPageQry.getType());
		queryWrapper.like(!StrUtil.isBlankIfStr(dictionaryPageQry.getName()), DictionaryDO::getName, dictionaryPageQry.getName());

		queryWrapper.orderByDesc(DictionaryDO::getDictionaryId);

		IPage<DictionaryDO> page = new Page<>(dictionaryPageQry.getPageIndex(), dictionaryPageQry.getPageSize());
		page = dictionaryMapper.selectPage(page, queryWrapper);

		return page.convert(dictionaryConvert::toDictionary);
	}

	@Override
	public List<Dictionary> list(DictionaryListQry dictionaryListQry) {
		LambdaQueryWrapper<DictionaryDO> queryWrapper = Wrappers.lambdaQuery(DictionaryDO.class);
		queryWrapper.eq(!StrUtil.isBlankIfStr(dictionaryListQry.getType()), DictionaryDO::getType, dictionaryListQry.getType());
		queryWrapper.orderByDesc(DictionaryDO::getDictionaryId);
		List<DictionaryDO> dictionaryDOList = dictionaryMapper.selectList(queryWrapper);
		return dictionaryDOList.stream().map(dictionaryConvert::toDictionary).toList();
	}

	@Override
	public Dictionary update(DictionaryUpdateCmd dictionaryUpdateCmd) {
		LambdaQueryWrapper<DictionaryDO> queryWrapper = Wrappers.lambdaQuery(DictionaryDO.class);
		queryWrapper.eq(DictionaryDO::getDictionaryId, dictionaryUpdateCmd.getDictionaryId());
		queryWrapper.last("limit 1");

		DictionaryDO dictionaryDO = dictionaryMapper.selectOne(queryWrapper);

		dictionaryConvert.toDictionaryDO(dictionaryDO, dictionaryUpdateCmd);
		dictionaryMapper.updateById(dictionaryDO);

		return dictionaryConvert.toDictionary(dictionaryDO);
	}

	@Override
	public Dictionary show(DictionaryShowQry dictionaryShowQry) {
		LambdaQueryWrapper<DictionaryDO> queryWrapper = Wrappers.lambdaQuery(DictionaryDO.class);
		queryWrapper.eq(DictionaryDO::getDictionaryId, dictionaryShowQry.getDictionaryId());
		queryWrapper.last("limit 1");

		DictionaryDO dictionaryDO = dictionaryMapper.selectOne(queryWrapper);
		return dictionaryConvert.toDictionary(dictionaryDO);
	}

	@Override
	public void destroy(DictionaryDestroyCmd dictionaryDestroyCmd) {
		LambdaQueryWrapper<DictionaryDO> queryWrapper = Wrappers.lambdaQuery(DictionaryDO.class);
		queryWrapper.eq(DictionaryDO::getDictionaryId, dictionaryDestroyCmd.getDictionaryId());
		queryWrapper.last("limit 1");

		DictionaryDO dictionaryDO = dictionaryMapper.selectOne(queryWrapper);
		dictionaryDO.deleteById();
	}
}

