package com.sonic.lion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sonic.lion.dao.AccountBuffAwaitingDao;
import com.sonic.lion.domain.entity.AccountBuffAwaiting;
import com.sonic.lion.service.AccountBuffAwaitingService;
import com.sonic.lion.enums.ToastResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author: code
 * @date: 2025/07/17
 * @Description:
 * @version: 1.0.0
 */
@Service
public class AccountBuffAwaitingServiceImpl implements AccountBuffAwaitingService {

    @Autowired
    private AccountBuffAwaitingDao accountBuffAwaitingDao;


    @Transactional
    @Override
    public void save(@NonNull AccountBuffAwaiting accountBuffAwaiting) {
        accountBuffAwaitingDao.insert(accountBuffAwaiting);
    }

    @Override
    public List<AccountBuffAwaiting> listWillToIncome(Integer num) {
        LambdaQueryWrapper<AccountBuffAwaiting> queryWrapper = Wrappers.<AccountBuffAwaiting>lambdaQuery()
                .eq(AccountBuffAwaiting::getStatus, AccountBuffAwaiting.Status.PENDING)
                .eq(AccountBuffAwaiting::getFronzenStatus, AccountBuffAwaiting.FronzenStatus.UN_FRONZEN)
                .gt(AccountBuffAwaiting::getToWithdrawableIncomeTime, LocalDateTime.now().plusDays(-3))
                .lt(AccountBuffAwaiting::getToWithdrawableIncomeTime, LocalDateTime.now()).last(" limit " + num);
        return accountBuffAwaitingDao.selectList(queryWrapper);
    }

    @Override
    public AccountBuffAwaiting getByTradeNo(String tradeNo) {
        if (tradeNo == null) {
            return null;
        }
        LambdaQueryWrapper<AccountBuffAwaiting> queryWrapper = Wrappers.<AccountBuffAwaiting>lambdaQuery()
                .eq(AccountBuffAwaiting::getTradeNo, tradeNo);
        return accountBuffAwaitingDao.selectOne(queryWrapper);
    }

    /**
     * 查询待入账状态的 数据
     *
     * @param tradeNo
     * @return
     */
    @Override
    public List<AccountBuffAwaiting> getListByTradeNo(String tradeNo) {
        if (tradeNo == null) {
            return null;
        }
        LambdaQueryWrapper<AccountBuffAwaiting> queryWrapper = Wrappers.<AccountBuffAwaiting>lambdaQuery()
                .eq(AccountBuffAwaiting::getStatus, AccountBuffAwaiting.Status.PENDING)
                .eq(AccountBuffAwaiting::getTradeNo, tradeNo);
        return accountBuffAwaitingDao.selectList(queryWrapper);
    }

    @Transactional
    @Override
    public void updateStatus(@NonNull Long id, @NonNull AccountBuffAwaiting.Status status, AccountBuffAwaiting.Status expectStatus) {
        LambdaUpdateWrapper<AccountBuffAwaiting> updateWrapper = Wrappers.<AccountBuffAwaiting>lambdaUpdate()
                .eq(AccountBuffAwaiting::getId, id);

        if (expectStatus != null) {
            updateWrapper.ge(AccountBuffAwaiting::getStatus, expectStatus);
        }

        AccountBuffAwaiting updater = AccountBuffAwaiting.builder()
                .status(status)
                .build();
        int n = accountBuffAwaitingDao.update(updater, updateWrapper);
        ToastResultCode.PAY_TRADE_STATUS_CHANGE.check(n != 1);
    }

    @Transactional
    @Override
    public void updateAwaitingBuff(Long id, Long awaitingBuff, AccountBuffAwaiting.Status expectStatus) {
        LambdaUpdateWrapper<AccountBuffAwaiting> updateWrapper = Wrappers.<AccountBuffAwaiting>lambdaUpdate()
                .eq(AccountBuffAwaiting::getId, id);

        if (expectStatus != null) {
            updateWrapper.ge(AccountBuffAwaiting::getStatus, expectStatus);
        }

        AccountBuffAwaiting updater = AccountBuffAwaiting.builder()
                .buff(awaitingBuff)
                .build();
        int n = accountBuffAwaitingDao.update(updater, updateWrapper);
        ToastResultCode.PAY_TRADE_STATUS_CHANGE.check(n != 1);
    }

    /**
     * 冻结
     *
     * @param tradeNoList
     */
    @Transactional
    @Override
    public void fronzenBuffAwaiting(List<String> tradeNoList) {
        LambdaUpdateWrapper<AccountBuffAwaiting> updateWrapper = Wrappers.<AccountBuffAwaiting>lambdaUpdate()
                .in(!CollectionUtils.isEmpty(tradeNoList), AccountBuffAwaiting::getTradeNo, tradeNoList)
                .eq(AccountBuffAwaiting::getFronzenStatus, AccountBuffAwaiting.FronzenStatus.UN_FRONZEN);
        AccountBuffAwaiting updater = AccountBuffAwaiting.builder()
                .fronzenStatus(AccountBuffAwaiting.FronzenStatus.FRONZEN)
                .build();
        int n = accountBuffAwaitingDao.update(updater, updateWrapper);
    }

    /**
     * 解冻
     *
     * @param tradeNoList
     */
    @Transactional
    @Override
    public void unFronzenBuffAwaiting(List<String> tradeNoList) {
        LambdaUpdateWrapper<AccountBuffAwaiting> updateWrapper = Wrappers.<AccountBuffAwaiting>lambdaUpdate()
                .in(!CollectionUtils.isEmpty(tradeNoList), AccountBuffAwaiting::getTradeNo, tradeNoList)
                .eq(AccountBuffAwaiting::getFronzenStatus, AccountBuffAwaiting.FronzenStatus.FRONZEN);
        AccountBuffAwaiting updater = AccountBuffAwaiting.builder()
                .fronzenStatus(AccountBuffAwaiting.FronzenStatus.UN_FRONZEN)
                .build();
        int n = accountBuffAwaitingDao.update(updater, updateWrapper);
    }

    @Transactional
    @Override
    public boolean deleteById(Long id) {
        return accountBuffAwaitingDao.deleteById(id) > 0;
    }


    @Transactional
    @Override
    public int updateOldData() {
        return accountBuffAwaitingDao.updateOldData();
    }

    @Override
    public int countMerchantSubscribeAwaitingIncome(String tradeNo,Long accountId) {
        return accountBuffAwaitingDao.selectCount(Wrappers.<AccountBuffAwaiting>lambdaQuery()
                .eq(AccountBuffAwaiting::getTradeNo, tradeNo)
                .eq(AccountBuffAwaiting::getAccountId, accountId)
                .eq(AccountBuffAwaiting::getStatus, AccountBuffAwaiting.Status.PENDING)
        );
    }
}
