package cn.iocoder.yudao.module.supplier.service.product;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.supplier.controller.admin.product.vo.*;
import cn.iocoder.yudao.module.supplier.dal.dataobject.product.*;
import cn.iocoder.yudao.module.supplier.dal.mysql.product.*;
import cn.iocoder.yudao.module.supplier.enums.ErrorCodeConstant;
import cn.iocoder.yudao.module.supplier.enums.common.SupplierAuditStatusEnum;
import cn.iocoder.yudao.module.supplier.enums.common.SupplierStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.supplier.enums.ErrorCodeConstant.SUPPLIER_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS;
import static cn.iocoder.yudao.module.supplier.util.SupplierAuditStatusUtils.convertBpmResultToAuditStatus;

/**
 * 供应商主数据 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class SupplierServiceImpl implements SupplierService {

    public static final String PROCESS_KEY = "supplier";

    @Resource
    private SupplierMapper supplierMapper;
    @Resource
    private CertificateMapper certificateMapper;
    @Resource
    private ContactMapper supplierContactMapper;
    @Resource
    private CoreProductMapper coreProductMapper;
    @Resource
    private ConnectRecordMapper connectRecordMapper;

    @Resource
    private BpmProcessInstanceApi processInstanceApi;

    @Override
    public Long create(SupplierSaveReqVO createReqVO) {
        List<SupplierDO> name = supplierMapper.selectList("name", createReqVO.getName());
        if (!CollectionUtils.isEmpty(name)){
            throw new ServiceException(ErrorCodeConstant.NAME_EXISTED.getCode(),"供应商名称重复");
        }
        // 插入
        SupplierDO supplierDO = BeanUtils.toBean(createReqVO, SupplierDO.class);
        supplierDO.setCode("S" + DateUtil.format(new Date(), "yyyyMMddHHmmss") +UUID.randomUUID().toString().substring(0, 3));
        //设置草稿状态
        supplierDO.setStatus(1);
        Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
        supplierDO.setDeptId(loginUserDeptId);
        supplierMapper.insert(supplierDO);
        // 返回
        return supplierDO.getId();
    }

    @Override
    public void update(SupplierSaveReqVO updateReqVO) {
        // 校验存在
        validateExists(updateReqVO.getId());
        // 更新
        SupplierDO updateObj = BeanUtils.toBean(updateReqVO, SupplierDO.class);
        supplierMapper.updateById(updateObj);
    }

    @Override
    public void delete(Long id) {
        // 校验存在
        validateExists(id);
        // 删除
        supplierMapper.deleteById(id);
    }

    private SupplierDO validateExists(Long id) {
        SupplierDO supplier = supplierMapper.selectById(id);
        if (ObjUtil.isNull(supplier)) {
            throw exception(ErrorCodeConstant.NOT_EXISTS);
        }
        return supplier;
    }

    @Override
    @DataPermission(enable = false)
    public SupplierDO get(Long id) {
        return supplierMapper.selectById(id);
    }

    @Override
    public PageResult<SupplierDO> getPage(SupplierPageReqVO pageReqVO) {
        return supplierMapper.selectPage(pageReqVO);
    }

    @Override
    public List<SupplierDO> getAll() {
        return supplierMapper.selectList();
    }

    @Override
    public void changeStatus(Long id, Integer status) {
        SupplierDO supplierDO = supplierMapper.selectById(id);
        assert Objects.nonNull(supplierDO);
        supplierDO.setStatus(status);
        supplierMapper.insertOrUpdate(supplierDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long submitForApproval(Long id) {
        // 校验供应商主数据是否存在
        validateExists(id);
        // 发起BPM流程
        // 获取当前登录人信息
        String processInstanceId = processInstanceApi.createProcessInstance(SecurityFrameworkUtils.getLoginUserId(),
                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY).setBusinessKey(String.valueOf(id)));
        // 将流程实例id 更新到 供应商主数据表
        supplierMapper.updateById(new SupplierDO().setId(id).setProcessInstanceId(processInstanceId)
                .setAuditStatus(SupplierAuditStatusEnum.PROCESS.getStatus()));
        return 0l;
    }

    @Override
    public void updateSupplierAuditStatus(Long id, Integer bpmResult) {
        // 1.1 校验存在
        SupplierDO supplier = validateExists(id);
        // 1.2 只有审批中，可以更新审批结果
        if (ObjUtil.notEqual(supplier.getAuditStatus(), SupplierAuditStatusEnum.PROCESS.getStatus())) {
            log.error("[updateSupplierAuditStatus][supplier({}) 不处于审批中，无法更新审批结果({})]",
                    supplier.getId(), bpmResult);
            throw exception(SUPPLIER_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
        }

        // 2. 更新供应商审批状态
        Integer auditStatus = convertBpmResultToAuditStatus(bpmResult);
        supplierMapper.updateById(new SupplierDO().setId(id).setAuditStatus(auditStatus).setStatus(SupplierStatusEnum.ACTIVE.getStatus()));
    }

    @Override
    public SupplierRespVO allSupplierInfo(Long id) {
        // 查询供应商基本信息
        SupplierDO supplierDO = supplierMapper.selectById(id);
        SupplierRespVO supplierRespVO = BeanUtils.toBean(supplierDO, SupplierRespVO.class);
        // 查询供应商证件信息
        List<CertificateDO> certificateDOS = certificateMapper.selectListBySupplierId(id);
        if (CollUtil.isNotEmpty(certificateDOS)) {
            List<CertificateRespVO> certificateRespVOS = BeanUtils.toBean(certificateDOS, CertificateRespVO.class);
            supplierRespVO.setCertificates(certificateRespVOS);
        }
        // 查询联系人信息
        List<ContactDO> contactsDOS = supplierContactMapper.selectListBySupplierId(id);
        if (CollUtil.isNotEmpty(contactsDOS)) {
            List<ContactRespVO> contactRespVOS = BeanUtils.toBean(contactsDOS, ContactRespVO.class);
            supplierRespVO.setContacts(contactRespVOS);
        }
        // 查询核心产品信息
        List<CoreProductDO> coreProductDOS = coreProductMapper.selectListBySupplierId(id);
        if (CollUtil.isNotEmpty(coreProductDOS)) {
            List<CoreProductRespVO> coreProductRespVOS = BeanUtils.toBean(coreProductDOS, CoreProductRespVO.class);
            supplierRespVO.setCoreProducts(coreProductRespVOS);
        }
        // 查询联系记录信息
        List<ConnectRecordDO> connectRecordDOS = connectRecordMapper.selectListBySupplierId(id);
        if (CollUtil.isNotEmpty(connectRecordDOS)) {
            List<ConnectRecordRespVO> connectRecordRespVOS = BeanUtils.toBean(connectRecordDOS, ConnectRecordRespVO.class);
            supplierRespVO.setConnectRecords(connectRecordRespVOS);
        }
        return supplierRespVO;
    }

    @Override
    public SupplierDO getByBpmProcessId(String bpmProcessInstanceId) {
        return supplierMapper.selectByBpmProcessInstanceId(bpmProcessInstanceId);
    }

}
