/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.check.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.check.entity.TCheckBankNo;
import com.yifu.cloud.plus.v1.check.mapper.TCheckBankNoMapper;
import com.yifu.cloud.plus.v1.check.service.TCanCheckService;
import com.yifu.cloud.plus.v1.check.service.TCheckBankNoService;
import com.yifu.cloud.plus.v1.check.utils.ChecksUtil;
import com.yifu.cloud.plus.v1.check.vo.CheckBankNoVo;
import com.yifu.cloud.plus.v1.check.vo.CheckBatchVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.ErrorCodes;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.MsgUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 银行卡卡号 校验
 *
 * @author fxj
 * @date 2022-06-20 19:56:33
 */
@RequiredArgsConstructor
@Service
public class TCheckBankNoServiceImpl extends ServiceImpl<TCheckBankNoMapper, TCheckBankNo> implements TCheckBankNoService {

	private final TCanCheckService canCheckService;

	@Override
	public R<TCheckBankNo> checkBankNo(String name, String cardNo) {
		synchronized (this){
			TCheckBankNo  checkBankNo = baseMapper.selectOne(Wrappers.<TCheckBankNo>query().lambda()
					.eq(TCheckBankNo::getBankNo, cardNo)
					.eq(TCheckBankNo::getName, name)
					.last(CommonConstants.LAST_ONE_SQL));
			if (Common.isNotNull(checkBankNo)){
				if ("01".equals(checkBankNo.getResult())) {
					return R.ok(checkBankNo);
				} else {
					return R.failed(checkBankNo);
				}
			}
			R<TCheckBankNo> resR = ChecksUtil.checkBankNoTwo(name,cardNo,canCheckService.getCanCheck());
			if (Common.isNotNull(resR) && Common.isNotNull(resR.getData())){
				baseMapper.insert(resR.getData());
			}
			return resR;
		}
	}

	@Override
	public CheckBankNoVo checkBankNoTwo(String name, String cardNo) {
		CheckBankNoVo vo = new CheckBankNoVo();
		if (Common.isEmpty(name)  || Common.isEmpty(cardNo)){
			vo.setRes(R.failed(MsgUtils.getMessage(ErrorCodes.CHECKS_BANK_NO_REQUEST_PARAM_ERROR)));
			return vo;
		}
		synchronized (this){
			TCheckBankNo  checkBankNo = baseMapper.selectOne(Wrappers.<TCheckBankNo>query().lambda()
					.eq(TCheckBankNo::getBankNo,cardNo)
					.eq(TCheckBankNo::getName,name)
					.last(CommonConstants.LAST_ONE_SQL));
			if (Common.isNotNull(checkBankNo)){
				vo.setRes(R.ok(checkBankNo));
				return vo;
			}
			R<TCheckBankNo> resR = ChecksUtil.checkBankNoTwo(name,cardNo,canCheckService.getCanCheck());
			if (Common.isNotNull(resR) && Common.isNotNull(resR.getData())){
				baseMapper.insert(resR.getData());
			}
			vo.setRes(resR);
			return vo;
		}
	}

	@Override
	public CheckBatchVo checkBankNoBatch(List<TCheckBankNo> list) {
		CheckBatchVo vo = new CheckBatchVo();
		List<String> noList = new ArrayList<>();
		for (TCheckBankNo no : list) {
			if (Common.isNotNull(no.getBankNo())) {
				noList.add(no.getBankNo());
			}
		}
		Map<String, TCheckBankNo> noMap = new HashMap<>();
		if (!noList.isEmpty()) {
			List<TCheckBankNo> checkBankNoList = baseMapper.getListByNoList(noList);
			if (checkBankNoList != null && !checkBankNoList.isEmpty()) {
				for (TCheckBankNo no : checkBankNoList) {
					noMap.put(no.getBankNo(), no);
				}
			}
		}
		List<TCheckBankNo> noCurlist = new ArrayList<>();
		TCheckBankNo cur;
		Map<String, Boolean> bankMap = new HashMap<>();
		for (TCheckBankNo check : list) {
			cur = noMap.get(check.getBankNo());
			if (cur != null) {
				if (CommonConstants.ZERO_ONE.equals(cur.getResult())) {
					bankMap.put(cur.getBankNo(), cur.getName().equals(check.getName()));
				} else {
					if (cur.getName().equals(check.getName())) {
						bankMap.put(cur.getBankNo(), false);
					} else {
						noCurlist.add(check);
					}
				}
			} else {
				noCurlist.add(check);
			}
		}
		List<TCheckBankNo> saveList = new ArrayList<>();
		if (!noCurlist.isEmpty()) {
			synchronized (this) {
				TCheckBankNo newNo;
				R<TCheckBankNo> resR;
				boolean canCheck = canCheckService.getCanCheck();
				for (TCheckBankNo no : noCurlist) {
					resR = ChecksUtil.checkBankNoTwo(no.getName(), no.getBankNo(), canCheck);
					if (Common.isNotNull(resR) && resR.getCode() == CommonConstants.SUCCESS
							&& Common.isNotNull(resR.getData())) {
						newNo = resR.getData();
						bankMap.put(no.getBankNo(), CommonConstants.ZERO_ONE.equals(newNo.getResult()));
						saveList.add(newNo);
					} else {
						bankMap.put(no.getBankNo(), false);
					}
				}
				if (!saveList.isEmpty()) {
					this.saveBatch(saveList);
				}
			}
		}
		vo.setCheckMap(bankMap);
		return vo;
	}

}
