package com.lanyuanxiaoyao.leopard.core.service;

import com.lanyuanxiaoyao.leopard.core.entity.Daily;
import com.lanyuanxiaoyao.leopard.core.entity.Daily_;
import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator;
import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator_;
import com.lanyuanxiaoyao.leopard.core.entity.QDaily;
import com.lanyuanxiaoyao.leopard.core.entity.QFinanceIndicator;
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
import com.lanyuanxiaoyao.leopard.core.repository.FinanceIndicatorRepository;
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
import com.lanyuanxiaoyao.service.template.service.SimpleServiceSupport;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

/**
 * @author lanyuanxiaoyao
 * @version 20250828
 */
@Slf4j
@Service
public class StockService extends SimpleServiceSupport<Stock> {
  private final FinanceIndicatorRepository financeIndicatorRepository;
  private final DailyRepository dailyRepository;

  public StockService(StockRepository repository, FinanceIndicatorRepository financeIndicatorRepository, DailyRepository dailyRepository) {
    super(repository);
    this.financeIndicatorRepository = financeIndicatorRepository;
    this.dailyRepository = dailyRepository;
  }

  @Cacheable(value = "long-cache", sync = true)
  public Optional<FinanceIndicator> findFinanceIndicator(Long stockId, Integer year) {
    return financeIndicatorRepository.findOne(
      QFinanceIndicator.financeIndicator.year.eq(year)
        .and(QFinanceIndicator.financeIndicator.stock.id.eq(stockId))
    );
  }

  @Cacheable(value = "long-cache", sync = true)
  public List<FinanceIndicator> findFinanceIndicatorRecent(Long stockId, int years) {
    var current = LocalDate.now();
    return financeIndicatorRepository.findAll(
      QFinanceIndicator.financeIndicator.stock.id.eq(stockId)
        .and(QFinanceIndicator.financeIndicator.year.between(current.minusYears(years).getYear(), current.getYear())),
      Sort.by(Sort.Direction.ASC, FinanceIndicator_.YEAR)
    );
  }

  @Cacheable(value = "long-cache", sync = true)
  public List<Daily> findDailyRecent(Long stockId, int days) {
    var current = LocalDate.now();
    return dailyRepository.findAll(
      QDaily.daily.stock.id.eq(stockId)
        .and(QDaily.daily.tradeDate.between(current.minusDays(days), current)),
      Sort.by(Sort.Direction.ASC, Daily_.TRADE_DATE)
    );
  }

  @Cacheable(value = "long-cache", sync = true)
  public Optional<Daily> findDailyLatest(Long stockId) {
    return dailyRepository.findLatest(stockId);
  }
}
