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.AuditUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.enums.AuditSubjectTypeEnum;
import com.xunhong.erp.turbo.api.biz.dto.qry.AuditPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.AuditShowQry;
import com.xunhong.erp.turbo.biz.domain.entity.Audit;
import com.xunhong.erp.turbo.biz.domain.gateway.AuditGateway;
import com.xunhong.erp.turbo.biz.infrastructure.convert.AuditConvert;
import com.xunhong.erp.turbo.biz.infrastructure.entity.AuditDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderDO;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.AuditMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

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

/**
 * @author shenyifei
 */
@Repository
@RequiredArgsConstructor
public class AuditGatewayImpl implements AuditGateway {
    private final AuditMapper auditMapper;
    private final AuditConvert auditConvert;

	private final OrderMapper orderMapper;

    @Override
    public IPage<Audit> page(AuditPageQry auditPageQry) {
        LambdaQueryWrapper<AuditDO> queryWrapper = Wrappers.lambdaQuery(AuditDO.class);

		queryWrapper.eq(Objects.nonNull(auditPageQry.getAuditId()), AuditDO::getAuditId, auditPageQry.getAuditId());
		queryWrapper.eq(Objects.nonNull(auditPageQry.getType()), AuditDO::getType, auditPageQry.getType());
		queryWrapper.eq(Objects.nonNull(auditPageQry.getState()), AuditDO::getState, auditPageQry.getState());
		queryWrapper.eq(Objects.nonNull(auditPageQry.getSubjectType()), AuditDO::getSubjectType, auditPageQry.getSubjectType());

		queryWrapper.orderByDesc(AuditDO::getCreatedAt);

        IPage<AuditDO> page = new Page<>(auditPageQry.getPageIndex(), auditPageQry.getPageSize());
        page = auditMapper.selectPage(page, queryWrapper);
		Set<Long> orderIdList = page.getRecords().stream().filter(auditDO -> auditDO.getSubjectType().equals(AuditSubjectTypeEnum.PURCHASE_ORDER)).map(AuditDO::getSubjectId).collect(Collectors.toSet());
		if (CollUtil.isNotEmpty(orderIdList)) {
			List<OrderDO> orderDOList = orderMapper.selectByOrderIdList(orderIdList);
			Map<Long, OrderDO> orderDOMap = orderDOList.stream().collect(Collectors.toMap(OrderDO::getOrderId, Function.identity()));
			page.getRecords().forEach(auditDO -> {
				OrderDO orderDO = orderDOMap.get(auditDO.getSubjectId());
				auditDO.setOrderDO(orderDO);
			});
		}

		return page.convert(auditConvert::toAudit);
    }

    @Override
    public Audit update(AuditUpdateCmd auditUpdateCmd) {
		LambdaQueryWrapper<AuditDO> queryWrapper = Wrappers.lambdaQuery(AuditDO.class);
		queryWrapper.eq(AuditDO::getAuditId, auditUpdateCmd.getAuditId());
		queryWrapper.last("limit 1");

		AuditDO auditDO = auditMapper.selectOne(queryWrapper);

		auditConvert.toAuditDO(auditDO, auditUpdateCmd);
		auditMapper.updateById(auditDO);

        return auditConvert.toAudit(auditDO);
    }

    @Override
    public Audit show(AuditShowQry auditShowQry) {
        LambdaQueryWrapper<AuditDO> queryWrapper = Wrappers.lambdaQuery(AuditDO.class);
        queryWrapper.eq(AuditDO::getAuditId, auditShowQry.getAuditId());
        queryWrapper.last("limit 1");

        AuditDO auditDO = auditMapper.selectOne(queryWrapper);
        return auditConvert.toAudit(auditDO);
    }
}

