package com.zd.airbottle.service.impl;

import com.zd.airbottle.constant.AuditType;
import com.zd.airbottle.domain.QpSupplier;
import com.zd.airbottle.domain.QpSupplierSyntheticalAudit;
import com.zd.airbottle.domain.QpTransportCar;
import com.zd.airbottle.domain.QpTransportUser;
import com.zd.airbottle.domain.vo.QpSupplierSyntheticalAuditVo;
import com.zd.airbottle.domain.vo.QpSupplierVo;
import com.zd.airbottle.domain.vo.QpTransportCarVo;
import com.zd.airbottle.domain.vo.QpTransportUserVo;
import com.zd.airbottle.mapper.QpSupplierSyntheticalAuditMapper;
import com.zd.airbottle.service.IQpSupplierService;
import com.zd.airbottle.service.IQpSupplierSyntheticalAuditService;
import com.zd.airbottle.service.IQpTransportCarService;
import com.zd.airbottle.service.IQpTransportUserService;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.bean.TransferUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 供应商综合审核Service业务层处理
 */
@Service
public class QpSupplierSyntheticalAuditServiceImpl implements IQpSupplierSyntheticalAuditService {
    @Autowired
    private QpSupplierSyntheticalAuditMapper qpSupplierSyntheticalAuditMapper;
    @Autowired
    private IQpSupplierService supplierService;

    @Autowired
    private IQpTransportUserService transportUserService;
    @Autowired
    private IQpTransportCarService carService;

    /**
     * 查询供应商综合审核列表
     *
     * @param qpSupplierSyntheticalAudit 供应商综合审核
     * @return 供应商综合审核
     */
    @Override
    public List<QpSupplierSyntheticalAudit> selectQpSupplierSyntheticalAuditList(QpSupplierSyntheticalAudit qpSupplierSyntheticalAudit) {
        return qpSupplierSyntheticalAuditMapper.selectQpSupplierSyntheticalAuditList(qpSupplierSyntheticalAudit);

    }

    private List<QpSupplierSyntheticalAuditVo> getTransportCar(List<QpSupplierSyntheticalAudit> qpSupplierSyntheticalAudits, Long[] ids) {
        List<QpTransportCar> qpTransportCars = carService.selectQpTransportCarList(ids);
        Map<Long, QpTransportCar> transportCarMap = qpTransportCars.stream().collect(Collectors.toMap(QpTransportCar::getId, qt -> qt));
        Map<Long, QpSupplier> qpSupplierMap = getSupplierMap(qpTransportCars.stream().map(QpTransportCar::getSupplierId));

        List<QpSupplierSyntheticalAuditVo> supplierSyntheticalAuditVos = new ArrayList<>();
        qpSupplierSyntheticalAudits.forEach(qssa -> {
            QpSupplierSyntheticalAuditVo syntheticalAuditVo = new QpSupplierSyntheticalAuditVo();
            BeanUtils.copyProperties(qssa, syntheticalAuditVo);
            Long syntheticalId = qssa.getSyntheticalId();
            if (!transportCarMap.isEmpty() && transportCarMap.containsKey(syntheticalId)) {
                QpTransportCarVo transportCarVo = new QpTransportCarVo();
                QpTransportCar transportCar = transportCarMap.get(syntheticalId);
                BeanUtils.copyProperties(transportCar, transportCarVo);
                syntheticalAuditVo.setTransportCarVo(transportCarVo);
                Long supplierId = transportCar.getSupplierId();
                if (!qpSupplierMap.isEmpty() && qpSupplierMap.containsKey(supplierId)) {
                    QpSupplierVo qpSupplierVo = new QpSupplierVo();
                    BeanUtils.copyProperties(qpSupplierMap.get(supplierId), qpSupplierVo);
                    syntheticalAuditVo.setQpSupplierVo(qpSupplierVo);
                }
            }
            supplierSyntheticalAuditVos.add(syntheticalAuditVo);
        });
        return supplierSyntheticalAuditVos;
    }

    /**
     * 供应商流转map（公共代码）
     *
     * @param ids 根数据
     * @return 结果集
     */
    private Map<Long, QpSupplier> getSupplierMap(Stream<Long> ids) {
        Long[] supplierIds = ids.toArray(Long[]::new);
        List<QpSupplier> suppliers = supplierService.selectQpSupplierListByIds(supplierIds);
        return suppliers.stream().collect(Collectors.toMap(QpSupplier::getId, qs -> qs));
    }

