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

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSONObject;
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.OrderSupplierBatchInvoiceUploadCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.OrderSupplierUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.qry.OrderSupplierPageQry;
import com.xunhong.erp.turbo.biz.domain.entity.OrderSupplier;
import com.xunhong.erp.turbo.biz.domain.gateway.OrderSupplierGateway;
import com.xunhong.erp.turbo.biz.infrastructure.convert.OrderSupplierConvert;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderCompanyDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderSupplierDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.PurchaseOrderDO;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderCompanyMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderSupplierMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.PurchaseOrderMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class OrderSupplierGatewayImpl implements OrderSupplierGateway {
	private final OrderSupplierMapper orderSupplierMapper;
	private final OrderSupplierConvert orderSupplierConvert;

	private final OrderCompanyMapper orderCompanyMapper;
	private final PurchaseOrderMapper purchaseOrderMapper;


	@Override
	public IPage<OrderSupplier> page(OrderSupplierPageQry orderSupplierPageQry) {
		LambdaQueryWrapper<OrderSupplierDO> queryWrapper = Wrappers.lambdaQuery(OrderSupplierDO.class);
		queryWrapper.eq(Objects.nonNull(orderSupplierPageQry.getSupplierId()), OrderSupplierDO::getSupplierId, orderSupplierPageQry.getSupplierId());
		queryWrapper.eq(Objects.nonNull(orderSupplierPageQry.getInvoiceUpload()), OrderSupplierDO::getInvoiceUpload, orderSupplierPageQry.getInvoiceUpload());
		queryWrapper.eq(Objects.nonNull(orderSupplierPageQry.getIsPaid()), OrderSupplierDO::getIsPaid, orderSupplierPageQry.getIsPaid());

		queryWrapper.orderByDesc(OrderSupplierDO::getCreatedAt);

		IPage<OrderSupplierDO> page = new Page<>(orderSupplierPageQry.getPageIndex(), orderSupplierPageQry.getPageSize());
		page = orderSupplierMapper.selectPage(page, queryWrapper, orderSupplierPageQry);

		List<Long> orderIdList = page.getRecords().stream().map(OrderSupplierDO::getOrderId).toList();
		if (CollUtil.isNotEmpty(orderIdList)) {
			LambdaQueryWrapper<OrderCompanyDO> queryWrapper2 = Wrappers.lambdaQuery(OrderCompanyDO.class);
			queryWrapper2.in(OrderCompanyDO::getOrderId, orderIdList);
			queryWrapper2.select(OrderCompanyDO::getOrderId, OrderCompanyDO::getShortName, OrderCompanyDO::getFullName, OrderCompanyDO::getCompanyId);
			List<OrderCompanyDO> orderCompanyDOList = orderCompanyMapper.selectList(queryWrapper2);
			Map<Long, OrderCompanyDO> orderCompanyDOMap = orderCompanyDOList.stream().collect(Collectors.toMap(OrderCompanyDO::getOrderId, Function.identity()));
			page.getRecords().forEach(orderSupplierDO -> {
				OrderCompanyDO orderCompanyDO = orderCompanyDOMap.get(orderSupplierDO.getOrderId());
				if (Objects.nonNull(orderCompanyDO)) {
					orderSupplierDO.setOrderCompanyDO(orderCompanyDO);
				}
			});

			List<PurchaseOrderDO> purchaseOrderDOList = purchaseOrderMapper.selectByOrderIdList(orderIdList);
			Map<Long, PurchaseOrderDO> purchaseOrderDOMap = purchaseOrderDOList.stream().collect(Collectors.toMap(PurchaseOrderDO::getOrderId, Function.identity()));
			page.getRecords().forEach(orderSupplierDO -> {
				PurchaseOrderDO purchaseOrderDO = purchaseOrderDOMap.get(orderSupplierDO.getOrderId());
				if (Objects.nonNull(purchaseOrderDO)) {
					orderSupplierDO.setPurchaseOrderDO(purchaseOrderDO);
				}
			});
		}

		return page.convert(orderSupplierConvert::toOrderSupplier);
	}

	@Override
	public OrderSupplier update(OrderSupplierUpdateCmd orderSupplierUpdateCmd) {
		LambdaQueryWrapper<OrderSupplierDO> queryWrapper = Wrappers.lambdaQuery(OrderSupplierDO.class);
		queryWrapper.eq(OrderSupplierDO::getOrderSupplierId, orderSupplierUpdateCmd.getOrderSupplierId());
		queryWrapper.last("limit 1");

		OrderSupplierDO orderSupplierDO = orderSupplierMapper.selectOne(queryWrapper);

		orderSupplierConvert.toOrderSupplierDO(orderSupplierDO, orderSupplierUpdateCmd);
		orderSupplierMapper.updateById(orderSupplierDO);

		return orderSupplierConvert.toOrderSupplier(orderSupplierDO);
	}

	@Override
	public void batchInvoiceUpload(OrderSupplierBatchInvoiceUploadCmd orderSupplierBatchInvoiceUploadCmd) {
		// 构建更新条件
		LambdaUpdateWrapper<OrderSupplierDO> updateWrapper = Wrappers.lambdaUpdate(OrderSupplierDO.class);
		updateWrapper.in(OrderSupplierDO::getOrderSupplierId, orderSupplierBatchInvoiceUploadCmd.getOrderSupplierIdList())
			.set(OrderSupplierDO::getInvoiceUpload, true)
			.set(OrderSupplierDO::getInvoiceImg, JSONObject.toJSONString(orderSupplierBatchInvoiceUploadCmd.getInvoiceImg()));

		// 执行更新
		orderSupplierMapper.update(updateWrapper);
	}
}

