package com.ruoyi.bst.account.service.impl;

import com.github.pagehelper.PageHelper;
import com.ruoyi.bst.account.domain.Account;
import com.ruoyi.bst.account.domain.AccountQuery;
import com.ruoyi.bst.account.domain.AccountVO;
import com.ruoyi.bst.account.domain.enums.AccountType;
import com.ruoyi.bst.account.mapper.AccountMapper;
import com.ruoyi.bst.account.service.AccountService;
import com.ruoyi.bst.account.service.AccountValidator;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.common.valid.bank.BankCardInfo;
import com.ruoyi.common.valid.bank.BankValidUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Collections;
import java.util.List;

/**
 * 收款账户Service业务层处理
 *
 * @author ruoyi
 * @date 2025-04-07
 */
@Service
public class AccountServiceImpl implements AccountService
{
    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private AccountValidator accountValidator;

    @Autowired
    private TransactionTemplate transactionTemplate;

    /**
     * 查询收款账户
     *
     * @param id 收款账户主键
     * @return 收款账户
     */
    @Override
    public AccountVO selectAccountById(Long id, boolean scope)
    {
        if (id == null) {
            return null;
        }
        AccountQuery query = new AccountQuery();
        query.setId(id);
        query.setScope(scope);
        return this.selectOne(query);
    }

    private AccountVO selectOne(AccountQuery query) {
        PageHelper.startPage(1, 1);
        List<AccountVO> list = this.selectAccountList(query);
        return CollectionUtils.firstElement(list);
    }

    /**
     * 查询收款账户列表
     *
     * @param account 收款账户
     * @return 收款账户
     */
    @Override
    public List<AccountVO> selectAccountList(AccountQuery account)
    {
        return accountMapper.selectAccountList(account);
    }

    /**
     * 新增收款账户
     *
     * @param account 收款账户
     * @return 结果
     */
    @Override
    public int insertAccount(Account account)
    {
        account.setCreateTime(DateUtils.getNowDate());

        // 银行卡三要素校验
        this.setBankInfo(account);

        Integer result = transactionTemplate.execute(status -> {
            int rows = accountMapper.insertAccount(account);

            if (rows > 0) {
                // 后校验
                accountValidator.validate(account.getId());
            }

            return rows;
        });
        return result == null ? 0 : result;
    }

    private void setBankInfo(Account account) {
        if (account != null && AccountType.BANK.getCode().equals(account.getType())) {
            // 银行卡三要素校验，并获取卡面信息
            ServiceUtil.assertion(StringUtils.isAnyBlank(account.getNo(), account.getName(), account.getIdCard()), "银行卡、姓名或身份证存在空值");
            BankCardInfo bankCardInfo = BankValidUtils.valid3Bank(account.getNo(), account.getName(), account.getIdCard());
            ServiceUtil.assertion(bankCardInfo == null, "银行卡三要素校验失败");
            account.setBankCardName(bankCardInfo.getBankName());
            account.setBankType(bankCardInfo.getType());
            account.setBankIcon(bankCardInfo.getIcon());
            account.setBankCardName(bankCardInfo.getCardName());
        }
    }

    /**
     * 修改收款账户
     *
     * @param account 收款账户
     * @return 结果
     */
    @Override
    public int updateAccount(Account account)
    {
        // 银行卡三要素校验
        this.setBankInfo(account);

        Integer result = transactionTemplate.execute(status -> {
            int rows = accountMapper.updateAccount(account);
            if (rows > 0) {
                accountValidator.validate(account.getId());
            }
            return rows;
        });
        return result == null ? 0 : result;
    }

    /**
     * 逻辑删除收款账户
     *
     * @param ids 需要删除的收款账户主键集合
     * @return 结果
     */
    @Override
    public int logicDel(List<Long> ids) {
        return accountMapper.logicDel(ids);
    }

    @Override
    public List<AccountVO> selectAccountListByIds(List<Long> ids, boolean scope) {
        if (CollectionUtils.isEmptyElement(ids)) {
            return Collections.emptyList();
        }
        AccountQuery query = new AccountQuery();
        query.setIds(ids);
        query.setScope(scope);
        return accountMapper.selectAccountList(query);
    }
}
