package com.m2pool.manage.task;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.m2pool.common.core.utils.DateUtils;
import com.m2pool.manage.entity.ManageWalletOutIn;
import com.m2pool.manage.mapper.ManageBroadcastMapper;
import com.m2pool.manage.mapper.ManageWalletOutInMapper;
import com.m2pool.manage.service.ManageWalletOutInService;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description 后台管理系统 定时任务
 * @Date 2025/7/15 15:45
 * @Author yyb
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "task.manage")
@EnableScheduling
public class ManageTask {
    private boolean enable;

    @Resource
    private ManageWalletOutInService manageWalletOutInService;

    @Resource
    private ManageWalletOutInMapper manageWalletOutInMapper;

    @Resource
    private ManageBroadcastMapper manageBroadcastMapper;
    /**
     * 存储交易记录定时任务
     */
    @Scheduled(cron = "22 51 0/1 * * ?")
    //@Scheduled(cron = "0 0/1 * * * ?")
    @DSTransactional
    public void insertDataToWalletOutInDb(){
        LocalDateTime maxDateData = manageWalletOutInMapper.getMaxDateIn();
        List<ManageWalletOutIn> manageWalletOutIns = new ArrayList<>();
        if (maxDateData != null){
            maxDateData = maxDateData.toLocalDate().atStartOfDay().minusDays(10);
            //获取startDate 后的数据,用于比对
            manageWalletOutIns = manageWalletOutInMapper.selectList(new LambdaQueryWrapper<ManageWalletOutIn>()
                    .ge(ManageWalletOutIn::getShouldOutDate, maxDateData.toLocalDate().atStartOfDay())

            );
        }

        List<ManageWalletOutIn> walletIn = manageWalletOutInMapper.getWalletIn(maxDateData);
        List<ManageWalletOutIn> walletOut = manageWalletOutInMapper.getWalletOut(maxDateData);

        // 存储walletIn 和 walletOut交集
        List<ManageWalletOutIn> intersection = new ArrayList<>();
        // 存储 walletIn 的差集
        List<ManageWalletOutIn> inDifference = new ArrayList<>(walletIn);
        // 存储 walletOut 的差集
        List<ManageWalletOutIn> outDifference = new ArrayList<>(walletOut);
        // 用于标记 walletIn 中哪些元素在 walletOut 中找到了匹配
        Set<ManageWalletOutIn> matchedInItems = new HashSet<>();

        for (ManageWalletOutIn in : walletIn) {
            for (ManageWalletOutIn out : walletOut) {
                //日期
                LocalDateTime dateIn = in.getShouldOutDate().toLocalDate().atStartOfDay();
                LocalDateTime dateOut = out.getShouldOutDate().toLocalDate().atStartOfDay();
                //挖矿账户
                String userIn = in.getUser();
                String userOut = out.getUser();
                //币种
                String coinIn = in.getCoin();
                String coinOut = out.getCoin();
                //最大高度
                Integer maxHeightIn = in.getMaxHeight();
                Integer maxHeightOut = out.getMaxHeight();

                if (coinIn.equals(coinOut) && userIn.equals(userOut) &&
                        dateIn.equals(dateOut) && maxHeightIn.equals(maxHeightOut)) {
                    //找到交集元素后 in 中设置 out的独有的几个数据字段
                    in.setDateOut(out.getDateOut());
                    in.setTransferAmount(out.getTransferAmount());
                    in.setTxId(out.getTxId());
                    in.setAddress(out.getAddress());
                    // 找到交集元素
                    intersection.add(in);
                    //标记存在交集的in
                    matchedInItems.add(in);
                    //移除 walletOut 中已经在交集里的元素，得到差集
                    outDifference.remove(out);
                }

            }
        }

        // 移除 walletIn 中已经在交集里的元素，得到差集
        inDifference.removeAll(matchedInItems);

        List<ManageWalletOutIn> walletInfo = new ArrayList<>();
        walletInfo.addAll(intersection);
        walletInfo.addAll(inDifference);
        walletInfo.addAll(outDifference);
        System.out.println("交集数量: " + intersection.size());
        System.out.println("walletIn 差集数量: " + inDifference.size());
        System.out.println("walletOut 差集数量: " + outDifference.size());
        //查询ManageWalletOutIn 数据，比对是否修改
        if (!manageWalletOutIns.isEmpty()){
            List<ManageWalletOutIn> updateList = new ArrayList<>();
            List<ManageWalletOutIn> saveList = new ArrayList<>();

            for (ManageWalletOutIn item : walletInfo) {
                for (ManageWalletOutIn dbItem : manageWalletOutIns) {
                    if (dbItem.getCoin().equals(item.getCoin())
                            && dbItem.getUser().equals(item.getUser())
                            && dbItem.getMaxHeight().equals(item.getMaxHeight())
                            && dbItem.getShouldOutDate().toLocalDate().atStartOfDay().equals(item.getShouldOutDate().toLocalDate().atStartOfDay())) {
                        // 若找到匹配项，设置 id 并添加到 updateList
                        item.setId(dbItem.getId());
                        updateList.add(item);
                        break;
                    }
                }

                if (item.getId() == null) {
                    saveList.add(item);
                }
            }
            if (!updateList.isEmpty()){

                boolean update = manageWalletOutInService.updateBatchById(updateList);
                System.out.println("walletOutIn 修改"+updateList.size());
            }
            if (!saveList.isEmpty()){
                boolean save = manageWalletOutInService.saveBatch(saveList);
                    System.out.println("walletOutIn 新增"+saveList.size());
            }
        }else{
            boolean b = manageWalletOutInService.saveOrUpdateBatch(walletInfo);
            System.out.println("初始化walletOutIn数据"+b);
        }
    }


    /**
     * 删除再离线数据(保留一月数据)
     */
    @Scheduled(cron = "5 5 1 * * ?")
    public void deleteOnlineAndOfflineDataForNexa(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("nexa", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("nexa", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除nexa在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 2 * * ?")
    public void deleteOnlineAndOfflineDataForMona(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("mona", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("mona", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除mona在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 3 * * ?")
    public void deleteOnlineAndOfflineDataForRxd(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("rxd", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("rxd", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除rxd在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 4 * * ?")
    public void deleteOnlineAndOfflineDataForGrs(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("grs", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("grs", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除Grs在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 5 * * ?")
    public void deleteOnlineAndOfflineDataForEnx(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("enx", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("enx", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除enx在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 6 * * ?")
    public void deleteOnlineAndOfflineDataForAlph(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("alph", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("alph", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除alph在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 7 * * ?")
    public void deleteOnlineAndOfflineDataForDgbo(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("dgbo", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("dgbo", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除dgbo在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 8 * * ?")
    public void deleteOnlineAndOfflineDataForDgbq(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("dgbq", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("dgbq", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除dgbq在离线时间: " + duration + " 毫秒");
    }

    @Scheduled(cron = "10 5 9 * * ?")
    public void deleteOnlineAndOfflineDataForDgbs(){
        if (!enable){
            return;
        }
        // 记录开始时间（纳秒）
        long startTime = System.nanoTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMonthAgo = now.minusMonths(1);
        int count = manageBroadcastMapper.selectNeedDeleteNumbers("dgbs", oneMonthAgo);
        while (count > 0) {
            int deletedCount = manageBroadcastMapper.deleteOnlineAndOfflineData("dgbs", oneMonthAgo);
            count -= deletedCount;
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime) / 1_000_000;
        System.out.println("删除dgbs在离线时间: " + duration + " 毫秒");
    }



}
