package com.friday.custody.service.tenantService.impl;

import com.alibaba.fastjson.JSON;
import com.friday.custody.dto.TenantEscrowAuthorizationInfoDto;
import com.friday.custody.dto.TenantInfoDto;
import com.friday.custody.entity.DataDictionaryTrustEntity;
import com.friday.custody.entity.TenantInfoEntity;
import com.friday.custody.enums.RetCodeEnum;
import com.friday.custody.exception.RRException;
import com.friday.custody.req.TenantEscrowAuthorizationInfoReq;
import com.friday.custody.req.TenantInfoReq;
import com.friday.custody.service.basicService.DataDictionaryTrustService;
import com.friday.custody.service.basicService.TenantEscrowAuthorizationInfoService;
import com.friday.custody.service.basicService.TenantInfoService;
import com.friday.custody.service.tenantService.TenantService;
import com.friday.custody.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;

@Service
@Slf4j
public class TenantServiceImpl implements TenantService {
    @Autowired
    private TenantInfoService tenantInfoService;

    @Autowired
    private TenantEscrowAuthorizationInfoService tenantEscrowAuthorizationInfoService;

    @Autowired
    private DataDictionaryTrustService dataDictionaryTrustService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R addTenant(TenantInfoDto dto) {
        return tenantInfoService.addTenant(dto);
    }

    @Override
    public  R<TenantInfoDto>  queryTenant(TenantInfoDto dto) {
        return tenantInfoService.queryByKey(dto);
    }

    @Override
    public R saveEscrowAuthorization(String tenantName, String accountKey, TenantEscrowAuthorizationInfoDto dto) {
        //1 查询用户 看看是否存在
        R<TenantInfoDto> tenantResp = tenantInfoService.queryByKey(TenantInfoDto.builder().tenantName(tenantName).accountKey(accountKey).build());
        if (((Integer) tenantResp.get("code")) != RetCodeEnum.SUCCESS.getCode()) {
            log.error("查询数据失败：{}", JSON.toJSONString(tenantResp));
            return tenantResp;
        }
        //2 新增授权
        return tenantEscrowAuthorizationInfoService.addEscrowAuthorization(tenantName,dto);
    }

    @Override
    public R queryAuthorization(String tenantName, String accountKey) {
        //todo 暂时先不做这个
        return null;
    }

    /**
     * 用于每天定时更新任务的
     * @return
     */
    @Override
    public  R<List<TenantEscrowAuthorizationInfoDto>> queryAuthorizations() {
        //之后这里为了防止内存爆掉 可以改成分页查询  暂时用查全部吧
        return  tenantEscrowAuthorizationInfoService.queryAuthorizations();
    }

    @Override
    public R addTenants(String tenantName, List<TenantInfoReq> tenantInfoReqs) {
        try {
            //查询所有租户信息
            R<List<TenantInfoEntity>> resp = tenantInfoService.queryAll();
            if (((Integer) resp.get("code")) != RetCodeEnum.SUCCESS.getCode()) {
                log.error("查询数据失败：{}", JSON.toJSONString(resp));
                return resp;
            }
            //判断新增租户是否已存在
            List<TenantInfoEntity> entityList = resp.getData();
            if (!ObjectUtils.isEmpty(entityList)) {
                entityList.forEach(entity -> {
                    tenantInfoReqs.forEach(req -> {
                        RRException.isNotTrue(StringUtils.isBlank(req.getAdmin()), RetCodeEnum.PARAM_ERROR.getCode(), "admin不能为空!");
                        RRException.isNotTrue(StringUtils.isBlank(req.getAccountKey()), RetCodeEnum.PARAM_ERROR.getCode(), "accountKey不能为空!");
                        String accountName = StringUtils.isNotBlank(req.getAccountName()) ? req.getAccountName() : tenantName;
                        if (entity.getTenantName().equals(req.getAdmin()) && (entity.getAccountKey().equals(req.getAccountKey())
                                 || entity.getAccountName().equals(accountName))) {
                            throw new RRException("开立失败！admin为:" + req.getAdmin() + ", accountName为" + accountName +", accountKey为 : " + req.getAccountKey() + "的租户已存在，请修改后再执行操作！");
                        }
                    });
                });
            }
            return tenantInfoService.addTenantInfos(tenantName,tenantInfoReqs);
        }catch (RRException rre){
            log.error("创建失败,租户已存在！",rre.getMsg());
            return R.error(rre.getMsg());
        }

    }

    @Override
    public R addEscrowAuthorizations(String tenantName, TenantInfoDto tenantInfoDto, List<TenantEscrowAuthorizationInfoReq> tenantEscrowAuthorizationInfoReqs) {
        //判断新增授权是否存在
        try {
            //获取所有授权信息
            R<List<TenantEscrowAuthorizationInfoDto>> listR = tenantEscrowAuthorizationInfoService.queryAuthorizations();
            List<TenantEscrowAuthorizationInfoDto> authorizationInfoDtoList = listR.getData();
            if (!ObjectUtils.isEmpty(authorizationInfoDtoList)) {
                authorizationInfoDtoList.forEach(authorization -> {
                    tenantEscrowAuthorizationInfoReqs.forEach(req -> {
                        RRException.isNotTrue(StringUtils.isBlank(req.getTrustName()), RetCodeEnum.PARAM_ERROR.getCode(), "trustName不能为空!");
                        //模糊匹配trust_no
                        List<DataDictionaryTrustEntity> trustEntities = dataDictionaryTrustService.queryByLikeValue(req.getTrustName());
                        if (ObjectUtils.isEmpty(trustEntities) || trustEntities.size() > 1){
                            throw new RRException(RetCodeEnum.PARAM_ERROR.getCode(),"trustName无法匹配到唯一的托管人信息，请提供准确名称!");
                        }
                        req.setTrustNo(trustEntities.get(0).getTrustNo());
                        //判断新增授权信息是否已经存在
                        if (authorization.getContactPerson().equals(tenantInfoDto.getContactPerson()) && trustEntities.get(0).getTrustNo().equals(authorization.getTrustNo())) {
                            throw new RRException("授权失败！当前租户的账号下已存在对" + req.getTrustName() + "的授权，请联系运维人员查询授权内容!");
                        }
                    });
                });
            }
            return tenantEscrowAuthorizationInfoService.addEscrowAuthorizations(tenantName, tenantInfoDto, tenantEscrowAuthorizationInfoReqs);
        } catch (RRException rre) {
            log.error("新增授权信息已存在！");
            return R.error(rre.getMsg());
        } catch (Exception e) {
            log.error("授权失败！",e);
            return R.error("授权失败！");
        }
    }
}
