package com.lanyuanxiaoyao.leopard.core.task;

import cn.hutool.core.util.EnumUtil;
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
import com.lanyuanxiaoyao.leopard.core.service.TuShareService;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 更新股票信息
 *
 * @author lanyuanxiaoyao
 * @version 20250924
 */
@Component
public class UpdateStockTask extends TaskRunner {
  private final StockRepository stockRepository;

  private final TuShareService tuShareService;

  public UpdateStockTask(ApplicationContext context, StockRepository stockRepository, TuShareService tuShareService) {
    super(context);
    this.stockRepository = stockRepository;
    this.tuShareService = tuShareService;
  }

  @Transactional(rollbackFor = Throwable.class)
  @Override
  public String process(Map<String, Object> params, StepUpdater updater) {
    var existsStockMap = stockRepository.findAll().stream().collect(Collectors.toMap(Stock::getCode, stock -> stock));
    var stocks = tuShareService.stockList()
      .data()
      .items()
      .stream()
      .map(item -> {
        var code = item.get(0);
        var name = item.get(1);
        var fullname = item.get(2);
        var market = EnumUtil.fromString(Stock.Market.class, item.get(3));
        var industry = item.get(4);
        var listedDate = LocalDate.parse(item.get(5), TuShareService.TRADE_FORMAT);
        var stock = existsStockMap.getOrDefault(code, new Stock());
        stock.setCode(code);
        stock.setName(name);
        stock.setFullname(fullname);
        stock.setMarket(market);
        stock.setIndustry(industry);
        stock.setListedDate(listedDate);
        return stock;
      })
      .toList();
    var currentCodes = stocks.stream().map(Stock::getCode).toList();
    var existsCodes = stockRepository.findDistinctCodes();
    var deleteCodes = existsCodes.stream().filter(code -> !currentCodes.contains(code)).toList();
    stockRepository.deleteAllByCodeIn(deleteCodes);
    stockRepository.saveAll(stocks);
    return null;
  }
}
