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

import cn.hutool.core.collection.CollUtil;
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.biz.dto.cmd.CompanyPaymentAccountCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.CompanyPaymentAccountDestroyCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.CompanyPaymentAccountUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.qry.CompanyPaymentAccountListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.CompanyPaymentAccountPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.CompanyPaymentAccountShowQry;
import com.xunhong.erp.turbo.biz.domain.entity.CompanyPaymentAccount;
import com.xunhong.erp.turbo.biz.domain.gateway.CompanyPaymentAccountGateway;
import com.xunhong.erp.turbo.biz.infrastructure.convert.CompanyPaymentAccountConvert;
import com.xunhong.erp.turbo.biz.infrastructure.entity.CompanyDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.CompanyPaymentAccountDO;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.CompanyMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.CompanyPaymentAccountMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author shenyifei
 */
@Repository
@RequiredArgsConstructor
public class CompanyPaymentAccountGatewayImpl implements CompanyPaymentAccountGateway {
	private final CompanyPaymentAccountMapper companyPaymentAccountMapper;
	private final CompanyPaymentAccountConvert companyPaymentAccountConvert;

	private final CompanyMapper companyMapper;

	@Override
	public CompanyPaymentAccount save(CompanyPaymentAccountCreateCmd companyPaymentAccountCreateCmd) {
		CompanyPaymentAccountDO companyPaymentAccountDO = companyPaymentAccountConvert.toCompanyPaymentAccountDO(companyPaymentAccountCreateCmd);
		companyPaymentAccountMapper.insert(companyPaymentAccountDO);

		return companyPaymentAccountConvert.toCompanyPaymentAccount(companyPaymentAccountDO);
	}

	@Override
	public IPage<CompanyPaymentAccount> page(CompanyPaymentAccountPageQry companyPaymentAccountPageQry) {
		LambdaQueryWrapper<CompanyPaymentAccountDO> queryWrapper = Wrappers.lambdaQuery(CompanyPaymentAccountDO.class);
		queryWrapper.like(StrUtil.isNotBlank(companyPaymentAccountPageQry.getAccountName()), CompanyPaymentAccountDO::getAccountName, companyPaymentAccountPageQry.getAccountName());
		queryWrapper.eq(Objects.nonNull(companyPaymentAccountPageQry.getAccountCategory()), CompanyPaymentAccountDO::getAccountCategory, companyPaymentAccountPageQry.getAccountCategory());
		queryWrapper.eq(Objects.nonNull(companyPaymentAccountPageQry.getCompanyId()), CompanyPaymentAccountDO::getCompanyId, companyPaymentAccountPageQry.getCompanyId());
		queryWrapper.orderByDesc(CompanyPaymentAccountDO::getCreatedAt);

		IPage<CompanyPaymentAccountDO> page = new Page<>(companyPaymentAccountPageQry.getPageIndex(), companyPaymentAccountPageQry.getPageSize());
		page = companyPaymentAccountMapper.selectPage(page, queryWrapper);

		return page.convert(companyPaymentAccountConvert::toCompanyPaymentAccount);
	}

