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

import cn.hutool.core.text.CharSequenceUtil;
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.user.dto.cmd.*;
import com.xunhong.erp.turbo.api.user.dto.qry.EmployeeListQry;
import com.xunhong.erp.turbo.api.user.dto.qry.EmployeePageQry;
import com.xunhong.erp.turbo.api.user.dto.qry.EmployeeShowQry;
import com.xunhong.erp.turbo.user.domain.entity.Employee;
import com.xunhong.erp.turbo.user.domain.gateway.EmployeeGateway;
import com.xunhong.erp.turbo.user.infrastructure.convert.EmployeeConvert;
import com.xunhong.erp.turbo.user.infrastructure.entity.EmployeeDO;
import com.xunhong.erp.turbo.user.infrastructure.mapper.EmployeeMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Objects;

/**
 * @author shenyifei
 */
@Repository
@RequiredArgsConstructor
public class EmployeeGatewayImpl implements EmployeeGateway {
	private final EmployeeMapper employeeMapper;
	private final EmployeeConvert employeeConvert;

	@Override
	public Employee save(EmployeeCreateCmd employeeCreateCmd) {
		EmployeeDO employeeDO = employeeConvert.toEmployeeDO(employeeCreateCmd);
		employeeMapper.insert(employeeDO);

		return employeeConvert.toEmployee(employeeDO);
	}

	@Override
	public IPage<Employee> page(EmployeePageQry employeePageQry) {
		LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery(EmployeeDO.class);
		queryWrapper.eq(Objects.nonNull(employeePageQry.getEmployeeId()), EmployeeDO::getEmployeeId, employeePageQry.getEmployeeId());
		queryWrapper.like(StrUtil.isNotEmpty(employeePageQry.getName()), EmployeeDO::getName, employeePageQry.getName());
		queryWrapper.eq(CharSequenceUtil.isNotBlank(employeePageQry.getNumber()), EmployeeDO::getNumber, employeePageQry.getNumber());
		queryWrapper.eq(CharSequenceUtil.isNotBlank(employeePageQry.getPhone()), EmployeeDO::getPhone, employeePageQry.getPhone());
		queryWrapper.eq(Objects.nonNull(employeePageQry.getStatus()), EmployeeDO::getStatus, employeePageQry.getStatus());

		IPage<EmployeeDO> page = new Page<>(employeePageQry.getPageIndex(), employeePageQry.getPageSize());
		page = employeeMapper.selectPage(page, queryWrapper);

		return page.convert(employeeConvert::toEmployee);
	}

	@Override
	public List<Employee> list(EmployeeListQry employeeListQry) {
		LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery(EmployeeDO.class);
		List<EmployeeDO> employeeDOList = employeeMapper.selectList(queryWrapper);
		return employeeDOList.stream().map(employeeConvert::toEmployee).toList();
	}

	@Override
	public Employee update(EmployeeUpdateCmd employeeUpdateCmd) {
		LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery(EmployeeDO.class);
		queryWrapper.eq(EmployeeDO::getEmployeeId, employeeUpdateCmd.getEmployeeId());
		queryWrapper.select(EmployeeDO::getEmployeeId);
		EmployeeDO employeeDO = employeeMapper.selectOne(queryWrapper);

		employeeConvert.toEmployeeDO(employeeDO, employeeUpdateCmd);
		employeeMapper.updateById(employeeDO);
		return employeeConvert.toEmployee(employeeDO);
	}

	@Override
	public Employee show(EmployeeShowQry employeeShowQry) {
		LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery(EmployeeDO.class);
		queryWrapper.eq(Objects.nonNull(employeeShowQry.getEmployeeId()), EmployeeDO::getEmployeeId, employeeShowQry.getEmployeeId());
		queryWrapper.eq(Objects.nonNull(employeeShowQry.getUserId()), EmployeeDO::getUserId, employeeShowQry.getUserId());
		EmployeeDO employeeDO = employeeMapper.selectOne(queryWrapper);

		return employeeConvert.toEmployee(employeeDO);
	}

	@Override
	public void destroy(EmployeeDestroyCmd employeeDestroyCmd) {
		employeeMapper.deleteById(employeeDestroyCmd.getEmployeeId());
	}

	@Override
	public Employee disable(EmployeeDisableCmd employeeDisableCmd) {
		LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery(EmployeeDO.class);
		queryWrapper.eq(EmployeeDO::getEmployeeId, employeeDisableCmd.getEmployeeId());
		EmployeeDO employeeDO = employeeMapper.selectOne(queryWrapper);

		employeeDO.setStatus(Boolean.TRUE);
		employeeMapper.updateById(employeeDO);

		return employeeConvert.toEmployee(employeeDO);
	}

	@Override
	public Employee updateAvatar(EmployeeUpdateAvatarCmd employeeUpdateAvatarCmd) {
		LambdaQueryWrapper<EmployeeDO> queryWrapper = Wrappers.lambdaQuery(EmployeeDO.class);
		queryWrapper.eq(EmployeeDO::getEmployeeId, employeeUpdateAvatarCmd.getEmployeeId());
		queryWrapper.select(EmployeeDO::getEmployeeId, EmployeeDO::getAvatar);
		EmployeeDO employeeDO = employeeMapper.selectOne(queryWrapper);
		employeeDO.setAvatar(employeeUpdateAvatarCmd.getAvatar());
		employeeMapper.updateById(employeeDO);
		return employeeConvert.toEmployee(employeeDO);
	}
}
