package com.lanyuanxiaoyao.leopard.server.service.task;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
import com.lanyuanxiaoyao.leopard.server.service.TaskService;
import com.lanyuanxiaoyao.leopard.server.service.TuShareService;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@LiteflowComponent("check_daily")
public class CheckDailyNode extends TaskNodeComponent {
  private final StockRepository stockRepository;
  private final DailyRepository dailyRepository;

  private final TuShareService tuShareService;

  public CheckDailyNode(TaskService taskService, StockRepository stockRepository, DailyRepository dailyRepository, TuShareService tuShareService) {
    super(taskService);
    this.stockRepository = stockRepository;
    this.dailyRepository = dailyRepository;
    this.tuShareService = tuShareService;
  }

  @Override
  public void process() {
    var reports = new ArrayList<MissedTradeReport>();
    var stocks = stockRepository.findAll();
    var exchanges = stocks.stream().map(Stock::getMarket).distinct().toList();
    for (Stock.Market exchange : exchanges) {
      var nowDate = LocalDate.now();
      var allTradeDates = tuShareService.tradeDateList(exchange.name())
        .data()
        .items()
        .stream()
        .map(item -> LocalDate.parse(item.getFirst(), TuShareService.TRADE_FORMAT))
        .filter(date -> date.isBefore(nowDate) || date.isEqual(nowDate))
        .toList();
      var total = stocks.size();
      var progress = 0;
      for (Stock stock : stocks) {
        log.info("正在处理：{} {}", stock.getCode(), stock.getName());
        if (exchange.equals(stock.getMarket())) {
          var existsTradeDates = dailyRepository.findDistinctTradeDateByStockId(stock.getId());
          var missedTradeDates = allTradeDates.stream()
            .filter(date -> date.isAfter(stock.getListedDate()) || date.isEqual(stock.getListedDate()))
            .filter(date -> !existsTradeDates.contains(date))
            .filter(date -> {
              ThreadUtil.safeSleep(100);
              var response = tuShareService.dailyList(date, stock.getCode());
              return !response.data().items().isEmpty();
            })
            .toList();
          if (ObjectUtil.isNotEmpty(missedTradeDates)) {
            reports.add(new MissedTradeReport(
              stock.getCode(),
              stock.getName(),
              missedTradeDates
            ));
          }
        }
        setStep(++progress * 100 / total);
      }
    }
    if (ObjectUtil.isNotEmpty(reports)) {
      var context = getContextBean(TaskMonitorNodes.TaskMonitorContext.class);
      context.setTaskResult(
        reports.stream()
          .map(report -> StrUtil.format("{}（{}）缺少如下交易日数据：{}", report.name(), report.code(), report.missedTradeDates().stream().map(LocalDate::toString).collect(Collectors.joining(", "))))
          .collect(Collectors.joining("\n"))
      );
    }
  }

  public record MissedTradeReport(
    String code,
    String name,
    List<LocalDate> missedTradeDates
  ) {
  }
}
