package cn.iocoder.yudao.module.basic.service.vendorinfo;

import cn.iocoder.yudao.framework.common.enums.CodeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.basic.api.redis.RedisBasicInfoUtilApi;
import cn.iocoder.yudao.module.basic.controller.admin.vendorinfo.vo.VendorInfoCreateReqVO;
import cn.iocoder.yudao.module.basic.controller.admin.vendorinfo.vo.VendorInfoPageReqVO;
import cn.iocoder.yudao.module.basic.controller.admin.vendorinfo.vo.VendorInfoUpdateReqVO;
import cn.iocoder.yudao.module.basic.convert.vendorinfo.VendorInfoConvert;
import cn.iocoder.yudao.module.basic.dal.dataobject.vendorinfo.VendorInfoDO;
import cn.iocoder.yudao.module.basic.dal.mysql.vendorinfo.VendorInfoMapper;
import cn.iocoder.yudao.module.basic.service.businessinfo.BusinessInfoServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.basic.enums.ErrorCodeConstants.*;

/**
 * 供应商 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class VendorInfoServiceImpl implements VendorInfoService {

    @Resource
    private VendorInfoMapper vendorInfoMapper;
    @Resource
    private RedisBasicInfoUtilApi redisUtil;
    @Resource
    private BusinessInfoServiceImpl businessInfoService;

    /**
     * 创建供应商实现
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    @Override
    public Long createVendorInfo(VendorInfoCreateReqVO createReqVO) {
        //校验所属商户是否存在
        businessInfoService.validateBusinessInfoExists(createReqVO.getBelongBusinessId());

        //如果是个人类型，将姓名当做供应商名称
        if (createReqVO.getVendorType() == 1) {
            createReqVO.setVendorName(createReqVO.getRealName());
        }
        // 校验是否存在相同名称供应商
        validateVendorNameExists(createReqVO.getVendorName(), (long) 0);
        // 插入
        VendorInfoDO vendorInfo = VendorInfoConvert.INSTANCE.convert(createReqVO);
        vendorInfo.setVendorId(CodeEnum.VENDOR_INFO_CODE.getCode());
        try {
            vendorInfoMapper.insert(vendorInfo);
        }catch (Exception e){
            e.printStackTrace();
            throw exception(VENDOR_INFO_FAIL_CREATE);
        }
        redisUtil.updateVendorInfoRedis(vendorInfo.getId(), VendorInfoConvert.INSTANCE.convertToDTO(vendorInfo));
        // 返回
        return vendorInfo.getId();
    }

    /**
     * 更新供应商实现
     *
     * @param updateReqVO 更新信息
     */
    @Override
    public void updateVendorInfo(VendorInfoUpdateReqVO updateReqVO) {
        // 校验存在
        validateVendorInfoExists(updateReqVO.getId());

        //校验所属商户是否存在
        businessInfoService.validateBusinessInfoExists(updateReqVO.getBelongBusinessId());

        //如果是个人类型，将姓名当做供应商名称
        if (updateReqVO.getVendorType() == 1) {
            updateReqVO.setVendorName(updateReqVO.getRealName());
        }

        //校验是否存在相同名称供应商
        validateVendorNameExists(updateReqVO.getVendorName(), updateReqVO.getId());

        VendorInfoDO updateObj = VendorInfoConvert.INSTANCE.convert(updateReqVO);
        // 更新
        try{
            vendorInfoMapper.updateById(updateObj);
        }catch (Exception e){
            e.printStackTrace();
            throw exception(VENDOR_INFO_FAIL_UPDATE);
        }

        redisUtil.updateVendorInfoRedis(updateObj.getId(),VendorInfoConvert.INSTANCE.convertToDTO(updateObj));
    }

    /**
     * 删除供应商实现
     *
     * @param id 编号
     */
    @Override
    public void deleteVendorInfo(Long id) {
        // 校验存在
        validateVendorInfoExists(id);
        // 删除
        try{
            vendorInfoMapper.deleteById(id);
        }catch (Exception e){
            e.printStackTrace();
            throw exception(VENDOR_INFO_FAIL_DEL);
        }
        redisUtil.delVendorInfoRedis(id);
    }

    private void validateVendorInfoExists(Long id) {
        if (vendorInfoMapper.selectById(id) == null) {
            throw exception(VENDOR_INFO_NOT_EXISTS);
        }
    }

    private void validateVendorNameExists(String vendorName, Long id) {
        QueryWrapper<VendorInfoDO> wrapper = new QueryWrapper<>();
        wrapper.eq("vendor_name", vendorName);
        wrapper.ne("id", id);
        if (!vendorInfoMapper.selectList(wrapper).isEmpty()) {
            throw exception(VENDOR_INFO_IS_EXISTS_VENDOR_NAME);
        }
    }

    /**
     * 获得供应商实现
     *
     * @param id 编号
     * @return 供应商
     */
    @Override
    public VendorInfoDO getVendorInfo(Long id) {
        return vendorInfoMapper.selectById(id);
    }

    /**
     * 获得供应商分页实现
     *
     * @param pageReqVO 分页查询
     * @return 供应商分页
     */
    @Override
    public PageResult<VendorInfoDO> getVendorInfoPage(VendorInfoPageReqVO pageReqVO) {
        PageResult<VendorInfoDO> vendorInfoDOPageResult = new PageResult<>();

        if (pageReqVO.getBelongBusinessName() != null && !Objects.equals(pageReqVO.getBelongBusinessName(), "")) {
            Page<VendorInfoDO> page = new Page<>(pageReqVO.getPageNo(),pageReqVO.getPageSize());
            IPage<VendorInfoDO> vendorInfoDOIPage = vendorInfoMapper.selectPageByInfo(page, new QueryWrapperX<VendorInfoDO>()
                    .likeIfPresent("vendor_name", pageReqVO.getVendorName())
                    .eqIfPresent("vendor_type", pageReqVO.getVendorType())
                    .likeIfPresent("bbi.business_name",pageReqVO.getBelongBusinessName())
                    .eq("bvi.deleted",0));

            vendorInfoDOPageResult.setList(vendorInfoDOIPage.getRecords());
            vendorInfoDOPageResult.setTotal(vendorInfoDOIPage.getTotal());
        } else {
            vendorInfoDOPageResult =  vendorInfoMapper.selectPage(pageReqVO);
        }

        vendorInfoDOPageResult.getList().forEach(item -> {
            if(redisUtil.validateBusinessInfoRedisExists(item.getBelongBusinessId())){
                item.setBelongBusinessName(redisUtil.getBusinessInfoRedis(item.getBelongBusinessId()).getBusinessName());
            }else {
                item.setBelongBusinessName("所属商户不存在");
            }
        });
        return vendorInfoDOPageResult;
    }


    @Override
    public List<VendorInfoDO> getVendorInfoList() {
        return vendorInfoMapper.selectList();
    }

    @Override
    public VendorInfoDO getVendorInfoByVendorId(String vendorId) {
        VendorInfoDO vendorInfoDO = new VendorInfoDO();
        vendorInfoDO.setVendorId(vendorId);
        return vendorInfoMapper.selectOne(new QueryWrapper<>(vendorInfoDO));
    }

}
