package jnpf.personnels.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.faceid.v20180301.FaceidClient;
import com.tencentcloudapi.faceid.v20180301.models.IdCardVerificationRequest;
import com.tencentcloudapi.faceid.v20180301.models.IdCardVerificationResponse;
import io.seata.spring.annotation.GlobalTransactional;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.exception.LoginException;
import jnpf.model.personnels.po.FtbPersonnelsIdcardVerification;
import jnpf.personnels.config.TengxunLicenseConfig;
import jnpf.personnels.mapper.FtbPersonnelsIdcardVerificationMapper;
import jnpf.util.TenantUtil;
import jnpf.util.data.DataSourceContextHolder;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * 身份信息认证（二要素核验）
 * @author wcx
 * @date 2026/03/10
 */
@Component
public class PersonnelIdCardVerificationUtils {

    @Resource
    private FaceidClient faceidClient;

    @Resource
    private FtbPersonnelsIdcardVerificationMapper ftbPersonnelsIdcardVerificationMapper;

    @Resource
    private RedissonClient redissonClient;

    @Value("${idcard.tenant.enabled:false}")
    private boolean isEnable;

    @Value("${idcard.tenant.code:''}")
    private String tenantIdcardList;

    private final ExecutorService threadPoolExecutor = Executors.newSingleThreadExecutor();

    /**
     * 校验身份信息认证一致
     *
     * @param idCard 身份证号
     * @param name  姓名
     * @return {@link IdCardVerificationResponse }
     */
    public IdCardVerificationResponse idCardVerification(String idCard,String name,String tenantId) {
        if (!isEnable) {
            return null;
        }
        if (StrUtil.isBlank(tenantIdcardList)) {
           return null;
        }
        if (!Arrays.asList(tenantIdcardList.split(",")).contains(tenantId)) {
            return null;
        }
        RLock rLock = redissonClient.getLock("ftb-idCard-lock-" + idCard);
        try {
            rLock.lock(30, TimeUnit.SECONDS);
            LambdaQueryWrapper<FtbPersonnelsIdcardVerification> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(FtbPersonnelsIdcardVerification::getIdCard, idCard);
            queryWrapper.eq(FtbPersonnelsIdcardVerification::getUserName, name);
            queryWrapper.last("limit 1");
            IdCardVerificationResponse verificationResult = getVerificationResult(queryWrapper);
            if (Objects.nonNull(verificationResult)) {
                return verificationResult;
            }
            IdCardVerificationRequest req = new IdCardVerificationRequest();
            req.setIdCard(idCard);
            req.setName(name);
            IdCardVerificationResponse response = faceidClient.IdCardVerification(req);
            FtbPersonnelsIdcardVerification insertValue = new FtbPersonnelsIdcardVerification();
            insertValue.setIdCard(idCard);
            insertValue.setUserName(name);
            insertValue.setVerificationResult(JSON.toJSONString(response));
            Future<Integer> integerFuture = threadPoolExecutor.submit(() -> {
                //切换成租户库
                try {
                    TenantDataSourceUtil.switchTenant(tenantId);
                    return ftbPersonnelsIdcardVerificationMapper.insert(insertValue);
                } catch (LoginException e) {
                    throw new RuntimeException("切换租户失败");
                } finally {
                    DataSourceContextHolder.clearDatasourceType();
                }
            });
            integerFuture.get();
            return response;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }

    /**
     * 统一校验结果
     * @param response
     */
    public void checkIdCardVerification(IdCardVerificationResponse response) {
        if (Objects.nonNull(response)) {
            if (!"0".equals(response.getResult())) {
                throw new RuntimeException(response.getDescription());
            }
        }
    }

    private IdCardVerificationResponse getVerificationResult(LambdaQueryWrapper<FtbPersonnelsIdcardVerification> queryWrapper) {
        FtbPersonnelsIdcardVerification ftbPersonnelsIdcardVerification = ftbPersonnelsIdcardVerificationMapper.selectOne(queryWrapper);
        if (Objects.nonNull(ftbPersonnelsIdcardVerification)) {
            return JSON.parseObject(ftbPersonnelsIdcardVerification.getVerificationResult(), IdCardVerificationResponse.class);
        }
        return null;
    }


    @Bean
    public FaceidClient faceidClient(TengxunLicenseConfig tengxunLicenseConfig) {
        Credential credential = new Credential(tengxunLicenseConfig.getSecretId(), tengxunLicenseConfig.getSecretKey());
        return new FaceidClient(credential,"");
    }

}
