package com.zd.airbottle.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.zd.airbottle.constant.AuditType;
import com.zd.airbottle.domain.*;
import com.zd.airbottle.domain.dto.QpSupplierCredentialsDto;
import com.zd.airbottle.domain.dto.QpSupplierDto;
import com.zd.airbottle.domain.vo.QpSupplierCredentialsVo;
import com.zd.airbottle.domain.vo.QpSupplierSyntheticalAuditVo;
import com.zd.airbottle.domain.vo.QpSupplierVo;
import com.zd.airbottle.mapper.QpSupplierMapper;
import com.zd.airbottle.service.*;
import com.zd.common.core.constant.Constants;
import com.zd.common.core.constant.HttpStatus;
import com.zd.common.core.constant.SecurityConstants;
import com.zd.common.core.domain.R;
import com.zd.common.core.domain.per.PerPrefix;
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 com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.utils.SaveUtil;
import com.zd.system.api.RemoteUserService;
import com.zd.system.api.domain.SysUser;
import com.zd.system.api.dto.SysUserDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
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;

/**
 * 供应商Service业务层处理
 */
@Service
public class QpSupplierServiceImpl implements IQpSupplierService {
    @Autowired
    private QpSupplierMapper qpSupplierMapper;
    @Autowired
    private IQpSupplierCredentialsService qpSupplierCredentialsService;
    @Autowired
    private RemoteUserService userService;
    @Autowired
    private IQpSupplierSyntheticalAuditService auditService;
    @Autowired
    private IQpTransportCarService carService;
    @Autowired
    private IQpTransportUserService transportUserService;
    @Autowired
    private IQpAirBottleService bottleService;

    private static final String USER_TYPE = "33";

    /**
     * 查询供应商
     *
     * @param id 供应商主键
     * @return 供应商
     */
    @Override
    public QpSupplierVo selectQpSupplierVoById(Long id) {
        QpSupplier qpSupplier = qpSupplierMapper.selectQpSupplierById(id);
        QpSupplierVo qpSupplierVo = new QpSupplierVo();
        BeanUtils.copyProperties(qpSupplier, qpSupplierVo);
        QpSupplierCredentials supplierCredentials = new QpSupplierCredentials();
        supplierCredentials.setSupplierId(qpSupplier.getId());
        getCredentialsInfo(qpSupplierVo, supplierCredentials, qpSupplierCredentialsService);
        return qpSupplierVo;
    }

    @Override
    public QpSupplierVo getDetail() {
        QpSupplier supplier = qpSupplierMapper.selectQpSupplierByAccountId(SecurityUtils.getUserId());
        if (supplier==null){
            throw new ServiceException("供应商被停用或不存在");
        }
        Integer state = supplier.getState();
        QpSupplierVo qpSupplierVo = new QpSupplierVo();
        BeanUtils.copyProperties(supplier, qpSupplierVo);

        Long id = supplier.getId();
        if (state== com.zd.airbottle.constant.Constants.SUPPLIER_NO_AUDIT){
            QpSupplierSyntheticalAudit audit = auditService.getQpSupplierSyntheticalAuditBySyntheticalId(id, AuditType.SUPPLIER_AUDIT);
            QpSupplierSyntheticalAuditVo auditVo=new QpSupplierSyntheticalAuditVo();
            BeanUtils.copyProperties(audit,auditVo);
            qpSupplierVo.setAudit(auditVo);
        }
        QpSupplierCredentials supplierCredentials = new QpSupplierCredentials();
        supplierCredentials.setSupplierId(id);
        getCredentialsInfo(qpSupplierVo, supplierCredentials, qpSupplierCredentialsService);

        Integer status = supplier.getStatus();
        if (status==com.zd.airbottle.constant.Constants.SUPPLIER_STATUS_STOP){
            throw new ServiceException("账号已被停用");
        }

        if (state== com.zd.airbottle.constant.Constants.SUPPLIER_ALREADY_AUDIT && status== com.zd.airbottle.constant.Constants.SUPPLIER_STATUS_START){
            List<QpTransportCar> cars = carService.selectQpTransportCarList(new QpTransportCar().setSupplierId(id));
            List<QpTransportUser> transportUsers = transportUserService.selectQpTransportUserList(new QpTransportUser().setSupplierId(id));
            List<QpAirBottleConfig> configs = bottleService.getBySupplierId(id);
            qpSupplierVo.setBottleSum(configs.size());
            qpSupplierVo.setCarSum(cars.size());
            qpSupplierVo.setPeopleSum(transportUsers.size());
        }
        return qpSupplierVo;
    }