    /**
     * 供应商信息组装
     *
     * @param qpSupplierSyntheticalAudits 审核信息集合
     * @param userIds                     人员ID集合
     * @return 结果集
     */
    private List<QpSupplierSyntheticalAuditVo> getTransportUser(List<QpSupplierSyntheticalAudit> qpSupplierSyntheticalAudits, Long[] userIds) {
        List<QpTransportUser> transportUsers = transportUserService.selectQpTransportUserListByIds(userIds);
        Map<Long, QpTransportUser> transportUserMap = transportUsers.stream().collect(Collectors.toMap(QpTransportUser::getId, qt -> qt));
        Map<Long, QpSupplier> qpSupplierMap = getSupplierMap(transportUsers.stream().map(QpTransportUser::getSupplierId));

        List<QpSupplierSyntheticalAuditVo> supplierSyntheticalAuditVos = new ArrayList<>();
        qpSupplierSyntheticalAudits.forEach(qssa -> {
            QpSupplierSyntheticalAuditVo syntheticalAuditVo = new QpSupplierSyntheticalAuditVo();
            BeanUtils.copyProperties(qssa, syntheticalAuditVo);
            Long syntheticalId = qssa.getSyntheticalId();
            if (!transportUserMap.isEmpty() && transportUserMap.containsKey(syntheticalId)) {
                QpTransportUserVo transportUserVo = new QpTransportUserVo();
                QpTransportUser transportUser = transportUserMap.get(syntheticalId);
                BeanUtils.copyProperties(transportUser, transportUserVo);
                syntheticalAuditVo.setQpTransportUserVo(transportUserVo);
                Long supplierId = transportUser.getSupplierId();
                if (!qpSupplierMap.isEmpty() && qpSupplierMap.containsKey(supplierId)) {
                    QpSupplierVo qpSupplierVo = new QpSupplierVo();
                    BeanUtils.copyProperties(qpSupplierMap.get(supplierId), qpSupplierVo);
                    syntheticalAuditVo.setQpSupplierVo(qpSupplierVo);
                }
            }
            supplierSyntheticalAuditVos.add(syntheticalAuditVo);
        });
        return supplierSyntheticalAuditVos;
    }

    /**
     * 供应商信息组装
     *
     * @param qpSupplierSyntheticalAudits 审核信息集合
     * @param syntheticalIds              供应商ID集合
     * @return 结果集
     */
    private List<QpSupplierSyntheticalAuditVo> getSupplier(List<QpSupplierSyntheticalAudit> qpSupplierSyntheticalAudits, Long[] syntheticalIds) {
        List<QpSupplier> suppliers = supplierService.selectQpSupplierListByIds(syntheticalIds);
        Map<Long, QpSupplier> qpSupplierMap = suppliers.stream().collect(Collectors.toMap(QpSupplier::getId, qs -> qs));

        List<QpSupplierSyntheticalAuditVo> supplierSyntheticalAuditVos = new ArrayList<>();
        qpSupplierSyntheticalAudits.forEach(qssa -> {
            QpSupplierSyntheticalAuditVo syntheticalAuditVo = new QpSupplierSyntheticalAuditVo();
            BeanUtils.copyProperties(qssa, syntheticalAuditVo);
            Long syntheticalId = qssa.getSyntheticalId();
            if (!qpSupplierMap.isEmpty() && qpSupplierMap.containsKey(syntheticalId)) {
                QpSupplierVo qpSupplierVo = new QpSupplierVo();
                BeanUtils.copyProperties(qpSupplierMap.get(syntheticalId), qpSupplierVo);
                syntheticalAuditVo.setQpSupplierVo(qpSupplierVo);
            }
            supplierSyntheticalAuditVos.add(syntheticalAuditVo);
        });
        return supplierSyntheticalAuditVos;
    }

