package com.sonic.lion.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sonic.lion.dao.PayAccountFundThirdDao;
import com.sonic.lion.dao.PayAccountThirdBindDao;
import com.sonic.lion.domain.entity.PayAccountFundThird;
import com.sonic.lion.domain.entity.PayAccountThirdBind;
import com.sonic.lion.domain.enums.UserThirdStatus;
import com.sonic.lion.domain.input.AccountGenerateInput;
import com.sonic.lion.domain.input.BindBankCardInput;
import com.sonic.lion.domain.input.ChannelBindBankCardInput;
import com.sonic.lion.domain.input.ChannelCreateCustomerInput;
import com.sonic.lion.domain.output.ChannelBindBankCardOutput;
import com.sonic.lion.domain.output.ChannelCreateCustomerOutput;
import com.sonic.lion.domain.output.CreateBeneficiaryOutput;
import com.sonic.lion.enums.BindDataType;
import com.sonic.lion.enums.PayChannel;
import com.sonic.lion.enums.ThirdAccountType;
import com.sonic.lion.service.PayAccountFundThirdService;
import com.sonic.lion.service.PayCallChannelService;
import com.sonic.sdk.api.utils.AesEncodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

/**
 * @author: code
 * @date: 2025/05/12
 * @Description:
 * @version: 1.0.0
 */
@Slf4j
@Service
public class PayAccountFundThirdServiceImpl implements PayAccountFundThirdService {

    @Autowired
    private PayCallChannelService payCallChannelService;

    @Autowired
    private PayAccountFundThirdDao payAccountFundThirdDao;

    @Autowired
    private PayAccountThirdBindDao payAccountThirdBindDao;

    public static final String SECRET_KEY = "a3580eb6999ebf2e07ba45237c0de889";

    @Override
    public PayAccountFundThird getByAccountIdAndAppType(Long accountId, ThirdAccountType thirdAccountType) {
        if (accountId == null || thirdAccountType == null) {
            return null;
        }
        LambdaQueryWrapper<PayAccountFundThird> queryWrapper = Wrappers.<PayAccountFundThird>lambdaQuery()
                .eq(PayAccountFundThird::getAccountId, accountId)
                .eq(PayAccountFundThird::getAppType, thirdAccountType)
                .orderByDesc(PayAccountFundThird::getId).last(" limit 1");
        return payAccountFundThirdDao.selectOne(queryWrapper);
    }

    @Override
    public Long getAccountIdByOpenId(String openId, ThirdAccountType thirdAccountType) {
        if (StringUtils.isBlank(openId) || thirdAccountType == null) {
            return null;
        }
        LambdaQueryWrapper<PayAccountFundThird> queryWrapper = Wrappers.<PayAccountFundThird>lambdaQuery()
                .eq(PayAccountFundThird::getOpenId, openId)
                .eq(PayAccountFundThird::getAppType, thirdAccountType)
                .orderByDesc(PayAccountFundThird::getId).last(" limit 1");
        PayAccountFundThird payAccountFundThird = payAccountFundThirdDao.selectOne(queryWrapper);
        if (payAccountFundThird == null) {
            return null;
        }
        return payAccountFundThird.getAccountId();
    }

    @Override
    public void generate(@NonNull AccountGenerateInput input) {
        ChannelCreateCustomerInput channelCreateCustomerInput = ChannelCreateCustomerInput.builder()
                .accountFundId(input.getAccountFundId())
                .addressLine1(input.getAddressLine1())
                .city(input.getCity())
                .country(input.getCountry())
                .email(input.getEmail())
                .firstName(input.getFirstName())
                .lastName(input.getLastName())
                .middleName(input.getMiddleName())
                .payChannel(input.getPayChannel())
                .postalCode(input.getPostalCode())
                .stateProvince(input.getStateProvince())
                .build();
        ChannelCreateCustomerOutput channelCreateCustomerOutput = payCallChannelService.callCreateCustomer(channelCreateCustomerInput);
        String name = getName(input.getFirstName(), input.getMiddleName(), input.getLastName());
        PayAccountFundThird payAccountFundThird = PayAccountFundThird.builder()
                .accountId(input.getUid())
                .accountFundId(input.getAccountFundId())
                .appType(ThirdAccountType.getWithdrawAccount(input.getPayChannel()))
                .channelId(input.getPayChannel())
                .openId(channelCreateCustomerOutput.getOpenId())
                .status(UserThirdStatus.ENABLED)
                .email(input.getEmail())
                .name(name)
                .extend(channelCreateCustomerOutput.getResult())
                .build();
        payAccountFundThirdDao.insert(payAccountFundThird);
    }

    @Override
    public void bindBankCard(@NonNull BindBankCardInput input) {

        PayAccountFundThird payAccountFundThird = getByAccountIdAndAppType(input.getUid(), ThirdAccountType.getWithdrawAccount(input.getPayChannel()));

        //将银行卡绑定到渠道
        ChannelBindBankCardInput channelBindBankCardInput = ChannelBindBankCardInput.builder()
                .thirdAccountOpenId(payAccountFundThird.getOpenId())
                .payChannel(input.getPayChannel())
                .cardNumber(input.getCardNumber())
                .cvv(input.getCvv())
                .dateOfExpiry(input.getDateOfExpiry())
                .build();
        ChannelBindBankCardOutput channelBindBankCardOutput = payCallChannelService.callBindBankCard(channelBindBankCardInput);

        //保存渠道openId和绑定关系
        PayAccountThirdBind payAccountThirdBind = PayAccountThirdBind.builder()
                .accountThirdId(payAccountFundThird.getId())
                .bindDataType(BindDataType.BANK_CARD)
                .thirdOpenId(channelBindBankCardOutput.getOpenId())
                .result(channelBindBankCardOutput.getResult())
                .build();
        payAccountThirdBindDao.insert(payAccountThirdBind);
    }

    @Override
    public PayAccountFundThird bindStripe(Long uid, String customerId) {
        PayAccountFundThird third = PayAccountFundThird.builder()
                .accountId(uid)
                .channelId(PayChannel.STRIPE)
                .appType(ThirdAccountType.STRIPE_PAYMENT)
                .openId(customerId)
                .name(uid.toString())
                .email(null)
                //加密存储 (付款方式、国家、货币类型、银行卡号 等)
                .status(UserThirdStatus.ENABLED)
                .build();
        payAccountFundThirdDao.insert(third);
        return third;
    }


    private String getName(String firstName, String middleName, String lastName) {
        if (StringUtils.isBlank(middleName)) {
            return firstName + " " + lastName;
        } else {
            return firstName + " " + middleName + " " + lastName;
        }
    }


    public static void main(String[] args) throws Exception {
        CreateBeneficiaryOutput output = new CreateBeneficiaryOutput();
        output.setBeneficiaryId("bf40c0c2-c064-4798-a6a0-ec4125f58a35");
        output.setBankName("GOLDMAN SACHS BANK USA (FORMERLY THE GOLDMAN SACHS TRUST COMPANY)");
        output.setLocalClearingSystem("ACH");
        output.setBankCountryCode("US");
        output.setAccountNumber("555552455");
        output.setAccountCurrency("USD");
        output.setAccountName("ttt");
        String abc = AesEncodeUtil.encrypt(JSONObject.toJSONString(output), SECRET_KEY);
        System.out.println(abc);
    }

}