    static void getCredentialsInfo(QpSupplierVo qpSupplierVo, QpSupplierCredentials supplierCredentials, IQpSupplierCredentialsService supplierCredentialsService) {
        List<QpSupplierCredentials> qpSupplierCredentials = supplierCredentialsService.selectQpSupplierCredentialsList(supplierCredentials);
        qpSupplierVo.setQpSupplierCredentialsVos(TransferUtils.transferList(qpSupplierCredentials,QpSupplierCredentialsVo.class));
    }

    @Override
    public QpSupplier selectQpSupplierById(Long id) {
        QpSupplier qpSupplier = qpSupplierMapper.selectQpSupplierById(id);
        if (qpSupplier == null) {
            throw new ServiceException("无此供应商信息");
        }
        return qpSupplier;
    }

    @Override
    //@DataScope(deptAlias = "d", userAlias = "u", permi = PerPrefix.MODULE_AIRBOTTLE+PerPrefix.BUSINESS_SUPPLIER)
    public List<QpSupplier> getList(QpSupplier qpSupplier) {
        return qpSupplierMapper.selectQpSupplierList(qpSupplier);
    }

    @Override
    public List<QpSupplierVo> getVoList(List<QpSupplier> list) {
        List<Long> supplierIds = list.stream().map(QpSupplier::getId).collect(Collectors.toList());
        Map<Long,Integer> userSumMap=transportUserService.getBySupplierIds(supplierIds);
        Map<Long,Integer> carSumMap=carService.getBySupplierIds(supplierIds);
        Map<Long,Integer> bottleSumMap=bottleService.getBySupplierIds(supplierIds);

        List<QpSupplierVo> supplierVos=new ArrayList<>();
        list.forEach(s->{
            QpSupplierVo supplierVo=new QpSupplierVo();
            BeanUtils.copyProperties(s,supplierVo);
            Long id = s.getId();
            if (userSumMap.containsKey(id)){
                supplierVo.setPeopleSum(userSumMap.get(id));
            }
            if (carSumMap.containsKey(id)){
                supplierVo.setCarSum(carSumMap.get(id));
            }
            if (bottleSumMap.containsKey(id)){
                supplierVo.setBottleSum(bottleSumMap.get(id));
            }
            supplierVos.add(supplierVo);
        });
        return supplierVos;
    }

    @Override
    public QpSupplier selectQpSupplierByAccountId(Long accountId) {
        if (accountId == null) {
            throw new ServiceException("供应商账号ID为空");
        }
        return qpSupplierMapper.selectQpSupplierByAccountId(accountId);
    }

    /**
     * 新增供应商
     *
     * @param qpSupplierDto 供应商信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertQpSupplier(QpSupplierDto qpSupplierDto) {
        try {
            checkCompanyName(qpSupplierDto);
            QpSupplier qpSupplier = getQpSupplier(qpSupplierDto);
            qpSupplier.setState(com.zd.airbottle.constant.Constants.SUPPLIER_ALREADY_AUDIT);
            qpSupplier.setStatus(com.zd.airbottle.constant.Constants.SUPPLIER_STATUS_START);//默认状态为启用
            SaveUtil.setCommonAttr(qpSupplier);
            qpSupplier.setAuditTime(qpSupplier.getCreateTime());
            if (qpSupplierMapper.insertQpSupplier(qpSupplier) > 0) {
                //保存供应商资质信息
                List<QpSupplierCredentials> qpSupplierCredentials = checkTime(qpSupplierDto, qpSupplier);
                return qpSupplierCredentialsService.batchInsertQpSupplierCredentials(qpSupplierCredentials);
            } else {
                throw new ServiceException("供应商信息添加失败");
            }
        } catch (BeansException e) {
            throw new ServiceException(e.getMessage());
        }
    }

    private void checkCompanyName(QpSupplierDto qpSupplierDto) {
        if (Boolean.TRUE.equals(checkName(qpSupplierDto.getCompanyName(),null))){
            throw new ServiceException("供应商已存在");
        }
    }

    /**
     * 保存供应商基本信息
     *
     * @param qpSupplierDto 元数据
     * @return 返回值
     */
    private QpSupplier getQpSupplier(QpSupplierDto qpSupplierDto) {
        //保存账号信息
        SysUserDto sysUserDto = getUserDto(qpSupplierDto);
        //保存供应商基本信息
        R<SysUser> userResult = userService.getUserInfoByUserName(sysUserDto.getUserName(), SecurityConstants.INNER);
        QpSupplier qpSupplier = new QpSupplier();

        BeanUtils.copyProperties(qpSupplierDto, qpSupplier);

        qpSupplier.setAccountId(userResult.getData().getUserId());
        return qpSupplier;
    }

