
package com.tmerclub.cloud.supplier.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.tmerclub.cloud.api.biz.feign.AttachFileFeignClient;
import com.tmerclub.cloud.api.payment.allinpay.member.resp.IdCardCollectByFileUploadResp;
import com.tmerclub.cloud.api.payment.feign.AllinpayFeignClient;
import com.tmerclub.cloud.api.platform.config.FeignShopConfig;
import com.tmerclub.cloud.api.supplier.vo.SupplierApiDetailVO;
import com.tmerclub.cloud.api.supplier.vo.SupplierBankCardVO;
import com.tmerclub.cloud.common.bean.UploadFile;
import com.tmerclub.cloud.common.constant.AllinpayConstant;
import com.tmerclub.cloud.common.constant.IdCardCollectProcessStatus;
import com.tmerclub.cloud.common.constant.PicType;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.supplier.constant.AuditStatus;
import com.tmerclub.cloud.supplier.dto.AllinpaySupplierBankCardDTO;
import com.tmerclub.cloud.supplier.dto.SupplierCompanyDTO;
import com.tmerclub.cloud.supplier.mapper.SupplierCompanyMapper;
import com.tmerclub.cloud.supplier.mapper.SupplierDetailMapper;
import com.tmerclub.cloud.supplier.model.SupplierAuditing;
import com.tmerclub.cloud.supplier.model.SupplierCompany;
import com.tmerclub.cloud.supplier.service.*;
import com.tmerclub.cloud.supplier.vo.SupplierAuditingVO;
import com.tmerclub.cloud.supplier.vo.SupplierCompanyVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 供应商工商信息
 *
 * @author lhd
 * @date 2022-03-14 17:04:32
 */
@Service
public class SupplierCompanyServiceImpl implements SupplierCompanyService {
    private static final Logger LOGGER = LoggerFactory.getLogger(SupplierCompanyServiceImpl.class);

    @Autowired
    private SupplierCompanyMapper supplierCompanyMapper;
    @Autowired
    private SupplierAuditingService supplierAuditingService;
    @DubboReference
    private AttachFileFeignClient attachFileFeignClient;
    @DubboReference
    private AllinpayFeignClient allinpayFeignClient;
    @Autowired
    private SupplierDetailMapper supplierDetailMapper;
    @Autowired
    private SupplierAllinpayService supplierAllinpayService;
    @Autowired
    @Lazy
    private SupplierDetailService supplierDetailService;
    @Autowired
    private SupplierBankCardService supplierBankCardService;
    @Autowired
    private FeignShopConfig feignShopConfig;

    private static final String HTTP = "http";
    private static final String JPG = "jpg";
    private static final String PNG = "png";
    private static final Integer ID_CARD_FAIL_RESULT = 2;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateBySupplierId(SupplierCompany supplierCompany, Long supplierId, Integer temp) {
        this.checkInfo(supplierCompany, false, temp);
        supplierCompanyMapper.updateBySupplierId(supplierCompany, supplierId, temp);
    }

    @Override
    public SupplierCompanyVO getById(Long supplierCompanyId) {
        SupplierCompany supplierCompany = supplierCompanyMapper.getBySupplierCompanyId(supplierCompanyId);
        return BeanUtil.map(supplierCompany, SupplierCompanyVO.class);
    }

    @Override
    public SupplierCompanyVO getSupplierCompanyBySupplierIdAndStatus(Long supplierId, Integer status) {
        SupplierCompanyVO supplierCompanyVO = supplierCompanyMapper.getSupplierCompanyBySupplierIdAndStatus(supplierId, status);
        // 检查工商信息是否有更新记录,若存在更新记录则发请求 查询审核信息 (逻辑上或许可以修改为存在多条工商信息记录)
        if (Objects.nonNull(supplierCompanyVO)) {
            Integer recordStatus = supplierCompanyMapper.getLatestRecord(supplierId);
            if (!Objects.equals(AuditStatus.SUCCESSAUDIT.value(), recordStatus)) {
                supplierCompanyVO.setEdit(true);
                supplierCompanyVO.setNewStatus(recordStatus);
            }
        }
        return supplierCompanyVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SupplierCompany supplierCompany, boolean isCreate) {
        this.checkInfo(supplierCompany, isCreate, null);
        supplierCompanyMapper.save(supplierCompany);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SupplierCompany supplierCompany) {
        supplierCompanyMapper.update(supplierCompany);
    }

