use chrono::NaiveDate;
use fidc_core::{
    CnSmallCapRotationConfig, CnSmallCapRotationStrategy, DataSet, JqMicroCapConfig,
    JqMicroCapStrategy, PortfolioState, Strategy, StrategyContext,
};
use std::path::PathBuf;

#[test]
fn strategy_emits_target_weights_and_diagnostics() {
    let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../data/demo");
    let data = DataSet::from_csv_dir(&data_dir).expect("demo data");
    let decision_date = NaiveDate::from_ymd_opt(2024, 1, 10).unwrap();
    let execution_date = NaiveDate::from_ymd_opt(2024, 1, 11).unwrap();
    let portfolio = PortfolioState::new(1_000_000.0);
    let mut cfg = CnSmallCapRotationConfig::cn_dyn_smallcap_band();
    cfg.signal_symbol = Some("000001.SZ".to_string());
    cfg.short_ma_days = 3;
    cfg.long_ma_days = 5;
    let mut strategy = CnSmallCapRotationStrategy::new(cfg);

    let decision = strategy
        .on_day(&StrategyContext {
            execution_date,
            decision_date,
            decision_index: 0,
            data: &data,
            portfolio: &portfolio,
        })
        .expect("decision");

    assert!(decision.rebalance);
    assert!(decision.rebalance);
    assert!(!decision.diagnostics.is_empty());
    assert!(
        decision
            .diagnostics
            .iter()
            .any(|line| line.contains("signal_symbol="))
    );
    assert_eq!(strategy.name(), "cn-dyn-smallcap-band");
}

#[test]
fn jq_strategy_emits_same_day_decision() {
    let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../data/demo");
    let data = DataSet::from_csv_dir(&data_dir).expect("demo data");
    let execution_date = NaiveDate::from_ymd_opt(2024, 1, 10).unwrap();
    let portfolio = PortfolioState::new(1_000_000.0);
    let mut cfg = JqMicroCapConfig::jq_microcap();
    cfg.benchmark_signal_symbol = "000001.SZ".to_string();
    cfg.benchmark_short_ma_days = 3;
    cfg.benchmark_long_ma_days = 5;
    cfg.stock_short_ma_days = 3;
    cfg.stock_mid_ma_days = 4;
    cfg.stock_long_ma_days = 5;
    let mut strategy = JqMicroCapStrategy::new(cfg);

    let decision = strategy
        .on_day(&StrategyContext {
            execution_date,
            decision_date: execution_date,
            decision_index: 0,
            data: &data,
            portfolio: &portfolio,
        })
        .expect("jq decision");

    assert!(!decision.rebalance);
    assert!(
        decision
            .diagnostics
            .iter()
            .any(|line| line.contains("jq_microcap signal="))
    );
    assert!(
        decision
            .diagnostics
            .iter()
            .any(|line| line.contains("selected="))
    );
}