    /**
     * 新增供应商综合审核
     *
     * @param qpSupplierSyntheticalAudit 供应商综合审核
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertQpSupplierSyntheticalAudit(QpSupplierSyntheticalAudit qpSupplierSyntheticalAudit) {
        return qpSupplierSyntheticalAuditMapper.insertQpSupplierSyntheticalAudit(qpSupplierSyntheticalAudit);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSyntheticalAudit(Long syntheticalId, Integer auditType, String createBy) {
        if (syntheticalId == null)
            throw new ServiceException("供应商ID为空");
        if (auditType == null) {
            throw new ServiceException("审核类型为空");
        }
        QpSupplierSyntheticalAudit syntheticalAudit = new QpSupplierSyntheticalAudit()
                .setSyntheticalId(syntheticalId)
                .setAuditType(auditType)
                .setStatus(0);
        syntheticalAudit.setCreateBy(createBy);
        syntheticalAudit.setCreateTime(new Date());
        if (qpSupplierSyntheticalAuditMapper.insertQpSupplierSyntheticalAudit(syntheticalAudit) <= 0) {
            throw new ServiceException("审核登记错误");
        }
    }

    /**
     * 修改供应商综合审核
     *
     * @param qpSupplierSyntheticalAudit 供应商综合审核
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateQpSupplierSyntheticalAudit(QpSupplierSyntheticalAudit qpSupplierSyntheticalAudit) {
        Integer auditType = qpSupplierSyntheticalAudit.getAuditType();
        if (auditType == null) {
            throw new ServiceException("供应商综合审核类型数据异常");
        }
        Long syntheticalId = qpSupplierSyntheticalAudit.getSyntheticalId();
        if (syntheticalId == null) {
            throw new ServiceException("供应商综合审核数据综合id异常");
        }

        QpSupplierSyntheticalAudit supplierSyntheticalAudit = qpSupplierSyntheticalAuditMapper.getWaitCheck(qpSupplierSyntheticalAudit);
        if (supplierSyntheticalAudit == null) {
            throw new ServiceException("供应商综合审核数据异常");
        }
        qpSupplierSyntheticalAudit.setId(supplierSyntheticalAudit.getId());
        int status = qpSupplierSyntheticalAudit.getStatus();
        switch (auditType) {
            case AuditType.SUPPLIER_USER_AUDIT:
                QpTransportUser transportUser = new QpTransportUser()
                        .setIsAudit(status)
                        .setId(syntheticalId)
                        .setAuditTime(DateUtils.getNowDate())
                        .setAuditUser(SecurityUtils.getUsername());
                if (transportUserService.updateQpTransportUser(transportUser) <= 0) {
                    throw new ServiceException("人员审核状态修改失败");
                }
                break;
            case AuditType.SUPPLIER_CAR_AUDIT:
                QpTransportCar qpTransportCar = new QpTransportCar()
                        .setIsAudit(status)
                        .setAuditUser(SecurityUtils.getUsername())
                        .setAuditTime(DateUtils.getNowDate())
                        .setId(syntheticalId);
                if (carService.updateQpTransportCar(qpTransportCar) <= 0) {
                    throw new ServiceException("运输车辆审核状态修改失败");
                }
                break;
            case AuditType.SUPPLIER_AUDIT:
            default:
                QpSupplier qpSupplier = new QpSupplier()
                        .setState(status)
                        .setId(syntheticalId)
                        .setAuditTime(Calendar.getInstance().getTime());
                if (supplierService.updateQpSupplierStatus(qpSupplier) <= 0) {
                    throw new ServiceException("供应商核状态修改失败");
                }
        }
        qpSupplierSyntheticalAudit.setAuditUser(SecurityUtils.getUsername());
        qpSupplierSyntheticalAudit.setAuditTime(DateUtils.getNowDate());
        qpSupplierSyntheticalAudit.setUpdateBy(SecurityUtils.getUsername());
        qpSupplierSyntheticalAudit.setUpdateTime(DateUtils.getNowDate());
        return qpSupplierSyntheticalAuditMapper.updateQpSupplierSyntheticalAudit(qpSupplierSyntheticalAudit);
    }

    /**
     * 批量删除供应商综合审核
     *
     * @param ids 需要删除的供应商综合审核主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteQpSupplierSyntheticalAuditByIds(Long[] ids) {
        return qpSupplierSyntheticalAuditMapper.deleteQpSupplierSyntheticalAuditByIds(ids);
    }

    /**
     * 删除供应商综合审核信息
     *
     * @param id 供应商综合审核主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteQpSupplierSyntheticalAuditById(Long id) {
        return qpSupplierSyntheticalAuditMapper.deleteQpSupplierSyntheticalAuditById(id);
    }

    @Override
    public QpSupplierSyntheticalAudit getQpSupplierSyntheticalAuditBySyntheticalId(Long syntheticalId, int auditType) {
        return qpSupplierSyntheticalAuditMapper.getQpSupplierSyntheticalAuditBySyntheticalId(syntheticalId, auditType);
    }

    @Override
    public List<QpSupplierSyntheticalAuditVo> getListVo(List<QpSupplierSyntheticalAudit> list, Integer auditType) {
        Long[] syntheticalIds = list.stream().map(QpSupplierSyntheticalAudit::getSyntheticalId).toArray(Long[]::new);
        List<QpSupplierSyntheticalAuditVo> qpSupplierSyntheticalAuditVos;
        switch (auditType) {
            case AuditType.SUPPLIER_USER_AUDIT:
                qpSupplierSyntheticalAuditVos = getTransportUser(list, syntheticalIds);
                break;
            case AuditType.SUPPLIER_CAR_AUDIT:
                qpSupplierSyntheticalAuditVos = getTransportCar(list, syntheticalIds);
                break;
            case AuditType.SUPPLIER_AUDIT:
            default:
                qpSupplierSyntheticalAuditVos = getSupplier(list, syntheticalIds);
        }
        return qpSupplierSyntheticalAuditVos;
    }

    @Override
    public List<QpSupplierSyntheticalAuditVo> getAuditInfo(Long syntheticId) {
        List<QpSupplierSyntheticalAudit> audits = qpSupplierSyntheticalAuditMapper.selectQpSupplierSyntheticalAuditList(new QpSupplierSyntheticalAudit().setSyntheticalId(syntheticId).setAuditType(AuditType.SUPPLIER_AUDIT));

        List<QpTransportUser> transportUsers = transportUserService.selectQpTransportUserList(new QpTransportUser().setSupplierId(syntheticId));
        Map<Long, String> userMap = transportUsers.stream().collect(Collectors.toMap(QpTransportUser::getId, QpTransportUser::getUserName));
        List<QpTransportCar> transportCars = carService.selectQpTransportCarList(new QpTransportCar().setSupplierId(syntheticId));
        Map<Long, String> carMap = transportCars.stream().collect(Collectors.toMap(QpTransportCar::getId, QpTransportCar::getCarCode));
        if (!transportCars.isEmpty()) {
            audits.addAll(qpSupplierSyntheticalAuditMapper.getBySyntheticIds(transportCars.stream().map(QpTransportCar::getId).collect(Collectors.toList()), AuditType.SUPPLIER_CAR_AUDIT));
        }
        if (!transportUsers.isEmpty()) {
            audits.addAll(qpSupplierSyntheticalAuditMapper.getBySyntheticIds(transportUsers.stream().map(QpTransportUser::getId).collect(Collectors.toList()), AuditType.SUPPLIER_USER_AUDIT));
        }
        audits = audits.stream().filter(q -> q.getStatus() != null).collect(Collectors.toList());
        List<QpSupplierSyntheticalAuditVo> auditVos = TransferUtils.transferList(audits, QpSupplierSyntheticalAuditVo.class);
        auditVos.forEach(a -> {
            Integer auditType = a.getAuditType();
            Long syntheticalId = a.getSyntheticalId();
            switch (auditType) {
                case AuditType.SUPPLIER_AUDIT:
                    a.setAuditTitle("供应商信息");
                    break;
                case AuditType.SUPPLIER_USER_AUDIT:
                    if (userMap.containsKey(syntheticalId)) {
                        a.setAuditTitle(userMap.get(syntheticalId) + "(人员)");
                    }
                    break;
                case AuditType.SUPPLIER_CAR_AUDIT:
                    if (carMap.containsKey(syntheticalId)) {
                        a.setAuditTitle(carMap.get(syntheticalId) + "(车辆)");
                    }
                    break;
                default:
            }
        });
        return auditVos.stream().sorted(Comparator.comparing(QpSupplierSyntheticalAuditVo::getAuditTime,Comparator.nullsLast(Date::compareTo)).thenComparing(QpSupplierSyntheticalAuditVo::getId).reversed()).collect(Collectors.toList());
    }
}
