package com.sunxung.factoring.service.financing.review.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.util.CodeUtil;
import com.sunxung.factoring.component.util.CollectionUtil;
import com.sunxung.factoring.component.util.ConstantConversionUtil;
import com.sunxung.factoring.component.util.ValidatorUtil;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.entity.ValidatorEntity;
import com.sunxung.factoring.entity.financing.review.*;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.mapper.financing.review.ReviewMortgageBasicInfoMapper;
import com.sunxung.factoring.service.financing.review.*;
import com.sunxung.factoring.service.sys.FileStorageService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description :
 * @Author : L.Jia
 * @Date: 2023-12-15 19:53
 */

@Service
public class ReviewMortgageBasicInfoServiceImpl extends ServiceImpl<ReviewMortgageBasicInfoMapper, ReviewMortgageBasicInfo>
        implements ReviewMortgageBasicInfoService {

    @Autowired
    private ReviewQuotaMortgageRelService reviewQuotaMortgageRelService;
    @Autowired
    private ReviewMortgageCollateralInfoService collateralInfoService;
    @Autowired
    private ReviewMortgagePledgeInfoService pledgeInfoService;
    @Autowired
    private ReviewMortgageBasicInfoService reviewMortgageBasicInfoService;
    @Autowired
    private IReviewGuaranteeFileService reviewGuaranteeFileService;
    @Autowired
    private FileStorageService fileStorageService;


    @Override
    public List<ReviewMortgageBasicInfo> findByQuotaDisburseId(Long quotaDisburseId) {

        List<ReviewQuotaMortgageRel> quotaMortgageRelList = reviewQuotaMortgageRelService.list(new QueryWrapper<ReviewQuotaMortgageRel>()
                .eq("review_quota_disburse_id", quotaDisburseId));
        List<ReviewMortgageBasicInfo> mortgageBasicInfoList = new ArrayList<>();
        if (quotaMortgageRelList != null && !quotaMortgageRelList.isEmpty()) {
            for (ReviewQuotaMortgageRel quotaMortgageRel : quotaMortgageRelList) {
                ReviewMortgageBasicInfo mortgageBasicInfo = baseMapper.selectById(quotaMortgageRel.getReviewMortgageBasicId());
                if (mortgageBasicInfo != null && mortgageBasicInfo.getId() != null) {
                    //获取抵押物信息
                    List<ReviewMortgageCollateralInfo> collateralInfoList = collateralInfoService.list(new QueryWrapper<ReviewMortgageCollateralInfo>()
                            .eq("review_mortgage_basic_id", mortgageBasicInfo.getId()));
                    if (CollectionUtil.isNotEmpty(collateralInfoList)) {
                        collateralInfoList.forEach(reviewMortgageCollateralInfo -> {
                            List<ReviewGuaranteeFile> reviewGuaranteeFiles = reviewGuaranteeFileService.lambdaQuery().eq(ReviewGuaranteeFile::getGuaranteeId, reviewMortgageCollateralInfo.getId())
                                    .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.CHATTELMORTGAGE_FILE).list();
                            if (CollectionUtil.isNotEmpty(reviewGuaranteeFiles)) {
                                List<FileStorage> fileStorages = reviewGuaranteeFiles.stream().map(reviewGuaranteeSecondFile -> fileStorageService.get(reviewGuaranteeSecondFile.getFileId())).collect(Collectors.toList());
                                reviewMortgageCollateralInfo.setFileStorageList(fileStorages);
                            }
                        });
                    }
                    mortgageBasicInfo.setMortgageCollateralInfoList(collateralInfoList);

                    //获取质押物信息
                    List<ReviewMortgagePledgeInfo> pledgeInfoList = pledgeInfoService.list(new QueryWrapper<ReviewMortgagePledgeInfo>()
                            .eq("review_mortgage_basic_id", mortgageBasicInfo.getId()));
                    if (CollectionUtil.isNotEmpty(pledgeInfoList)) {
                        pledgeInfoList.forEach(reviewMortgagePledgeInfo -> {
                            List<ReviewGuaranteeFile> reviewGuaranteeFiles = reviewGuaranteeFileService.lambdaQuery().eq(ReviewGuaranteeFile::getGuaranteeId, reviewMortgagePledgeInfo.getId())
                                    .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.PLEDGEINFORMATION_FILE).list();
                            if (CollectionUtil.isNotEmpty(reviewGuaranteeFiles)) {
                                List<FileStorage> fileStorages = reviewGuaranteeFiles.stream().map(reviewGuaranteeSecondFile -> fileStorageService.get(reviewGuaranteeSecondFile.getFileId())).collect(Collectors.toList());
                                reviewMortgagePledgeInfo.setFileStorageList(fileStorages);
                            }
                        });
                    }
                    mortgageBasicInfo.setMortgagePledgeInfoList(pledgeInfoList);

                    // 填充附件信息
                    List<ReviewGuaranteeFile> reviewGuaranteeFiles = reviewGuaranteeFileService.lambdaQuery().eq(ReviewGuaranteeFile::getGuaranteeId, mortgageBasicInfo.getId())
                            .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.MORTGAGEINFORMATION_FILE).list();
                    if (CollectionUtil.isNotEmpty(reviewGuaranteeFiles)) {
                        List<FileStorage> fileStorages = reviewGuaranteeFiles.stream().map(reviewGuaranteeSecondFile -> fileStorageService.get(reviewGuaranteeSecondFile.getFileId())).collect(Collectors.toList());
                        mortgageBasicInfo.setFileStorageList(fileStorages);
                    }
                    mortgageBasicInfoList.add(mortgageBasicInfo);
                }
            }
        }
        return mortgageBasicInfoList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addMortgageInfo(ReviewMortgageBasicInfo mortgageBasicInfo, ReviewQuotaDisburse quotaDisburse) {
        ValidatorUtil.validator(ValidatorEntity.ValidatorType.ADD, mortgageBasicInfo);
        //对所有字符串字段进行trim操作
        ReviewMortgageBasicInfo trimBasicInfo = BeanUtil.trimStrFields(mortgageBasicInfo);
        baseMapper.insert(trimBasicInfo);

        //添加中间表
        ReviewQuotaMortgageRel reviewQuotaMortgageRel = new ReviewQuotaMortgageRel();
        reviewQuotaMortgageRel.setReviewMortgageBasicId(mortgageBasicInfo.getId());
        reviewQuotaMortgageRel.setReviewQuotaDisburseId(quotaDisburse.getId());
        reviewQuotaMortgageRelService.save(reviewQuotaMortgageRel);

        addCollAndPleList(mortgageBasicInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByQuotaDisburseId(ReviewQuotaDisburse quota) {
        if (null != quota) {
            Long quotaDisburseId = quota.getId();
            //查询关联表中有无对应的额度支用ID的信息
            List<ReviewQuotaMortgageRel> quotaMortgageRelList = reviewQuotaMortgageRelService.list(new QueryWrapper<ReviewQuotaMortgageRel>().eq("review_quota_disburse_id", quotaDisburseId));
            if (quotaMortgageRelList != null && !quotaMortgageRelList.isEmpty()) {
                for (ReviewQuotaMortgageRel quotaMortgageRel : quotaMortgageRelList) {
                    Long mortgageInfoId = quotaMortgageRel.getReviewMortgageBasicId();
                    // 删除抵押物详情信息
                    List<ReviewMortgageCollateralInfo> collateralInfos = collateralInfoService.list(new QueryWrapper<ReviewMortgageCollateralInfo>().eq("review_mortgage_basic_id", mortgageInfoId));
                    for (ReviewMortgageCollateralInfo collateralInfo : collateralInfos) {
                        //删除附件
                        reviewGuaranteeFileService.lambdaUpdate().eq(ReviewGuaranteeFile::getGuaranteeId, collateralInfo.getId())
                                .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.CHATTELMORTGAGE_FILE).remove();
                    }
                    collateralInfoService.remove(new QueryWrapper<ReviewMortgageCollateralInfo>().eq("review_mortgage_basic_id", mortgageInfoId));
                    // 删除质押物信息
                    List<ReviewMortgagePledgeInfo> reviewMortgagePledgeInfos = pledgeInfoService.list(new QueryWrapper<ReviewMortgagePledgeInfo>().eq("review_mortgage_basic_id", mortgageInfoId));
                    for (ReviewMortgagePledgeInfo reviewMortgagePledgeInfo : reviewMortgagePledgeInfos) {
                        //删除附件
                        reviewGuaranteeFileService.lambdaUpdate().eq(ReviewGuaranteeFile::getGuaranteeId, reviewMortgagePledgeInfo.getId())
                                .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.PLEDGEINFORMATION_FILE).remove();
                    }
                    pledgeInfoService.remove(new QueryWrapper<ReviewMortgagePledgeInfo>().eq("review_mortgage_basic_id", mortgageInfoId));
                    // 删除附件信息
                    //删除附件
                    reviewGuaranteeFileService.lambdaUpdate().eq(ReviewGuaranteeFile::getGuaranteeId, mortgageInfoId)
                            .eq(ReviewGuaranteeFile::getGuaranteeFileType, ConstantConversionUtil.MORTGAGEINFORMATION_FILE).remove();
                    //删除中间表关联项
                    reviewQuotaMortgageRelService.remove(new QueryWrapper<ReviewQuotaMortgageRel>()
                            .eq("review_quota_disburse_id", quotaDisburseId)
                            .eq("review_mortgage_basic_id", mortgageInfoId));
                    //删除基础表
                    reviewMortgageBasicInfoService.removeById(mortgageInfoId);
                }
            }
        }
    }

    private void addCollAndPleList(ReviewMortgageBasicInfo mortgageBasicInfo) {
        //添加抵押物信息
        List<ReviewMortgageCollateralInfo> collateralInfoList = mortgageBasicInfo.getMortgageCollateralInfoList();
        if (collateralInfoList != null && !collateralInfoList.isEmpty()) {
            int i = 0;
            for (ReviewMortgageCollateralInfo collateralInfo : collateralInfoList) {
                i = i + 1;
                collateralInfo.setSerNo(String.valueOf(i));
                collateralInfo.setReviewMortgageBasicId(mortgageBasicInfo.getId());
                //行政区划设置
                if (CollectionUtil.isNotEmpty(collateralInfo.getCollDistrictStr())) {
                    String collDistrict = StringUtils.join(collateralInfo.getCollDistrictStr(), ConstantConversionUtil.MULTIPLE_SELECTION_SEPARATOR);
                    collateralInfo.setCollDistrict(collDistrict);
                }
                collateralInfoService.save(collateralInfo);
                List<Long> fileStorageIds = collateralInfo.getFileStorageIds();
                if (CollectionUtil.isNotEmpty(fileStorageIds)) {
                    fileStorageIds.forEach(id -> {
                        ReviewGuaranteeFile reviewGuaranteeFile = new ReviewGuaranteeFile();
                        reviewGuaranteeFile.setFileId(id);
                        reviewGuaranteeFile.setGuaranteeFileType(ConstantConversionUtil.CHATTELMORTGAGE_FILE);
                        reviewGuaranteeFile.setGuaranteeId(collateralInfo.getId());
                        reviewGuaranteeFileService.save(reviewGuaranteeFile);
                    });
                }
//                if (CollectionUtil.isNotEmpty(multipartFiles)) {
//                    addSecondGuaranteeFile(collateralInfo.getId(), ConstantConversionUtil.CHATTELMORTGAGE_FILE, multipartFiles);
//                }
            }
        }

        //添加质押物信息
        List<ReviewMortgagePledgeInfo> pledgeInfoList = mortgageBasicInfo.getMortgagePledgeInfoList();
        if (pledgeInfoList != null && !pledgeInfoList.isEmpty()) {
            int i = 0;
            for (ReviewMortgagePledgeInfo pledgeInfo : pledgeInfoList) {
                i = i + 1;
                pledgeInfo.setSerNo(String.valueOf(i));
                pledgeInfo.setReviewMortgageBasicId(mortgageBasicInfo.getId());
                if (pledgeInfo.getEquityRatio() != null) {
                    pledgeInfo.setEquityRatio(pledgeInfo.getEquityRatio().divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP));
                }
                pledgeInfoService.save(pledgeInfo);
                List<Long> multipartFilesIds = pledgeInfo.getFileStorageIds();
                if (CollectionUtil.isNotEmpty(multipartFilesIds)) {
                    multipartFilesIds.forEach(id -> {
                        ReviewGuaranteeFile reviewGuaranteeFile = new ReviewGuaranteeFile();
                        reviewGuaranteeFile.setFileId(id);
                        reviewGuaranteeFile.setGuaranteeFileType(ConstantConversionUtil.PLEDGEINFORMATION_FILE);
                        reviewGuaranteeFile.setGuaranteeId(pledgeInfo.getId());
                        reviewGuaranteeFileService.save(reviewGuaranteeFile);
                    });
                }
//                if (CollectionUtil.isNotEmpty(multipartFiles)) {
//                    addSecondGuaranteeFile(pledgeInfo.getId(), ConstantConversionUtil.PLEDGEINFORMATION_FILE, multipartFiles);
//                }
            }
        }
    }

    private void addSecondGuaranteeFile(Long guaranteeId, String guaranteeFileType, List<MultipartFile> multipartFiles) {
        multipartFiles.forEach(multipartFile -> {
            try {
                FileStorage fileStorage = fileStorageService.addFileStorage(multipartFile, FileModuleDict.ChildEnum.REVIEW_QUOTA_DISBURSE);
                if (null != fileStorage) {
                    ReviewGuaranteeFile reviewGuaranteeFile = new ReviewGuaranteeFile();
                    reviewGuaranteeFile.setFileId(fileStorage.getId());
                    reviewGuaranteeFile.setGuaranteeFileType(guaranteeFileType);
                    reviewGuaranteeFile.setGuaranteeId(guaranteeId);
                    reviewGuaranteeFileService.save(reviewGuaranteeFile);
                }
            } catch (IOException e) {
                log.error("额度支用上传担保类附件出错：" + e.getMessage());
                throw new BusinessException(CodeUtil.FAIL, e.getMessage());
            }
        });
    }
}