    @Override
    public Boolean checkCreditCode(String creditCode, Long supplierId) {
        List<Long> supplierIds = supplierCompanyMapper.getSupplierIdByCreditCode(creditCode);
        if (CollUtil.isNotEmpty(supplierIds)) {
            boolean isSame = true;
            for (Long creditSupplierId : supplierIds) {
                if (!Objects.equals(creditSupplierId, supplierId)) {
                    LOGGER.info("供应商信用代码重复");
                    isSame = false;
                    break;
                }
            }
            return !isSame;
        }
        return false;
    }

    @Override
    public void deleteBySupplierIdAndStatus(Long supplierId, Integer status) {
        supplierCompanyMapper.deleteBySupplierIdAndStatus(supplierId, status);
    }

    @Override
    public void batchUpdateStatus(Long supplierId, Integer status, Integer dbStatus) {
        supplierCompanyMapper.batchUpdateStatus(supplierId, status, dbStatus);
    }

    /**
     * 校验供应商工商信息，isCreate为true代表校验新增时的信息，false代表校验更新时的信息
     * @param supplierCompany
     * @param isCreate
     * @param temp 0代表通过审核，1代表平台修改
     */
    @Override
    public void checkInfo(SupplierCompany supplierCompany, Boolean isCreate, Integer temp) {
        if (isCreate) {
            SupplierCompanyVO oldCompany = supplierCompanyMapper.getSupplierCompanyBySupplierIdAndStatus(supplierCompany.getSupplierId(), AuditStatus.SUCCESSAUDIT.value());
            if (Objects.nonNull(oldCompany)) {
                throw new LuckException("供应商工商信息已存在,不能重复新增");
            }
        } else {
            SupplierAuditingVO supplierAuditingVO = supplierAuditingService.getBySupplierId(supplierCompany.getSupplierId());
            if (Objects.nonNull(supplierAuditingVO) && Objects.equals(supplierAuditingVO.getStatus(), AuditStatus.WAITAUDIT.value())
                    && !supplierAllinpayService.getIsAllinpay() && !Objects.equals(temp, 0)) {
                throw new LuckException("供应商处于待审核状态，无法修改供应商信息");
            }
        }
        if (checkCreditCode(supplierCompany.getCreditCode(), supplierCompany.getSupplierId())) {
            throw new LuckException("统一信用码重复");
        }
        if (supplierCompany.getEndTime() != null && !supplierCompany.getStartTime().before(supplierCompany.getEndTime())) {
            throw new LuckException("营业起始日期不能大于营业终止时间");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(SupplierCompany supplierCompany) {
        supplierCompanyMapper.updateById(supplierCompany);
    }

    @Override
    public String idCardCollect(SupplierCompanyVO supplierCompany, Long supplierId) {
        // 该方法会上传营业执照和身份证
        String businessLicense = getImgUrl(supplierCompany.getBusinessLicense(), PicType.BUSINESS_LICENSE.getCode());
        if (!businessLicense.contains(HTTP)) {
            LOGGER.info("供应商营业执照获取文件路径失败，原因{}", businessLicense);
            return businessLicense;
        }
        ServerResponseEntity<IdCardCollectByFileUploadResp> buinessLicense = allinpayFeignClient.idCardCollectByFileUpload(null,
                null, PicType.BUSINESS_LICENSE.getCode(), businessLicense, AllinpayConstant.SUPPLIER + supplierId);
        if (!buinessLicense.isSuccess() || Objects.equals(buinessLicense.getData().getResult(), ID_CARD_FAIL_RESULT)) {
            return "供应商审核通过，影印件上传失败，原因为：" + (Objects.isNull(buinessLicense.getMsg()) ? buinessLicense.getData().getFailReason() : buinessLicense.getMsg());
        }
        // 人面像
        String legalPicFaceToken = getImgUrl(supplierCompany.getIdentityCardFront(), PicType.FRONT_OF_ID_CARD.getCode());
        if (!legalPicFaceToken.contains(HTTP)) {
            LOGGER.info("供应商身份证-人面像获取文件路径失败，原因{}", legalPicFaceToken);
            return legalPicFaceToken;
        }
        // 国徽面
        String legalPicEmblemToken = getImgUrl(supplierCompany.getIdentityCardLater(), PicType.REVERSE_SIDE_OF_ID_CARD.getCode());
        if (!legalPicEmblemToken.contains(HTTP)) {
            LOGGER.info("供应商身份证-国徽像获取文件路径失败，原因{}", legalPicEmblemToken);
            return legalPicEmblemToken;
        }
        ServerResponseEntity<IdCardCollectByFileUploadResp> fileUpload = allinpayFeignClient.idCardCollectByFileUpload(legalPicFaceToken,
                legalPicEmblemToken, null, null, AllinpayConstant.SUPPLIER + supplierId);
        if (!fileUpload.isSuccess() || Objects.equals(fileUpload.getData().getResult(), ID_CARD_FAIL_RESULT)) {
            return "供应商审核通过，影印件上传失败，原因为：" + (Objects.isNull(fileUpload.getMsg()) ? fileUpload.getData().getFailReason() : fileUpload.getMsg());
        }
        // 所有都上传成功，改变供应商影印件状态
        supplierDetailMapper.updateAllinpayIdCardStatus(supplierId, IdCardCollectProcessStatus.WAIT_AUDIT.value());
        return AllinpayConstant.ALLINPAY_AUDIT_SUCCESS;
    }

    @Override
    public void updateStatusToWaitAudit() {
        supplierCompanyMapper.updateStatusToWaitAudit();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String uploadIdCard(SupplierCompanyDTO supplierCompanyDTO, SupplierApiDetailVO supplierApiDetailVO, Integer status) {
        Long supplierId = supplierApiDetailVO.getSupplierId();
        if (!Objects.equals(supplierApiDetailVO.getIdCardCollectProcessStatus(), status)) {
            // 状态不同先更新状态
            supplierDetailService.updateAllinpayIdCardStatus(AllinpayConstant.SUPPLIER + supplierId, status);
            supplierApiDetailVO.setIdCardCollectProcessStatus(status);
        }
        if (Objects.equals(supplierApiDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.ALL.value())) {
            return "影印件已审核通过，请刷新页面";
        }
        if (Objects.equals(supplierApiDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.WAIT_AUDIT.value())) {
            return "影印件待审核中，请刷新影印件";
        }
        if (Objects.equals(supplierApiDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.UN_COMMITTED.value())) {
            LOGGER.info("供应商{}影印件上传失败，尝试重新上传", supplierId);
            // 还没提交上传
            SupplierCompanyVO supplierCompanyVO = BeanUtil.map(supplierCompanyDTO, SupplierCompanyVO.class);
            String result = idCardCollect(supplierCompanyVO, supplierId);
            if (Objects.equals(result, AllinpayConstant.ALLINPAY_AUDIT_SUCCESS)) {
                supplierCompanyMapper.updateIdCardById(supplierCompanyVO);
            }
            return result;
        }
        if (Objects.equals(supplierApiDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.REG.value())) {
            LOGGER.info("供应商{}影印件只有工商信息审核通过了,尝试重新上传身份证信息", supplierId);
            // 只有工商信息审核通过了,重新提交下身份证信息
            // 国徽面
            String legalPicEmblemToken = getImgUrl(supplierCompanyDTO.getIdentityCardLater(), PicType.REVERSE_SIDE_OF_ID_CARD.getCode());
            if (!legalPicEmblemToken.contains(HTTP)) {
                LOGGER.info("供应商重新上传身份证-国徽像获取文件路径失败，原因{}", legalPicEmblemToken);
                return legalPicEmblemToken;
            }
            // 人面像
            String legalPicFaceToken = getImgUrl(supplierCompanyDTO.getIdentityCardFront(), PicType.FRONT_OF_ID_CARD.getCode());
            if (!legalPicFaceToken.contains(HTTP)) {
                LOGGER.info("供应商重新上传身份证-人面像获取文件路径失败，原因{}", legalPicFaceToken);
                return legalPicFaceToken;
            }
            ServerResponseEntity<IdCardCollectByFileUploadResp> fileUpload = allinpayFeignClient.idCardCollectByFileUpload(legalPicFaceToken,
                    legalPicEmblemToken, null, null, AllinpayConstant.SUPPLIER + supplierId);
            if (!fileUpload.isSuccess() || Objects.equals(fileUpload.getData().getResult(), ID_CARD_FAIL_RESULT)) {
                return "供应商审核通过，影印件-身份证信息上传失败，原因为：" + (Objects.isNull(fileUpload.getMsg()) ? fileUpload.getData().getFailReason() : fileUpload.getMsg());
            }
            supplierCompanyMapper.updateIdCardById(BeanUtil.map(supplierCompanyDTO, SupplierCompanyVO.class));
        }
        if (Objects.equals(supplierApiDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.ID_CARD.value())) {
            LOGGER.info("供应商{}影印件只有法人信息通过,尝试重新上传工商信息", supplierId);
            // 只有法人信息通过,重新提交下工商信息
            String businessLicense = getImgUrl(supplierCompanyDTO.getBusinessLicense(), PicType.BUSINESS_LICENSE.getCode());
            if (!businessLicense.contains(HTTP)) {
                LOGGER.info("供应商重新上传营业执照获取文件路径失败，原因{}", businessLicense);
                return businessLicense;
            }
            ServerResponseEntity<IdCardCollectByFileUploadResp> fileUpload = allinpayFeignClient.idCardCollectByFileUpload(null,
                    null, PicType.BUSINESS_LICENSE.getCode(), businessLicense, AllinpayConstant.SUPPLIER + supplierId);
            if (!fileUpload.isSuccess() || Objects.equals(fileUpload.getData().getResult(), ID_CARD_FAIL_RESULT)) {
                return "供应商审核通过，影印件-营业执照信息上传失败，原因为：" + (Objects.isNull(fileUpload.getMsg()) ? fileUpload.getData().getFailReason() : fileUpload.getMsg());
            }
            supplierCompanyMapper.updateIdCardById(BeanUtil.map(supplierCompanyDTO, SupplierCompanyVO.class));
        }
        return "影印件更新成功";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void platformUpdateSupplierCompany(SupplierCompany supplierCompany, Long supplierId) {
        this.checkInfo(supplierCompany, false, null);
        // 通联开启后，平台更新商家的工商信息也需要通过通联审核
        // 且只有平台开店审核失败的店铺才能更改工商信息，所以这里只需要设置企业信息，同步返回
        SupplierCompanyVO supplierCompanyVO = getSupplierCompanyBySupplierIdAndStatus(supplierId, AuditStatus.SUCCESSAUDIT.value());
        if (Objects.nonNull(supplierCompanyVO)) {
            throw new LuckException("工商信息已通过，无需修改");
        }
        List<SupplierBankCardVO> supplierBankCardList = supplierBankCardService.listBySupplierId(supplierId);
        if (CollUtil.isEmpty(supplierBankCardList)) {
            throw new LuckException("供应商银行卡为空，请补充");
        }
        updateBySupplierId(supplierCompany, supplierCompany.getSupplierId(), 0);
        // 更新开店为待审核状态，影印件才可以回调
        SupplierAuditingVO supplierAuditingVO = supplierAuditingService.getBySupplierId(supplierId);
        SupplierAuditing shopAuditing = BeanUtil.map(supplierAuditingVO, SupplierAuditing.class);
        shopAuditing.setStatus(AuditStatus.WAITAUDIT.value());
        shopAuditing.setRemarks("平台提交申请");
        if (Objects.equals(supplierAuditingVO.getStatus(), AuditStatus.FAILAUDIT.value())) {
            supplierAuditingService.update(shopAuditing);
        }
        // 通联审核
        SupplierBankCardVO supplierBankCardVO = supplierBankCardList.get(0);
        AllinpaySupplierBankCardDTO allinpaySupplierBankCardDTO = new AllinpaySupplierBankCardDTO();
        allinpaySupplierBankCardDTO.setAccountNo(supplierBankCardVO.getCardNo());
        allinpaySupplierBankCardDTO.setParentBankName(supplierBankCardVO.getBankName());
        allinpaySupplierBankCardDTO.setBankName(supplierBankCardVO.getBranchName());
        allinpaySupplierBankCardDTO.setUnionBank(supplierBankCardVO.getUnionBank());
        SupplierApiDetailVO supplierApiDetailVO = supplierDetailService.getBySupplierId(supplierId);
        supplierBankCardService.allinpaySetCompanyInfo(allinpaySupplierBankCardDTO, supplierId, BeanUtil.map(supplierCompany, SupplierCompanyVO.class), supplierApiDetailVO);
    }

    private String getImgUrl(String imageUrl, Integer picType) {
        if (Objects.isNull(imageUrl)) {
            return "供应商审核通过，" + PicType.getPicTypeName(picType) + "为空，请重新上传";
        }
        ServerResponseEntity<String> responseEntity = attachFileFeignClient.getfileTypeByfilePath(imageUrl);
        String fileType = responseEntity.getData();
        if (Objects.isNull(fileType)) {
            return "供应商审核通过，" + PicType.getPicTypeName(picType) + "该图片类型为空";
        }
        UploadFile uploadFile = feignShopConfig.getUploadFile();
        String imgDomain = uploadFile.getResourceUrl();
        if (!imageUrl.contains(HTTP)) {
            // 给imageUrl 加上文件全路径
            if (Objects.isNull(imgDomain)) {
                // 未配置文件域名，无法上传成功图片
                return "供应商审核通过，" + "未配置文件域名，无法上传成功图片";
            }
            imageUrl = StringUtils.join(imgDomain, imageUrl);
        }
        return imageUrl;
    }

}