	@Override
	public List<CompanyPaymentAccount> list(CompanyPaymentAccountListQry companyPaymentAccountListQry) {
		LambdaQueryWrapper<CompanyPaymentAccountDO> queryWrapper = Wrappers.lambdaQuery(CompanyPaymentAccountDO.class);
		queryWrapper.like(StrUtil.isNotBlank(companyPaymentAccountListQry.getAccountName()), CompanyPaymentAccountDO::getAccountName, companyPaymentAccountListQry.getAccountName());
		queryWrapper.eq(Objects.nonNull(companyPaymentAccountListQry.getAccountCategory()), CompanyPaymentAccountDO::getAccountCategory, companyPaymentAccountListQry.getAccountCategory());
		queryWrapper.eq(Objects.nonNull(companyPaymentAccountListQry.getCompanyId()), CompanyPaymentAccountDO::getCompanyId, companyPaymentAccountListQry.getCompanyId());
		queryWrapper.eq(Objects.nonNull(companyPaymentAccountListQry.getStatus()), CompanyPaymentAccountDO::getStatus, companyPaymentAccountListQry.getStatus());
		queryWrapper.orderByDesc(CompanyPaymentAccountDO::getCreatedAt);
		List<CompanyPaymentAccountDO> companyPaymentAccountDOList = companyPaymentAccountMapper.selectList(queryWrapper);

		List<Long> companyIdList = companyPaymentAccountDOList.stream().map(CompanyPaymentAccountDO::getCompanyId).toList();

		if (CollUtil.isNotEmpty(companyIdList)) {
			LambdaQueryWrapper<CompanyDO> queryWrapper1 = Wrappers.lambdaQuery(CompanyDO.class);
			queryWrapper1.in(CompanyDO::getCompanyId, companyIdList);
			List<CompanyDO> companyDOList = companyMapper.selectList(queryWrapper1);
			Map<Long, CompanyDO> companyDOMap = companyDOList.stream().collect(Collectors.toMap(CompanyDO::getCompanyId, Function.identity()));
			companyPaymentAccountDOList.forEach(companyPaymentAccountDO -> companyPaymentAccountDO.setCompanyDO(companyDOMap.get(companyPaymentAccountDO.getCompanyId())));
		}

		return companyPaymentAccountDOList.stream().map(companyPaymentAccountConvert::toCompanyPaymentAccount).toList();
	}

	@Override
	public CompanyPaymentAccount update(CompanyPaymentAccountUpdateCmd companyPaymentAccountUpdateCmd) {
		LambdaQueryWrapper<CompanyPaymentAccountDO> queryWrapper = Wrappers.lambdaQuery(CompanyPaymentAccountDO.class);
		queryWrapper.eq(CompanyPaymentAccountDO::getAccountId, companyPaymentAccountUpdateCmd.getAccountId());
		queryWrapper.last("limit 1");

		CompanyPaymentAccountDO companyPaymentAccountDO = companyPaymentAccountMapper.selectOne(queryWrapper);

		companyPaymentAccountConvert.toCompanyPaymentAccountDO(companyPaymentAccountDO, companyPaymentAccountUpdateCmd);
		companyPaymentAccountMapper.updateById(companyPaymentAccountDO);

		return companyPaymentAccountConvert.toCompanyPaymentAccount(companyPaymentAccountDO);
	}

	@Override
	public CompanyPaymentAccount show(CompanyPaymentAccountShowQry companyPaymentAccountShowQry) {
		LambdaQueryWrapper<CompanyPaymentAccountDO> queryWrapper = Wrappers.lambdaQuery(CompanyPaymentAccountDO.class);
		queryWrapper.eq(CompanyPaymentAccountDO::getAccountId, companyPaymentAccountShowQry.getAccountId());
		queryWrapper.last("limit 1");

		CompanyPaymentAccountDO companyPaymentAccountDO = companyPaymentAccountMapper.selectOne(queryWrapper);
		return companyPaymentAccountConvert.toCompanyPaymentAccount(companyPaymentAccountDO);
	}

	@Override
	public void destroy(CompanyPaymentAccountDestroyCmd companyPaymentAccountDestroyCmd) {
		LambdaQueryWrapper<CompanyPaymentAccountDO> queryWrapper = Wrappers.lambdaQuery(CompanyPaymentAccountDO.class);
		queryWrapper.eq(CompanyPaymentAccountDO::getAccountId, companyPaymentAccountDestroyCmd.getAccountId());
		queryWrapper.last("limit 1");

		CompanyPaymentAccountDO companyPaymentAccountDO = companyPaymentAccountMapper.selectOne(queryWrapper);
		companyPaymentAccountDO.deleteById();
	}
}

