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

import cn.hutool.core.collection.CollUtil;
import com.tmerclub.cloud.api.biz.feign.AttachFileFeignClient;
import com.tmerclub.cloud.api.multishop.vo.ShopBankCardVO;
import com.tmerclub.cloud.api.multishop.vo.ShopDetailVO;
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.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.multishop.constant.AuditStatus;
import com.tmerclub.cloud.multishop.dto.AllinpayShopBankCardDTO;
import com.tmerclub.cloud.multishop.dto.ShopCompanyDTO;
import com.tmerclub.cloud.multishop.mapper.ShopCompanyMapper;
import com.tmerclub.cloud.multishop.mapper.ShopDetailMapper;
import com.tmerclub.cloud.multishop.model.ShopAuditing;
import com.tmerclub.cloud.multishop.model.ShopCompany;
import com.tmerclub.cloud.multishop.service.*;
import com.tmerclub.cloud.multishop.vo.ShopAuditingVO;
import com.tmerclub.cloud.multishop.vo.ShopCompanyVO;
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 lth
 * @Date 2021/4/25 15:45
 */
@Service
public class ShopCompanyServiceImpl implements ShopCompanyService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ShopCompanyServiceImpl.class);

    @Autowired
    private ShopCompanyMapper shopCompanyMapper;
    @Autowired
    private ShopAuditingService shopAuditingService;
    @DubboReference
    private AttachFileFeignClient attachFileFeignClient;
    @DubboReference
    private AllinpayFeignClient allinpayFeignClient;
    @Autowired
    private ShopDetailMapper shopDetailMapper;
    @Autowired
    private ShopAllinpayService shopAllinpayService;
    @Autowired
    @Lazy
    private ShopDetailService shopDetailService;
    @Autowired
    private ShopBankCardService shopBankCardService;
    @Autowired
    private FeignShopConfig feignShopConfig;

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

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateByShopId(ShopCompany shopCompany, Long shopId, Integer temp) {
        this.checkInfo(shopCompany, false, temp);
        shopCompanyMapper.updateByShopId(shopCompany, shopId, temp);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void platformUpdateShopCompany(ShopCompany shopCompany, Long shopId) {
        this.checkInfo(shopCompany, false, null);
        // 通联开启后，平台更新商家的工商信息也需要通过通联审核
        // 且只有平台开店审核失败的店铺才能更改工商信息，所以这里只需要设置企业信息，同步返回
        ShopCompanyVO shopCompanyVO = getShopCompanyByShopIdAndStatus(shopId, AuditStatus.SUCCESSAUDIT.value());
        if (Objects.nonNull(shopCompanyVO)) {
            throw new LuckException("工商信息已通过，无需修改");
        }
        List<ShopBankCardVO> shopBankCardList = shopBankCardService.listByShopId(shopId);
        if (CollUtil.isEmpty(shopBankCardList)) {
            throw new LuckException("店铺银行卡为空，请补充");
        }
        updateByShopId(shopCompany, shopCompany.getShopId(), 0);
        // 更新开店为待审核状态，影印件才可以回调
        ShopAuditingVO shopAuditingVO = shopAuditingService.getByshopId(shopId);
        ShopAuditing shopAuditing = BeanUtil.map(shopAuditingVO, ShopAuditing.class);
        shopAuditing.setStatus(AuditStatus.WAITAUDIT.value());
        shopAuditing.setRemarks("平台提交申请");
        if (Objects.equals(shopAuditingVO.getStatus(), AuditStatus.FAILAUDIT.value())) {
            shopAuditingService.update(shopAuditing);
        }
        // 通联审核
        ShopBankCardVO shopBankCardVO = shopBankCardList.get(0);
        AllinpayShopBankCardDTO allinpayShopBankCardDTO = new AllinpayShopBankCardDTO();
        allinpayShopBankCardDTO.setAccountNo(shopBankCardVO.getCardNo());
        allinpayShopBankCardDTO.setParentBankName(shopBankCardVO.getBankName());
        allinpayShopBankCardDTO.setBankName(shopBankCardVO.getBranchName());
        allinpayShopBankCardDTO.setUnionBank(shopBankCardVO.getUnionBank());
        ShopDetailVO shopDetailVO = shopDetailService.getByShopId(shopId);
        shopBankCardService.allinpaySetCompanyInfo(allinpayShopBankCardDTO, shopId, BeanUtil.map(shopCompany, ShopCompanyVO.class), shopDetailVO);
    }

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

    @Override
    public ShopCompanyVO getById(Long shopCompanyId) {
        ShopCompany shopCompany = shopCompanyMapper.getByShopCompanyId(shopCompanyId);
        return BeanUtil.map(shopCompany, ShopCompanyVO.class);
    }

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

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(ShopCompany shopCompany, boolean isCreate) {
        this.checkInfo(shopCompany, isCreate, null);
        shopCompanyMapper.save(shopCompany);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ShopCompany shopCompany) {
        shopCompanyMapper.update(shopCompany);
    }

    @Override
    public Boolean checkCreditCode(String creditCode, Long shopId) {
        List<Long> shopIds = shopCompanyMapper.getShopIdByCreditCode(creditCode);
        if (CollUtil.isNotEmpty(shopIds)) {
            boolean isSame = true;
            for (Long creditShopId : shopIds) {
                if (!Objects.equals(creditShopId, shopId)) {
                    LOGGER.info("店铺信用代码重复");
                    isSame = false;
                    break;
                }
            }
            return !isSame;
        }
        return false;
    }

    @Override
    public void deleteByShopIdAndStatus(Long shopId, Integer status) {
        shopCompanyMapper.deleteByShopIdAndStatus(shopId, status);
    }

    @Override
    public void checkInfo(ShopCompany shopCompany, Boolean isCreate, Integer temp) {
        if (isCreate) {
            ShopCompanyVO oldCompany = shopCompanyMapper.getShopCompanyByShopIdAndStatus(shopCompany.getShopId(), AuditStatus.SUCCESSAUDIT.value());
            if (Objects.nonNull(oldCompany)) {
                throw new LuckException("店铺工商信息已存在,不能重复新增");
            }
        } else {
            ShopAuditingVO shopAuditingVO = shopAuditingService.getByshopId(shopCompany.getShopId());
            if (Objects.nonNull(shopAuditingVO) && Objects.equals(shopAuditingVO.getStatus(), AuditStatus.WAITAUDIT.value())
                    && !shopAllinpayService.getIsAllinpay() && !Objects.equals(temp, 0)) {
                throw new LuckException("店铺处于待审核状态，无法修改店铺信息");
            }
        }
        if (checkCreditCode(shopCompany.getCreditCode(), shopCompany.getShopId())) {
            throw new LuckException("统一信用码重复");
        }
        if (shopCompany.getEndTime() != null && !shopCompany.getStartTime().before(shopCompany.getEndTime())) {
            throw new LuckException("营业起始日期不能大于营业终止时间");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(ShopCompany shopCompany) {
        shopCompanyMapper.updateById(shopCompany);
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String uploadIdCard(ShopCompanyDTO shopCompanyDTO, ShopDetailVO shopDetailVO, Integer status) {
        Long shopId = shopDetailVO.getShopId();
        if (!Objects.equals(shopDetailVO.getIdCardCollectProcessStatus(), status)) {
            // 状态不同先更新状态
            shopDetailService.updateAllinpayIdCardStatus(AllinpayConstant.SHOP + shopId, status);
            shopDetailVO.setIdCardCollectProcessStatus(status);
        }
        if (Objects.equals(shopDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.ALL.value())) {
            return "影印件已审核通过，请刷新页面";
        }
        if (Objects.equals(shopDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.WAIT_AUDIT.value())) {
            return "影印件待审核中，请刷新影印件";
        }
        if (Objects.equals(shopDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.UN_COMMITTED.value())) {
            LOGGER.info("店铺{}影印件上传失败，尝试重新上传", shopId);
            // 还没提交上传
            ShopCompanyVO shopCompanyVO = BeanUtil.map(shopCompanyDTO, ShopCompanyVO.class);
            String result = idCardCollect(shopCompanyVO, shopId);
            if (Objects.equals(result, AllinpayConstant.ALLINPAY_AUDIT_SUCCESS)) {
                shopCompanyMapper.updateIdCardById(shopCompanyVO);
            }
            return result;
        }
        if (Objects.equals(shopDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.REG.value())) {
            LOGGER.info("店铺{}影印件只有工商信息审核通过了,尝试重新上传身份证信息", shopId);
            // 只有工商信息审核通过了,重新提交下身份证信息
            // 国徽面
            String legalPicEmblemToken = getImgUrl(shopCompanyDTO.getIdentityCardLater(), PicType.REVERSE_SIDE_OF_ID_CARD.getCode());
            if (!legalPicEmblemToken.contains(HTTP)) {
                LOGGER.info("店铺身份证-国徽像获取文件路径失败，原因{}", legalPicEmblemToken);
                return legalPicEmblemToken;
            }
            // 人面像
            String legalPicFaceToken = getImgUrl(shopCompanyDTO.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.SHOP + shopId);
            if (!fileUpload.isSuccess() || Objects.equals(fileUpload.getData().getResult(), ID_CARD_FAIL_RESULT)) {
                return "店铺审核通过，影印件-身份证信息上传失败，原因为：" + (Objects.isNull(fileUpload.getMsg()) ? fileUpload.getData().getFailReason() : fileUpload.getMsg());
            }
            shopCompanyMapper.updateIdCardById(BeanUtil.map(shopCompanyDTO, ShopCompanyVO.class));
        }
        if (Objects.equals(shopDetailVO.getIdCardCollectProcessStatus(), IdCardCollectProcessStatus.ID_CARD.value())) {
            LOGGER.info("店铺{}影印件只有法人信息通过,尝试重新上传工商信息", shopId);
            // 只有法人信息通过,重新提交下工商信息
            String businessLicense = getImgUrl(shopCompanyDTO.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.SHOP + shopId);
            if (!fileUpload.isSuccess() || Objects.equals(fileUpload.getData().getResult(), ID_CARD_FAIL_RESULT)) {
                return "店铺审核通过，影印件-营业执照信息上传失败，原因为：" + (Objects.isNull(fileUpload.getMsg()) ? fileUpload.getData().getFailReason() : fileUpload.getMsg());
            }
            shopCompanyMapper.updateIdCardById(BeanUtil.map(shopCompanyDTO, ShopCompanyVO.class));
        }
        return "影印件更新成功";
    }

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

    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;
    }
}
