package io.renren.service.impl;

import java.math.BigDecimal;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import io.renren.common.constant.LLianPayConstant;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.HttpClientUtil;
import io.renren.common.vo.account.AcctInfoQueryResp;
import io.renren.common.vo.account.OpenacctApplyResult;
import io.renren.common.vo.user.UserInfoQueryResp;
import io.renren.dao.LAccountDao;
import io.renren.dao.LAccountDetailDao;
import io.renren.dao.LUserDao;
import io.renren.entity.LAccountDetailEntity;
import io.renren.entity.LAccountEntity;
import io.renren.entity.LUserEntity;
import io.renren.service.AccountService;
import io.renren.vo.AcctInfoQueryParams;
import io.renren.vo.OpenacctApplyParams;
import io.renren.vo.UserInfoQueryParams;
import lombok.extern.log4j.Log4j2;

@Log4j2
@Service
public class AccountServiceImpl implements AccountService {
	
	@Autowired
	private LLianPayConstant constant;
	
	@Autowired
	private LUserDao userDao;
	
	@Autowired
	private LAccountDao accountDao;
	
	@Autowired
	private LAccountDetailDao accountDetailDao;

	@Override
	public String openAccount(String userId) throws Exception {
		LUserEntity userEntity = userDao.selectOne(new QueryWrapper<LUserEntity>().eq("user_id", userId));
		if(null != userEntity) {
			throw new Exception("该用户已存在，无需再次开户");
		}
		log.info("企业用户开户申请");
		String timestamp = DateUtils.getTimestamp();
        OpenacctApplyParams params = new OpenacctApplyParams();
        params.setTimestamp(timestamp);
        params.setOid_partner(constant.getOidPartner());//  LLianPayConstant.OID_PARTNER
        params.setUser_id(userId);
        params.setTxn_seqno(String.valueOf(System.currentTimeMillis()));
        params.setTxn_time(timestamp);
        params.setFlag_chnl("H5");//交易发起渠道。目前只支持H5
        params.setReturn_url(constant.getReturnUrl());//交易完成回跳页面地址
        params.setNotify_url(constant.getNotifyUrl());//交易结果异步通知接收地址
        params.setUser_type("INNERCOMPANY");//用户类型(INNERUSER个人用户;INNERCOMPANY企业用户)

        String resultJsonStr = HttpClientUtil.sendRequest(constant.getOpenacctApply(), JSON.toJSONString(params),constant.getPrivateKey(),constant.getPublicKey());
        OpenacctApplyResult result = JSON.parseObject(resultJsonStr, OpenacctApplyResult.class);
        if(!LLianPayConstant.RET_CODE.equals(result.getRetCode())) {
        	throw new Exception("调用连连接【用户开户申请】接口失败："+result.getRetMsg());
        }
        
        userEntity = new LUserEntity();
		userEntity.setUserId(userId);
		BeanUtils.copyProperties(result, userEntity);
		userDao.insert(userEntity);
		
        return result.getGatewayUrl();
	}
	
	@Override
	public AcctInfoQueryResp queryAccount(String userId) throws Exception{
		LUserEntity userEntity = userDao.selectOne(new QueryWrapper<LUserEntity>().eq("user_id", userId));
		if(null == userEntity) {
			throw new Exception("该用户不存在");
		}
		
		AcctInfoQueryParams params = new AcctInfoQueryParams();
        params.setTimestamp(DateUtils.getTimestamp());
        params.setOid_partner(constant.getOidPartner());
        params.setUser_id(userId);
        params.setUser_type(userEntity.getUserType());
        String resultJsonStr = HttpClientUtil.sendRequest(constant.getQueryAcctinfo(), JSON.toJSONString(params),constant.getPrivateKey(),constant.getPublicKey());
        AcctInfoQueryResp result = JSON.parseObject(resultJsonStr, AcctInfoQueryResp.class);
        if(!LLianPayConstant.RET_CODE.equals(result.getRetCode())) {
        	throw new Exception("调用连连【查询账户信息】接口失败："+result.getRetMsg());
        }
        
    	BigDecimal amtBalcurTotal = BigDecimal.ZERO;//资金余额
    	BigDecimal amtBalavalTotal = BigDecimal.ZERO;//可用余额
    	BigDecimal amtBalfrzTotal = BigDecimal.ZERO;//冻结金额
        
        List<AcctInfoQueryResp.Acctinfo> acctinfoList = result.getAcctinfoList();
    	acctinfoList.forEach(info->{
    		amtBalcurTotal.add(info.getAmtBalcur());
    		amtBalavalTotal.add(info.getAmtBalaval());
    		amtBalfrzTotal.add(info.getAmtBalfrz());
    		
    		//查询账户明细列表，有就更新，没有就新增
    		LAccountDetailEntity accountDetail = accountDetailDao.selectOne(new QueryWrapper<LAccountDetailEntity>().lambda().eq(LAccountDetailEntity::getOidAcctno, info.getOidAcctno()));
    		if(null == accountDetail) {
    			accountDetail = new LAccountDetailEntity();
    			accountDetail.setUserId(userId);
    			BeanUtils.copyProperties(info, accountDetail);
    			accountDetailDao.insert(accountDetail);
    		}else {
    			BeanUtils.copyProperties(info, accountDetail);
    			accountDetailDao.updateById(accountDetail);
    		}
    	});
    	
    	LAccountEntity accountEntity = accountDao.selectOne(new QueryWrapper<LAccountEntity>().eq("user_id", userId));
    	if(null == accountEntity) {
    		accountEntity = new LAccountEntity();
    		BeanUtils.copyProperties(result, accountEntity);
    		accountDao.insert(accountEntity);
    	}else {
    		accountEntity.setAmtBalcur(amtBalcurTotal);
    		accountEntity.setAmtBalaval(amtBalavalTotal);
    		accountEntity.setAmtBalfrz(amtBalfrzTotal);
    		accountDao.updateById(accountEntity);
    	}
		return result;
	}

	@Override
	public UserInfoQueryResp queryUserinfo(String userId) throws Exception {
		UserInfoQueryParams params = new UserInfoQueryParams();
        params.setTimestamp(DateUtils.getTimestamp());
        params.setOid_partner(constant.getOidPartner());
        params.setUser_id(userId);

        String resultJsonStr = HttpClientUtil.sendRequest(constant.getQueryUserinfo(), JSON.toJSONString(params),constant.getPrivateKey(),constant.getPublicKey());
        UserInfoQueryResp result = JSON.parseObject(resultJsonStr, UserInfoQueryResp.class);
        if(!LLianPayConstant.RET_CODE.equals(result.getRetCode())) {
        	throw new Exception("调用连连【查询用户信息】接口失败："+result.getRetMsg());
        }
        LUserEntity userEntity = userDao.selectOne(new QueryWrapper<LUserEntity>().lambda().eq(LUserEntity::getUserId, userId));
        BeanUtils.copyProperties(result, userEntity);
        userDao.updateById(userEntity);
        return result;
	}

}