package com.jeequan.jeepay.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.domain.BankcardExtInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.TransferOrder;
import com.jeequan.jeepay.core.entity.TransferSubject;
import com.jeequan.jeepay.core.model.tranfer.TransferBasicInfo;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.db.entity.TransferOrderEntity;
import com.jeequan.jeepay.db.entity.TransferSubjectEntity;
import com.jeequan.jeepay.service.mapper.TransferSubjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.jeequan.jeepay.core.utils.DateKit.getBegin;
import static com.jeequan.jeepay.core.utils.DateKit.getEnd;

/**
 * <p>
 * 转账对象表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2024-04-25
 */
@Service
public class TransferSubjectService extends ServiceImpl<TransferSubjectMapper, TransferSubjectEntity> {

    @Autowired
    private TransferSubjectMapper transferSubjectMapper;

    @Autowired
    private TransferOrderService transferOrderService;

    public TransferSubjectEntity getByApplyId(String transApplyId) {
        return lambdaQuery().eq(TransferSubjectEntity::getTransApplyId, transApplyId).one();
    }

    public IPage<TransferSubjectEntity> getPageList(IPage<TransferSubjectEntity> iPage, TransferSubjectEntity transferSubject) {
        IPage<TransferSubjectEntity> pageList = transferSubjectMapper.getPageList(iPage, transferSubject);

        if (ObjUtil.isEmpty(pageList.getRecords())) {
            return pageList;
        }

        List<String> transferSubjectIds = pageList.getRecords().stream()
                .map(TransferSubjectEntity::getId)
                .collect(Collectors.toList());

        //获取最新每日下放剩余总额度   总额度-订单生成金额-转账中金额-转账成功金额
        Date nowDateTime = new Date();  //当前时间
        Date[] dates = {getBegin(nowDateTime), getEnd(nowDateTime)};

//        // 查询所有收款方金额总数和笔数
//        List<TransferOrderEntity> transferOrderList = transferOrderService.lambdaQuery()
//                .in(TransferOrderEntity::getTransferSubjectIdJs, transferSubjectIds)
//                .eq(TransferOrderEntity::getState, TransferOrder.STATE_SUCCESS)
//                .list();
//
//        // 查询所有今日数据
//        List<TransferOrderEntity> todayTransferOrderList = transferOrderService.list(
//                TransferOrderEntity.gw()
//                        .in(TransferOrderEntity::getTransferSubjectIdFq, transferSubjectIds)
//                        .in(TransferOrderEntity::getState, TransferOrderEntity.STATE_INIT, TransferOrderEntity.STATE_ING, TransferOrderEntity.STATE_SUCCESS)
//                        .ge(TransferOrderEntity::getCreatedAt, dates[0])
//                        .le(TransferOrderEntity::getCreatedAt, dates[1])
//        );

        for (TransferSubjectEntity record : pageList.getRecords()) {
            //获取收款方金额总数和笔数
            List<TransferOrderEntity> transferOrderList = transferOrderService.list(
                    TransferOrderEntity.gw().eq(TransferOrderEntity::getTransferSubjectIdJs, record.getId())
                            .eq(TransferOrderEntity::getState, TransferOrder.STATE_SUCCESS));
            if (!transferOrderList.isEmpty()) {
                record.setAmountNumber(transferOrderList.size());
                long sumAmount = transferOrderList.stream()
                        .mapToLong(TransferOrderEntity::getAmount)
                        .sum();
                String amount = AmountUtil.convertCent2Dollar(sumAmount);
                record.setTotalAmount(amount);
            }

            //当日数据不为空
            List<TransferOrderEntity> todayTransferOrderList = transferOrderService.list(TransferOrderEntity.gw()
                    .eq(TransferOrderEntity::getTransferSubjectIdFq, record.getId())
                    .in(TransferOrderEntity::getState, TransferOrderEntity.STATE_INIT, TransferOrderEntity.STATE_ING, TransferOrderEntity.STATE_SUCCESS)
                    .ge(TransferOrderEntity::getCreatedAt, dates[0])
                    .le(TransferOrderEntity::getCreatedAt, dates[1]));
            if (!todayTransferOrderList.isEmpty()) {
                if (record.getZfbDayMax() != null) {
                    //获取今日支付宝总交易金额
                    long totalAmountZfb = todayTransferOrderList.stream()
                            .filter(order -> TransferOrder.ENTRY_ALIPAY_CASH.equals(order.getEntryType()))
                            .mapToLong(TransferOrderEntity::getAmount)
                            .sum();
                    //只展示
                    record.setZfbDayMax(record.getZfbDayMax() - totalAmountZfb);
                }
                if (record.getBankCardDayMax() != null) {
                    //获取今日银行卡总交易金额
                    long totalAmountBank = todayTransferOrderList.stream()
                            .filter(order -> TransferOrder.ENTRY_BANK_CARD.equals(order.getEntryType()))
                            .mapToLong(TransferOrderEntity::getAmount)
                            .sum();
                    //只展示
                    record.setBankCardDayMax(record.getBankCardDayMax() - totalAmountBank);
                }
            }
        }

        return pageList;
    }

