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

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.SupplierInvoiceCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.SupplierInvoiceDestroyCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.SupplierInvoiceUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.common.OrderSupplierInvoice;
import com.xunhong.erp.turbo.api.biz.dto.qry.SupplierInvoiceListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.SupplierInvoicePageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.SupplierInvoiceShowQry;
import com.xunhong.erp.turbo.biz.domain.entity.SupplierInvoice;
import com.xunhong.erp.turbo.biz.domain.gateway.SupplierInvoiceGateway;
import com.xunhong.erp.turbo.biz.infrastructure.convert.SupplierInvoiceConvert;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderSupplierDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.SupplierInvoiceDO;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderSupplierMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.SupplierInvoiceMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author shenyifei
 */
@Repository
@RequiredArgsConstructor
public class SupplierInvoiceGatewayImpl implements SupplierInvoiceGateway {
	private final SupplierInvoiceMapper supplierInvoiceMapper;
	private final SupplierInvoiceConvert supplierInvoiceConvert;

	private final OrderSupplierMapper orderSupplierMapper;

	@Override
	@Transactional
	public SupplierInvoice save(SupplierInvoiceCreateCmd supplierInvoiceCreateCmd) {
		SupplierInvoiceDO supplierInvoiceDO = supplierInvoiceConvert.toInvoiceDO(supplierInvoiceCreateCmd);
		supplierInvoiceMapper.insert(supplierInvoiceDO);

		List<Long> orderSupplierIdList = supplierInvoiceCreateCmd.getOrderSupplierInvoiceList().stream().map(OrderSupplierInvoice::getOrderSupplierId).toList();
		if (CollUtil.isNotEmpty(orderSupplierIdList)) {
			LambdaUpdateWrapper<OrderSupplierDO> updateWrapper = Wrappers.lambdaUpdate(OrderSupplierDO.class);
			updateWrapper.in(OrderSupplierDO::getOrderSupplierId, orderSupplierIdList);
			updateWrapper.set(OrderSupplierDO::getInvoiceUpload, Boolean.TRUE);
			updateWrapper.set(OrderSupplierDO::getInvoiceId, supplierInvoiceDO.getSupplierInvoiceId());
			orderSupplierMapper.update(null, updateWrapper);
		}

		return supplierInvoiceConvert.toInvoice(supplierInvoiceDO);
	}

	@Override
	public IPage<SupplierInvoice> page(SupplierInvoicePageQry supplierInvoicePageQry) {
		LambdaQueryWrapper<SupplierInvoiceDO> queryWrapper = Wrappers.lambdaQuery(SupplierInvoiceDO.class);
		queryWrapper.orderByDesc(SupplierInvoiceDO::getCreatedAt);

		IPage<SupplierInvoiceDO> page = new Page<>(supplierInvoicePageQry.getPageIndex(), supplierInvoicePageQry.getPageSize());
		page = supplierInvoiceMapper.selectPage(page, queryWrapper);

		return page.convert(supplierInvoiceConvert::toInvoice);
	}

	@Override
	public List<SupplierInvoice> list(SupplierInvoiceListQry supplierInvoiceListQry) {
		LambdaQueryWrapper<SupplierInvoiceDO> queryWrapper = Wrappers.lambdaQuery(SupplierInvoiceDO.class);
		List<SupplierInvoiceDO> supplierInvoiceDOList = supplierInvoiceMapper.selectList(queryWrapper);
		return supplierInvoiceDOList.stream().map(supplierInvoiceConvert::toInvoice).toList();
	}

	@Override
	public SupplierInvoice update(SupplierInvoiceUpdateCmd invoiceUpdateCmd) {
		LambdaQueryWrapper<SupplierInvoiceDO> queryWrapper = Wrappers.lambdaQuery(SupplierInvoiceDO.class);
		queryWrapper.eq(SupplierInvoiceDO::getSupplierInvoiceId, invoiceUpdateCmd.getSupplierInvoiceId());
		queryWrapper.last("limit 1");

		SupplierInvoiceDO supplierInvoiceDO = supplierInvoiceMapper.selectOne(queryWrapper);

		supplierInvoiceConvert.toInvoiceDO(supplierInvoiceDO, invoiceUpdateCmd);
		supplierInvoiceMapper.updateById(supplierInvoiceDO);

		return supplierInvoiceConvert.toInvoice(supplierInvoiceDO);
	}

	@Override
	public SupplierInvoice show(SupplierInvoiceShowQry supplierInvoiceShowQry) {
		LambdaQueryWrapper<SupplierInvoiceDO> queryWrapper = Wrappers.lambdaQuery(SupplierInvoiceDO.class);
		queryWrapper.eq(SupplierInvoiceDO::getSupplierInvoiceId, supplierInvoiceShowQry.getSupplierInvoiceId());
		queryWrapper.last("limit 1");

		SupplierInvoiceDO supplierInvoiceDO = supplierInvoiceMapper.selectOne(queryWrapper);
		return supplierInvoiceConvert.toInvoice(supplierInvoiceDO);
	}

	@Override
	public void destroy(SupplierInvoiceDestroyCmd supplierInvoiceDestroyCmd) {
		LambdaQueryWrapper<SupplierInvoiceDO> queryWrapper = Wrappers.lambdaQuery(SupplierInvoiceDO.class);
		queryWrapper.eq(SupplierInvoiceDO::getSupplierInvoiceId, supplierInvoiceDestroyCmd.getSupplierInvoiceId());
		queryWrapper.last("limit 1");

		SupplierInvoiceDO supplierInvoiceDO = supplierInvoiceMapper.selectOne(queryWrapper);
		supplierInvoiceDO.deleteById();
	}
}

