package com.izouma.nineth.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.AdapayCommon;
import com.huifu.adapay.model.SettleAccount;
import com.izouma.nineth.config.AdapayProperties;
import com.izouma.nineth.dto.Balance;
import com.izouma.nineth.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@AllArgsConstructor
@Service
@Slf4j
public class AdapayService {

    private final AdapayProperties adapayProperties;

    public String createMember(Long id, String tel, String name, String idNo) throws BaseAdaPayException {
        Map<String, Object> memberParams = new HashMap<>();
        memberParams.put("adapay_func_code", "members.realname");
        memberParams.put("member_id", id.toString());
        memberParams.put("app_id", adapayProperties.getAppId());
        memberParams.put("tel_no", tel);
        memberParams.put("user_name", name);
        memberParams.put("cert_type", "00");
        memberParams.put("cert_id", idNo);
        Map<String, Object> member = AdapayCommon.requestAdapay(memberParams);
        log.info("createMember\n{}", JSON.toJSONString(member, SerializerFeature.PrettyFormat));
        checkSuccess(member);
        return MapUtils.getString(member, "member_id");
    }

    public String createSettleAccount(String memberId, String realName, String idNo, String phone, String bankNo) throws BaseAdaPayException {
        Map<String, Object> settleCountParams = new HashMap<>();
        Map<String, Object> accountInfo = new HashMap<>();
        accountInfo.put("card_id", bankNo);
        accountInfo.put("card_name", realName);
        accountInfo.put("cert_id", idNo);
        accountInfo.put("cert_type", "00");
        accountInfo.put("tel_no", phone);
        accountInfo.put("bank_acct_type", "2");
        settleCountParams.put("member_id", memberId);
        settleCountParams.put("app_id", adapayProperties.getAppId());
        settleCountParams.put("channel", "bank_account");
        settleCountParams.put("account_info", accountInfo);
        Map<String, Object> settleCount = SettleAccount.create(settleCountParams);
        log.info("createSettleAccount\n{}", JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat));
        checkSuccess(settleCount);
        return MapUtils.getString(settleCount, "id");
    }

    public void delSettleAccount(String memberId, String accountId) throws BaseAdaPayException {
        Map<String, Object> settleCountParams = new HashMap<>();
        settleCountParams.put("settle_account_id", accountId);
        settleCountParams.put("member_id", memberId);
        settleCountParams.put("app_id", adapayProperties.getAppId());
        Map<String, Object> settleCount = SettleAccount.delete(settleCountParams);
        log.info("delSettleAccount\n{}", JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat));
        checkSuccess(settleCount);
    }

    public Balance queryBalance(String memberId, String settleAccountId) throws BaseAdaPayException {
        Map<String, Object> queryParams = new HashMap<>();
        queryParams.put("settle_account_id", settleAccountId);
        queryParams.put("member_id", memberId);
        queryParams.put("app_id", adapayProperties.getAppId());
        Map<String, Object> settleCount = SettleAccount.balance(queryParams);
        String json = JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat);
        log.info("queryBalance\n{}", JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat));
        checkSuccess(settleCount);
        return JSON.parseObject(json, Balance.class);
    }

    public static void checkSuccess(Map<String, Object> map) {
        if (!"succeeded".equals(MapUtils.getString(map, "status"))) {
            String errMsg = MapUtils.getString(map, "error_msg");
            String errCode = MapUtils.getString(map, "error_code");
            throw new BusinessException(errMsg + "(" + errCode + ")");
        }
    }
}
