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.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.OrderCostCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.qry.OrderCostPageQry;
import com.xunhong.erp.turbo.biz.domain.entity.OrderCost;
import com.xunhong.erp.turbo.biz.domain.gateway.OrderCostGateway;
import com.xunhong.erp.turbo.biz.infrastructure.convert.OrderCostConvert;
import com.xunhong.erp.turbo.biz.infrastructure.entity.CostDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderCompanyDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderCostDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.PurchaseOrderDO;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.CostMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderCompanyMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderCostMapper;
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 OrderCostGatewayImpl implements OrderCostGateway {
	private final OrderCostMapper orderCostMapper;
	private final OrderCostConvert orderCostConvert;

	private final OrderCompanyMapper orderCompanyMapper;
	private final PurchaseOrderMapper purchaseOrderMapper;

	private final CostMapper costMapper;


	@Override
	public IPage<OrderCost> page(OrderCostPageQry orderCostPageQry) {
		LambdaQueryWrapper<OrderCostDO> queryWrapper = Wrappers.lambdaQuery(OrderCostDO.class);
		queryWrapper.eq(Objects.nonNull(orderCostPageQry.getCostId()), OrderCostDO::getCostId, orderCostPageQry.getCostId());
		queryWrapper.eq(Objects.nonNull(orderCostPageQry.getIsPaid()), OrderCostDO::getIsPaid, orderCostPageQry.getIsPaid());
		queryWrapper.in(Objects.nonNull(orderCostPageQry.getBelongs()), OrderCostDO::getBelong, orderCostPageQry.getBelongs());

		queryWrapper.orderByDesc(OrderCostDO::getCreatedAt);

		IPage<OrderCostDO> page = new Page<>(orderCostPageQry.getPageIndex(), orderCostPageQry.getPageSize());
		page = orderCostMapper.selectPage(page, queryWrapper, orderCostPageQry);

		List<Long> orderIdList = page.getRecords().stream().map(OrderCostDO::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(orderCostDO -> {
				OrderCompanyDO orderCompanyDO = orderCompanyDOMap.get(orderCostDO.getOrderId());
				if (Objects.nonNull(orderCompanyDO)) {
					orderCostDO.setOrderCompanyDO(orderCompanyDO);
				}
			});

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

		return page.convert(orderCostConvert::toOrderCost);
	}

	@Override
	public OrderCost save(OrderCostCreateCmd orderCostCreateCmd) {
		CostDO costDO = costMapper.selectById(orderCostCreateCmd.getCostId());
		OrderCostDO orderCostDO = orderCostConvert.toOrderCostDO(orderCostCreateCmd);
		orderCostDO.setUnit(costDO.getUnit());
		orderCostDO.setName(costDO.getName());
		orderCostDO.setBelong(costDO.getBelong());
		orderCostMapper.insert(orderCostDO);

		return orderCostConvert.toOrderCost(orderCostDO);
	}
}