    /**
     * 保存账号信息
     *
     * @param qpSupplierDto 元数据
     * @return 返回值
     */
    private SysUserDto getUserDto(QpSupplierDto qpSupplierDto) {
        SysUser sysUser = new SysUser();
        SysUserDto sysUserDto = qpSupplierDto.getSysUserDto();

        BeanUtils.copyProperties(sysUserDto, sysUser);
        sysUser.setNickName(qpSupplierDto.getCompanyName());
        sysUser.setAddr(qpSupplierDto.getBusinessAddress());
        sysUser.setPhonenumber(qpSupplierDto.getPhone());
        sysUser.setPassword(SecurityUtils.encryptPassword(sysUserDto.getPassword()));
        sysUser.setUserType(USER_TYPE);
        sysUser.setStatus(Constants.NORMAL);
        sysUser.setCreateTime(DateUtils.getNowDate());
        sysUser.setCreateBy(SecurityUtils.getUsername());
        R<Boolean> userInfo = userService.registerUserInfo(sysUser, SecurityConstants.INNER);
        if (userInfo.getCode() != HttpStatus.SUCCESS) {
            throw new ServiceException(userInfo.getMsg());
        }
        return sysUserDto;
    }

    /**
     * 修改供应商
     *
     * @param qpSupplierDto 供应商信息
     * @param isAudit 是否需要审核
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateQpSupplier(QpSupplierDto qpSupplierDto, boolean isAudit) {
        QpSupplier qpSupplier = new QpSupplier();
        BeanUtils.copyProperties(qpSupplierDto, qpSupplier);
        qpSupplier.setUpdateTime(DateUtils.getNowDate());
        qpSupplier.setUpdateBy(SecurityUtils.getUsername());

        //添加待审核
        if (isAudit){
            qpSupplier.setState(com.zd.airbottle.constant.Constants.SUPPLIER_NOT_AUDIT);
            auditService.addSyntheticalAudit(qpSupplier.getId(), AuditType.SUPPLIER_AUDIT, qpSupplier.getCompanyName());
        }
        qpSupplierMapper.updateQpSupplier(qpSupplier);

        List<QpSupplierCredentials> credentials = qpSupplierCredentialsService.selectQpSupplierCredentialsList(new QpSupplierCredentials().setSupplierId(qpSupplier.getId()));
        List<Long> cIds = Collections.synchronizedList(credentials.stream().map(QpSupplierCredentials::getId).collect(Collectors.toList()));
        List<QpSupplierCredentialsDto> supplierCredentialsDtos = qpSupplierDto.getQpSupplierCredentialsDtos();
        if (CollUtil.isNotEmpty(supplierCredentialsDtos)) {
            supplierCredentialsDtos.forEach(qsc -> {
                QpSupplierCredentials supplierCredentials = new QpSupplierCredentials();
                BeanUtils.copyProperties(qsc, supplierCredentials);
                if (supplierCredentials.getId() == null) {
                    supplierCredentials.setSupplierId(qpSupplier.getId());
                    if (qpSupplierCredentialsService.insertQpSupplierCredentials(supplierCredentials) <= 0)
                        throw new ServiceException("添加供应商证件失败");
                } else {
                    cIds.remove(qsc.getId());
                    if (qpSupplierCredentialsService.updateQpSupplierCredentials(supplierCredentials) <= 0)
                        throw new ServiceException("修改供应商证件失败");
                }
            });
        }
        if (CollUtil.isNotEmpty(cIds)){
            qpSupplierCredentialsService.deleteQpSupplierCredentialsByIds(cIds.toArray(cIds.toArray(new Long[0])));
        }
        return qpSupplierMapper.updateQpSupplier(qpSupplier);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateQpSupplierStatus(QpSupplier qpSupplier) {
        return qpSupplierMapper.updateQpSupplier(qpSupplier);
    }

    /**
     * 批量删除供应商
     *
     * @param ids 需要删除的供应商主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteQpSupplierByIds(Long[] ids) {
        if (ids.length > 0) {
            List<QpSupplier> qpSuppliers = qpSupplierMapper.selectQpSupplierListByIds(ids);
            if (CollUtil.isNotEmpty(qpSuppliers)) {
                Long[] accountIds = qpSuppliers.stream().map(QpSupplier::getAccountId).toArray(Long[]::new);
                userService.remove(accountIds);
            }
            List<QpSupplierCredentials> qpSupplierCredentials = qpSupplierCredentialsService.selectQpSupplierCredentialsListBySupplierIds(ids);
            if (CollUtil.isNotEmpty(qpSupplierCredentials)) {
                Long[] credentialsIds = qpSupplierCredentials.stream().map(QpSupplierCredentials::getId).toArray(Long[]::new);
                qpSupplierCredentialsService.deleteQpSupplierCredentialsByIds(credentialsIds);
            }
        }
        return qpSupplierMapper.deleteQpSupplierByIds(ids);
    }

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

    @Override
    public Boolean checkName(String name, Integer type) {
        return qpSupplierMapper.checkName(name, type);
    }

    @Override
    public List<QpSupplier> selectQpSupplierListByIds(Long[] ids) {
        if (ids.length==0)
            return new ArrayList<>();
        return qpSupplierMapper.selectQpSupplierListByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(QpSupplierDto qpSupplierDto) {
        try {
            checkCompanyName(qpSupplierDto);
            //保存账号信息
            QpSupplier qpSupplier = getQpSupplier(qpSupplierDto);
            qpSupplier.setCreateTime(DateUtils.getNowDate());
            qpSupplier.setState(com.zd.airbottle.constant.Constants.SUPPLIER_NOT_AUDIT);
            qpSupplier.setStatus(com.zd.airbottle.constant.Constants.SUPPLIER_STATUS_START);//默认状态为启用

            //设置创建人
            qpSupplier.setCreateBy(qpSupplier.getCompanyName());
            if (qpSupplierMapper.insertQpSupplier(qpSupplier) > 0) {
                //添加待审核记录
                auditService.addSyntheticalAudit(qpSupplier.getId(), AuditType.SUPPLIER_AUDIT,qpSupplier.getCompanyName());
                //保存供应商资质信息
                List<QpSupplierCredentials> qpSupplierCredentials = checkTime(qpSupplierDto, qpSupplier);
                return qpSupplierCredentialsService.batchInsertQpSupplierCredentials(qpSupplierCredentials) > 0;
            } else {
                throw new ServiceException("供应商信息添加失败");
            }
        } catch (BeansException e) {
            throw new ServiceException(e.getMessage());
        }
    }

    private List<QpSupplierCredentials> checkTime(QpSupplierDto qpSupplierDto, QpSupplier qpSupplier) {
        List<QpSupplierCredentials> qpSupplierCredentials = getQpSupplierCredentials(qpSupplierDto, qpSupplier);
        for (QpSupplierCredentials supplierCredentials :qpSupplierCredentials) {
            Date endTime = supplierCredentials.getEndTime();
            Date startTime = supplierCredentials.getStartTime();
            if (startTime!=null && endTime!=null && startTime.getTime()>endTime.getTime()){
                throw new ServiceException("开始时间不能大于使用时间");
            }
        }
        return qpSupplierCredentials;
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u", permi = PerPrefix.MODULE_AIRBOTTLE + PerPrefix.BUSINESS_SUPPLIER)
    public List<QpSupplier> checkList(QpSupplier qpSupplier) {
        return qpSupplierMapper.selectQpSupplierList(qpSupplier);
    }

    @Override
    public List<QpSupplier> getByIds(List<Long> ids) {
        if (ids.isEmpty()){
            return new ArrayList<>();
        }
        return qpSupplierMapper.getByIds(ids);
    }

    /**
     * 构造新资质证件的集合
     *
     * @param qpSupplierDto 元数据
     * @param qpSupplier    供应商基本数据
     * @return 返回值
     */
    private List<QpSupplierCredentials> getQpSupplierCredentials(QpSupplierDto qpSupplierDto, QpSupplier qpSupplier) {
        List<QpSupplierCredentials> qpSupplierCredentials = new ArrayList<>();
        qpSupplierDto.getQpSupplierCredentialsDtos().forEach(qd -> {
            QpSupplierCredentials supplierCredentials = new QpSupplierCredentials();
            BeanUtils.copyProperties(qd, supplierCredentials);
            supplierCredentials.setCreateTime(new Date());
            supplierCredentials.setCreateBy(supplierCredentials.getCreateBy());
            supplierCredentials.setSupplierId(qpSupplier.getId());
            qpSupplierCredentials.add(supplierCredentials);
        });
        return qpSupplierCredentials;
    }
}