    /**
     * 获取现有的接收方数据
     *
     * @param isvNo       渠道号
     * @param transIfCode 通道编码
     * @param infoType    用户类型， MCH、AGENT
     * @param infoId      用户ID,   mchNo, agentNo
     * @param accountNo   账号
     * @param entryType   账号渠道
     * @param accountType 账号类型
     * @return
     */
    public TransferSubjectEntity getReceiver(String isvNo, String transIfCode, String infoType, String infoId, String accountNo, String entryType, String accountType) {
        return lambdaQuery().eq(TransferSubjectEntity::getTransIfCode, transIfCode)
                .eq(TransferSubjectEntity::getIsvNo, isvNo)
                .eq(TransferSubjectEntity::getInfoType, infoType)
                .eq(CS.SYS_ROLE_TYPE.MCH.equals(infoType), TransferSubjectEntity::getMchNo, infoId)
                .eq(CS.SYS_ROLE_TYPE.AGENT.equals(infoType), TransferSubjectEntity::getAgentNo, infoId)
                .eq(TransferSubjectEntity::getAccount, SysConfigService.DB_ENCRYPT_SM4.encryptBase64(accountNo))
                .eq(accountType != null, TransferSubjectEntity::getAccountType, accountType)
                .eq(entryType != null, TransferSubjectEntity::getAccountType, entryType)
                .one();
    }

    public TransferSubjectEntity getReceiverSaveIfNotExist(String accountNo, String accountName,
                                                           String entryType, String accountType,
                                                           TransferSubjectEntity sponsor, BankcardExtInfo bankInfo) {
        // Encrypt the account number
        String encryptedAccountNo = SysConfigService.DB_ENCRYPT_SM4.encryptBase64(accountNo);

        // Query for existing receiver
        TransferSubjectEntity existData = lambdaQuery()
                .eq(TransferSubjectEntity::getTransIfCode, sponsor.getTransIfCode())
                .eq(TransferSubjectEntity::getIsvNo, sponsor.getIsvNo())
                .eq(TransferSubjectEntity::getInfoType, sponsor.getInfoType())
                .eq(CS.SYS_ROLE_TYPE.MCH.equals(sponsor.getInfoType()), TransferSubjectEntity::getMchNo, sponsor.getMchNo())
                .eq(CS.SYS_ROLE_TYPE.AGENT.equals(sponsor.getInfoType()), TransferSubjectEntity::getAgentNo, sponsor.getAgentNo())
                .eq(TransferSubjectEntity::getAccount, encryptedAccountNo)
                .eq(accountType != null, TransferSubjectEntity::getAccountType, accountType)
                .eq(entryType != null, TransferSubjectEntity::getEntryType, entryType)
                .last("limit 1")
                .one();

        TransferSubjectEntity receiver = new TransferSubjectEntity();
        if (existData != null) {
            receiver.setId(existData.getId());
        } else {
            receiver.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
        }

        receiver.setAccount(accountNo); // Save encrypted account
        receiver.setState(TransferSubject.STATE_ENABLE);
        receiver.setSubjectType(TransferSubject.SUBJECT_TYPE_RECEIVER);
        receiver.setIsvNo(sponsor.getIsvNo());
        receiver.setInfoType(sponsor.getInfoType());
        receiver.setMchNo(CS.SYS_ROLE_TYPE.MCH.equals(sponsor.getInfoType()) ? sponsor.getMchNo() : null);
        receiver.setAgentNo(sponsor.getAgentNo());
        receiver.setAgentName(sponsor.getAgentName());
        receiver.setTopAgentNo(sponsor.getTopAgentNo());
        receiver.setTransIfCode(sponsor.getTransIfCode());
        receiver.setSignState(sponsor.getSignState());
        receiver.setAccountName(accountName);
        receiver.setAccountType(accountType);
        receiver.setEntryType(entryType);

        // If the entry type is bank, save additional bank information
        if (TransferBasicInfo.ENTRY_TYPE_BANK.equalsIgnoreCase(entryType)) {
            receiver.setAccountMessage(JSON.toJSONString(bankInfo));
        }

        saveOrUpdate(receiver);

        return receiver;
    }

    /**
     * 统计收款账户总成交金额和总成交笔数
     */
    public Map<String, Object> getSubStatistics(TransferSubjectEntity transferSubject) {
        return transferSubjectMapper.getSubStatistics(transferSubject);
    }
}
